diff options
author | Mike Marciniszyn <mike.marciniszyn@qlogic.com> | 2011-02-10 14:11:28 +0000 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2011-02-10 11:24:08 -0800 |
commit | 414ed90cee32486c50f91b28990443e0dc21c868 (patch) | |
tree | bcb6fc2551b3bb230c6aa9ebf18502728f573228 /drivers/infiniband/hw | |
parent | 831d52bc153971b70e64eccfbed2b232394f22f8 (diff) | |
download | kernel_samsung_espresso10-414ed90cee32486c50f91b28990443e0dc21c868.zip kernel_samsung_espresso10-414ed90cee32486c50f91b28990443e0dc21c868.tar.gz kernel_samsung_espresso10-414ed90cee32486c50f91b28990443e0dc21c868.tar.bz2 |
IB/qib: Fix double add_timer()
The following panic BUG_ON occurs during qib testing:
Kernel BUG at include/linux/timer.h:82
RIP [<ffffffff881f7109>] :ib_qib:start_timer+0x73/0x89
RSP <ffffffff80425bd0>
<0>Kernel panic - not syncing: Fatal exception
<0>Dumping qib trace buffer from panic
qib_set_lid INFO: IB0:1 got a lid: 0xf8
Done dumping qib trace buffer
BUG: warning at kernel/panic.c:137/panic() (Tainted: G
The flaw is due to a missing state test when processing responses that
results in an add_timer() call when the same timer is already queued.
This code was executing in parallel with a QP destroy on another CPU
that had changed the state to reset, but the missing test caused to
response handling code to run on into the panic.
Signed-off-by: Mike Marciniszyn <mike.marciniszyn@qlogic.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r-- | drivers/infiniband/hw/qib/qib_rc.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/qib/qib_rc.c b/drivers/infiniband/hw/qib/qib_rc.c index 8245237..31e09b0 100644 --- a/drivers/infiniband/hw/qib/qib_rc.c +++ b/drivers/infiniband/hw/qib/qib_rc.c @@ -1439,6 +1439,8 @@ static void qib_rc_rcv_resp(struct qib_ibport *ibp, } spin_lock_irqsave(&qp->s_lock, flags); + if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) + goto ack_done; /* Ignore invalid responses. */ if (qib_cmp24(psn, qp->s_next_psn) >= 0) |