be2iscsi: Fix processing cqe for cxn whose endpoint is freed
authorJayamohan Kallickal <jayamohan.kallickal@emulex.com>
Tue, 6 May 2014 01:41:30 +0000 (21:41 -0400)
committerChristoph Hellwig <hch@lst.de>
Wed, 28 May 2014 16:13:17 +0000 (18:13 +0200)
 During heavy IO in multipath environment with many active sessions
 and port-bouncing happening, there is a race condition because of
 which beiscsi_prcess_cqe() gets called for a connection whose
 endpoint is freed.

 Checking endpoint reference for a connection before processing in
 beiscsi_process_cq().

Signed-off-by: Minh Tran <minhduc.tran@emulex.com>
Signed-off-by: John Soni Jose <sony.john-n@emulex.com>
Signed-off-by: Jayamohan Kallickal <jayamohan.kallickal@emulex.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/scsi/be2iscsi/be_main.c

index 554349029628417d03b163cb066b94b6b0552c05..ac54cf55998f67f3e502227b0495bd7946857203 100644 (file)
@@ -2110,6 +2110,16 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
 
                cri_index = BE_GET_CRI_FROM_CID(cid);
                ep = phba->ep_array[cri_index];
+               if (unlikely(ep == NULL)) {
+                       /* connection has already been freed
+                        * just move on to next one
+                        */
+                       beiscsi_log(phba, KERN_WARNING,
+                                   BEISCSI_LOG_INIT,
+                                   "BM_%d : proc cqe of disconn ep: cid %d\n",
+                                   cid);
+                       goto proc_next_cqe;
+               }
                beiscsi_ep = ep->dd_data;
                beiscsi_conn = beiscsi_ep->conn;
 
@@ -2219,6 +2229,7 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
                        break;
                }
 
+proc_next_cqe:
                AMAP_SET_BITS(struct amap_sol_cqe, valid, sol, 0);
                queue_tail_inc(cq);
                sol = queue_tail_node(cq);