diff options
author | Ram Vepa <ram.vepa@qlogic.com> | 2011-05-27 09:41:55 -0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2011-07-18 15:09:23 -0400 |
commit | 4356d0b64b9be53c507f66c572c1e275b4529239 (patch) | |
tree | 58c15fe0987ae06873f2fe8a1b188db73fbaf796 /drivers/infiniband | |
parent | 2df4f7579d212e8e0df7c8a24f57bf90f23fd516 (diff) |
IB/qib: Fix potential deadlock with link down interrupt
There is a possibility of a deadlock due to the way locks are
acquired and released in qib_set_uevent_bits(). The function
qib_set_uevent_bits() is called in process context and it uses
spin_lock() and spin_unlock(). This same lock is acquired/released
in interrupt context which can lead to a deadlock when running on
the same cpu.
The fix is to replace spin_lock() and spin_unlock() with
spin_lock_irqsave() and spin_unlock_irqrestore() respectively in
qib_set_uevent_bits().
Signed-off-by: Mike Marciniszyn <mike.marciniszyn@qlogic.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/hw/qib/qib_file_ops.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c b/drivers/infiniband/hw/qib/qib_file_ops.c index a94a46001745..26253039d2c7 100644 --- a/drivers/infiniband/hw/qib/qib_file_ops.c +++ b/drivers/infiniband/hw/qib/qib_file_ops.c | |||
@@ -1905,8 +1905,9 @@ int qib_set_uevent_bits(struct qib_pportdata *ppd, const int evtbit) | |||
1905 | struct qib_ctxtdata *rcd; | 1905 | struct qib_ctxtdata *rcd; |
1906 | unsigned ctxt; | 1906 | unsigned ctxt; |
1907 | int ret = 0; | 1907 | int ret = 0; |
1908 | unsigned long flags; | ||
1908 | 1909 | ||
1909 | spin_lock(&ppd->dd->uctxt_lock); | 1910 | spin_lock_irqsave(&ppd->dd->uctxt_lock, flags); |
1910 | for (ctxt = ppd->dd->first_user_ctxt; ctxt < ppd->dd->cfgctxts; | 1911 | for (ctxt = ppd->dd->first_user_ctxt; ctxt < ppd->dd->cfgctxts; |
1911 | ctxt++) { | 1912 | ctxt++) { |
1912 | rcd = ppd->dd->rcd[ctxt]; | 1913 | rcd = ppd->dd->rcd[ctxt]; |
@@ -1925,7 +1926,7 @@ int qib_set_uevent_bits(struct qib_pportdata *ppd, const int evtbit) | |||
1925 | ret = 1; | 1926 | ret = 1; |
1926 | break; | 1927 | break; |
1927 | } | 1928 | } |
1928 | spin_unlock(&ppd->dd->uctxt_lock); | 1929 | spin_unlock_irqrestore(&ppd->dd->uctxt_lock, flags); |
1929 | 1930 | ||
1930 | return ret; | 1931 | return ret; |
1931 | } | 1932 | } |