Skip to content

Commit

Permalink
IB/qib: Fix potential deadlock with link down interrupt
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Ram Vepa authored and Roland Dreier committed Jul 18, 2011
1 parent 2df4f75 commit 4356d0b
Showing 1 changed file with 3 additions and 2 deletions.
5 changes: 3 additions & 2 deletions drivers/infiniband/hw/qib/qib_file_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1905,8 +1905,9 @@ int qib_set_uevent_bits(struct qib_pportdata *ppd, const int evtbit)
struct qib_ctxtdata *rcd;
unsigned ctxt;
int ret = 0;
unsigned long flags;

spin_lock(&ppd->dd->uctxt_lock);
spin_lock_irqsave(&ppd->dd->uctxt_lock, flags);
for (ctxt = ppd->dd->first_user_ctxt; ctxt < ppd->dd->cfgctxts;
ctxt++) {
rcd = ppd->dd->rcd[ctxt];
Expand All @@ -1925,7 +1926,7 @@ int qib_set_uevent_bits(struct qib_pportdata *ppd, const int evtbit)
ret = 1;
break;
}
spin_unlock(&ppd->dd->uctxt_lock);
spin_unlock_irqrestore(&ppd->dd->uctxt_lock, flags);

return ret;
}
Expand Down

0 comments on commit 4356d0b

Please sign in to comment.