scsi: libfc: Avoid invoking response handler twice if ep is already completed
authorJaved Hasan <jhasan@marvell.com>
Tue, 15 Dec 2020 19:47:31 +0000 (11:47 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 13 Jan 2021 04:07:32 +0000 (23:07 -0500)
commitb2b0f16fa65e910a3ec8771206bb49ee87a54ac5
tree18bb6288dcd54a1f4529959814d4bc0af3d41261
parent72eeb7c7151302ef007f1acd018cbf6f30e50321
scsi: libfc: Avoid invoking response handler twice if ep is already completed

A race condition exists between the response handler getting called because
of exchange_mgr_reset() (which clears out all the active XIDs) and the
response we get via an interrupt.

Sequence of events:

 rport ba0200: Port timeout, state PLOGI
 rport ba0200: Port entered PLOGI state from PLOGI state
 xid 1052: Exchange timer armed : 20000 msecs      xid timer armed here
 rport ba0200: Received LOGO request while in state PLOGI
 rport ba0200: Delete port
 rport ba0200: work event 3
 rport ba0200: lld callback ev 3
 bnx2fc: rport_event_hdlr: event = 3, port_id = 0xba0200
 bnx2fc: ba0200 - rport not created Yet!!
 /* Here we reset any outstanding exchanges before
 freeing rport using the exch_mgr_reset() */
 xid 1052: Exchange timer canceled
 /* Here we got two responses for one xid */
 xid 1052: invoking resp(), esb 20000000 state 3
 xid 1052: invoking resp(), esb 20000000 state 3
 xid 1052: fc_rport_plogi_resp() : ep->resp_active 2
 xid 1052: fc_rport_plogi_resp() : ep->resp_active 2

Skip the response if the exchange is already completed.

Link: https://lore.kernel.org/r/20201215194731.2326-1-jhasan@marvell.com
Signed-off-by: Javed Hasan <jhasan@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/libfc/fc_exch.c