ACPI / IPMI: Add reference counting for ACPI IPMI transfers
authorLv Zheng <lv.zheng@intel.com>
Fri, 13 Sep 2013 05:14:11 +0000 (13:14 +0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 30 Sep 2013 17:46:12 +0000 (19:46 +0200)
commit7b9844772237e34968ffd4b086d7b5ed36b30856
treeafb6796063d5254bcc22accb015390cb07520d0a
parente96a94edd7ae302168e17daa0198b9ef08b2109d
ACPI / IPMI: Add reference counting for ACPI IPMI transfers

This patch adds reference counting for ACPI IPMI transfers to tune the
locking granularity of tx_msg_lock.

This patch also makes the whole acpi_ipmi module's coding style consistent
by using reference counting for all its objects (i.e., acpi_ipmi_device and
acpi_ipmi_msg).

The acpi_ipmi_msg handling is re-designed using referece counting.
 1. tx_msg is always unlinked before complete(), so that it is safe to put
    complete() out side of tx_msg_lock.
 2. tx_msg reference counters are incremented before calling
    ipmi_request_settime() and tx_msg_lock protection is added to
    ipmi_cancel_tx_msg() so that a complete() can be safely called in
    parellel with tx_msg unlinking in failure cases.
 3. tx_msg holds a reference to acpi_ipmi_device so that it can be flushed
    and freed in the contexts other than acpi_ipmi_space_handler().

The lockdep_chains shows all acpi_ipmi locks are leaf locks after the
tuning:
 1. ipmi_lock is always leaf:
    irq_context: 0
    [ffffffff81a943f8] smi_watchers_mutex
    [ffffffffa06eca60] driver_data.ipmi_lock
    irq_context: 0
    [ffffffff82767b40] &buffer->mutex
    [ffffffffa00a6678] s_active#103
    [ffffffffa06eca60] driver_data.ipmi_lock
 2. without this patch applied, lock used by complete() is held after
    holding tx_msg_lock:
    irq_context: 0
    [ffffffff82767b40] &buffer->mutex
    [ffffffffa00a6678] s_active#103
    [ffffffffa06ecce8] &(&ipmi_device->tx_msg_lock)->rlock
    irq_context: 1
    [ffffffffa06ecce8] &(&ipmi_device->tx_msg_lock)->rlock
    irq_context: 1
    [ffffffffa06ecce8] &(&ipmi_device->tx_msg_lock)->rlock
    [ffffffffa06eccf0] &x->wait#25
    irq_context: 1
    [ffffffffa06ecce8] &(&ipmi_device->tx_msg_lock)->rlock
    [ffffffffa06eccf0] &x->wait#25
    [ffffffff81e36620] &p->pi_lock
    irq_context: 1
    [ffffffffa06ecce8] &(&ipmi_device->tx_msg_lock)->rlock
    [ffffffffa06eccf0] &x->wait#25
    [ffffffff81e36620] &p->pi_lock
    [ffffffff81e5d0a8] &rq->lock
 3. with this patch applied, tx_msg_lock is always leaf:
    irq_context: 0
    [ffffffff82767b40] &buffer->mutex
    [ffffffffa00a66d8] s_active#107
    [ffffffffa07ecdc8] &(&ipmi_device->tx_msg_lock)->rlock
    irq_context: 1
    [ffffffffa07ecdc8] &(&ipmi_device->tx_msg_lock)->rlock

Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Reviewed-by: Huang Ying <ying.huang@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/acpi/acpi_ipmi.c