diff mbox series

[2/2] scsi: libfc: Skip additional kref updating work event.

Message ID 20200622101212.3922-3-jhasan@marvell.com
State New
Headers show
Series libfc: Handling of extra kref. | expand

Commit Message

Javed Hasan June 22, 2020, 10:12 a.m. UTC
When an rport event(RPORT_EV_READY) is updated without work being
  queued, avoid taking an additional reference.

  This issue was leading to memory leak. Below is the trace from
  KMEMLEAK tool.
  unreferenced object 0xffff8888259e8780 (size 512):
  comm "kworker/2:1", pid 182614, jiffies 4433237386 (age 113021.971s)
    hex dump (first 32 bytes):
	58 0a ec cf 83 88 ff ff 00 00 00 00 00 00 00 00
	01 00 00 00 08 00 00 00 13 7d f0 1e 0e 00 00 10
  backtrace:
    [<000000006b25760f>] fc_rport_recv_req+0x3c6/0x18f0 [libfc]
    [<00000000f208d994>] fc_lport_recv_els_req+0x120/0x8a0 [libfc]
    [<00000000a9c437b8>] fc_lport_recv+0xb9/0x130 [libfc]
    [<00000000a9c437b8>] fc_lport_recv+0xb9/0x130 [libfc]
    [<00000000ad5be37b>] qedf_ll2_process_skb+0x73d/0xad0 [qedf]
    [<00000000e0eb6893>] process_one_work+0x382/0x6c0
    [<000000002dfd9e21>] worker_thread+0x57/0x5c0
    [<00000000b648204f>] kthread+0x1a0/0x1c0
    [<0000000072f5ab20>] ret_from_fork+0x35/0x40
    [<000000001d5c05d8>] 0xffffffffffffffff

  Below is the logs sequence which leads to memory leak.
  Here we get the RPORT_EV_READY and RPORT_EV_STOP back to back, which lead to
  overwrite the event RPORT_EV_READY by event RPORT_EV_STOP. Because of this
  kref_count get incremented by 1.
	kernel: host0: rport fffce5: Received PLOGI request
	kernel: host0: rport fffce5: Received PLOGI in INIT state
	kernel: host0: rport fffce5: Port is Ready
	kernel: host0: rport fffce5: Received PRLI request while in state Ready
	kernel: host0: rport fffce5: PRLI rspp type 8 active 1 passive 0
	kernel: host0: rport fffce5: Received LOGO request while in state Ready
	kernel: host0: rport fffce5: Delete port
	kernel: host0: rport fffce5: Received PLOGI request
	kernel: host0: rport fffce5: Received PLOGI in state Delete - send busy
	kernel: host0: rport fffce5: work event 3
	kernel: host0: rport fffce5: lld callback ev 3
	kernel: host0: rport fffce5: work delete

  Reviewed-by: Girish Basrur <gbasrur@marvell.com>
  Reviewed-by: Saurav Kashyap <skashyap@marvell.com>
  Reviewed-by: Shyam Sundar <ssundar@marvell.com>
  Signed-off-by: Javed Hasan <jhasan@marvell.com>
---
 drivers/scsi/libfc/fc_rport.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index ca39b4b..830df32f 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -483,10 +483,11 @@  static void fc_rport_enter_delete(struct fc_rport_priv *rdata,
 
 	fc_rport_state_enter(rdata, RPORT_ST_DELETE);
 
-	kref_get(&rdata->kref);
-	if (rdata->event == RPORT_EV_NONE &&
-	    !queue_work(rport_event_queue, &rdata->event_work))
-		kref_put(&rdata->kref, fc_rport_destroy);
+	if (rdata->event == RPORT_EV_NONE) {
+		kref_get(&rdata->kref);
+	    if(!queue_work(rport_event_queue, &rdata->event_work))
+			kref_put(&rdata->kref, fc_rport_destroy);
+	}
 
 	rdata->event = event;
 }