Driver should process the completion queue entries before a connection
resources are freed. While running mixed traffic due to latency, driver
processes the CQE after the connection resources are freed. This fix
processes all the completion queue before the connection resources are
freed.
Signed-off-by: John Soni Jose <[email protected]>
Signed-off-by: Jayamohan Kallickal <[email protected]>
Reviewed-by: Mike Christie <[email protected]>
Signed-off-by: Christoph Hellwig <[email protected]>
return 0;
}
+/**
+ * beiscsi_flush_cq()- Flush the CQ created.
+ * @phba: ptr device priv structure.
+ *
+ * Before the connection resource are freed flush
+ * all the CQ enteries
+ **/
+static void beiscsi_flush_cq(struct beiscsi_hba *phba)
+{
+ uint16_t i;
+ struct be_eq_obj *pbe_eq;
+ struct hwi_controller *phwi_ctrlr;
+ struct hwi_context_memory *phwi_context;
+
+ phwi_ctrlr = phba->phwi_ctrlr;
+ phwi_context = phwi_ctrlr->phwi_ctxt;
+
+ for (i = 0; i < phba->num_cpus; i++) {
+ pbe_eq = &phwi_context->be_eq[i];
+ blk_iopoll_disable(&pbe_eq->iopoll);
+ beiscsi_process_cq(pbe_eq);
+ blk_iopoll_enable(&pbe_eq->iopoll);
+ }
+}
+
/**
* beiscsi_close_conn - Upload the connection
* @ep: The iscsi endpoint
}
ret = beiscsi_mccq_compl(phba, tag, NULL, NULL);
+
+ /* Flush the CQ entries */
+ beiscsi_flush_cq(phba);
+
return ret;
}
* return
* Number of Completion Entries processed.
**/
-static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
+unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
{
struct be_queue_info *cq;
struct sol_cqe *sol;
cri_index = BE_GET_CRI_FROM_CID(cid);
ep = phba->ep_array[cri_index];
+
+ if (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;
break;
}
+proc_next_cqe:
AMAP_SET_BITS(struct amap_sol_cqe, valid, sol, 0);
queue_tail_inc(cq);
sol = queue_tail_node(cq);
void hwi_ring_cq_db(struct beiscsi_hba *phba,
unsigned int id, unsigned int num_processed,
unsigned char rearm, unsigned char event);
+
+unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq);
+
static inline bool beiscsi_error(struct beiscsi_hba *phba)
{
return phba->ue_detected || phba->fw_timeout;