This has us use the blk/scsi-ml mq cmd pre-allocator for scsi tasks. We now do not need the back/frwd locks for scsi task allocation. We still need it for mgmt tasks, but that will be fixed in the next patch. Signed-off-by: Mike Christie <michael.christie@xxxxxxxxxx> --- drivers/scsi/libiscsi.c | 81 +++++++++++++++++++++---------------------------- include/scsi/libiscsi.h | 13 +++++--- 2 files changed, 42 insertions(+), 52 deletions(-) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 462a308..e46f9ea 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -550,7 +550,6 @@ static void iscsi_free_task(struct iscsi_task *task) return; iscsi_free_itt(session, task); - kfifo_in(&session->cmdpool.queue, (void*)&task, sizeof(void*)); /* * if the window opened when we processed a data/r2t pdu make sure we @@ -562,7 +561,9 @@ static void iscsi_free_task(struct iscsi_task *task) iscsi_conn_queue_work(conn); } - if (sc) { + if (!sc) { + kfifo_in(&session->mgmt_pool.queue, (void *)&task, sizeof(void *)); + } else { /* SCSI eh reuses commands to verify us */ sc->SCp.ptr = NULL; /* @@ -811,13 +812,13 @@ static int iscsi_prep_mgmt_task(struct iscsi_conn *conn, BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE); BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED); - if (!kfifo_out(&session->cmdpool.queue, - (void*)&task, sizeof(void*))) + if (!kfifo_out(&session->mgmt_pool.queue, (void *)&task, + sizeof(void *))) return NULL; if (iscsi_alloc_itt(session, task)) { spin_lock(&session->back_lock); - kfifo_in(&session->cmdpool.queue, (void *)&task, + kfifo_in(&session->mgmt_pool.queue, (void *)&task, sizeof(void *)); spin_unlock(&session->back_lock); return NULL; @@ -1720,14 +1721,10 @@ static void iscsi_xmitworker(struct work_struct *work) } while (rc >= 0 || rc == -EAGAIN); } -static inline struct iscsi_task *iscsi_alloc_task(struct iscsi_conn *conn, - struct scsi_cmnd *sc) +static struct iscsi_task *iscsi_init_scsi_task(struct iscsi_conn *conn, + struct scsi_cmnd *sc) { - struct iscsi_task *task; - - if (!kfifo_out(&conn->session->cmdpool.queue, - (void *) &task, sizeof(void *))) - return NULL; + struct iscsi_task *task = scsi_cmd_priv(sc); sc->SCp.phase = conn->session->age; sc->SCp.ptr = (char *) task; @@ -1830,22 +1827,16 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc) goto fault; } - spin_lock_bh(&session->frwd_lock); - if (test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx)) { - spin_unlock_bh(&session->frwd_lock); - reason = FAILURE_SESSION_IN_RECOVERY; - sc->result = DID_REQUEUE << 16; - goto fault; - } - - task = iscsi_alloc_task(conn, sc); - if (!task) { - spin_unlock_bh(&session->frwd_lock); - reason = FAILURE_OOM; - goto reject; - } + task = iscsi_init_scsi_task(conn, sc); + spin_lock_bh(&session->frwd_lock); if (!ihost->workq) { + if (test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx)) { + reason = FAILURE_SESSION_IN_RECOVERY; + sc->result = DID_REQUEUE << 16; + goto prepd_fault; + } + if (iscsi_check_cmdsn_window_closed(conn)) { reason = FAILURE_WINDOW_CLOSED; goto prepd_reject; @@ -1880,7 +1871,7 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc) spin_lock_bh(&session->back_lock); iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ); spin_unlock_bh(&session->back_lock); -reject: + ISCSI_DBG_SESSION(session, "cmd 0x%x rejected (%d)\n", sc->cmnd[0], reason); return SCSI_MLQUEUE_TARGET_BUSY; @@ -2958,19 +2949,16 @@ struct iscsi_cls_session * if (!session->cmds) goto cmds_alloc_fail; - /* initialize SCSI PDU commands pool */ - if (iscsi_pool_init(&session->cmdpool, session->cmds_max, NULL, + /* initialize mgmt PDU pool */ + if (iscsi_pool_init(&session->mgmt_pool, ISCSI_MGMT_CMDS_MAX, + (void ***)&session->mgmt_cmds, cmd_task_size + sizeof(struct iscsi_task))) - goto cmdpool_alloc_fail; - - for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { - struct iscsi_task *task = session->cmds[cmd_i]; + goto mgmt_pool_alloc_fail; - if (cmd_task_size) - task->dd_data = &task[1]; - task->state = ISCSI_TASK_FREE; - INIT_LIST_HEAD(&task->running); + for (cmd_i = 0; cmd_i < ISCSI_MGMT_CMDS_MAX; cmd_i++) { + struct iscsi_task *task = session->mgmt_cmds[cmd_i]; + iscsi_init_task(task); if (iscsit->alloc_task_priv) { if (iscsit->alloc_task_priv(session, task)) goto free_task_priv; @@ -2993,8 +2981,8 @@ struct iscsi_cls_session * iscsit->free_task_priv(session, session->cmds[cmd_i]); } - iscsi_pool_free(&session->cmdpool); -cmdpool_alloc_fail: + iscsi_pool_free(&session->mgmt_pool); +mgmt_pool_alloc_fail: kfree(session->cmds); cmds_alloc_fail: sbitmap_free(&session->itts); @@ -3023,7 +3011,7 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) session->cmds[cmd_i]); } - iscsi_pool_free(&session->cmdpool); + iscsi_pool_free(&session->mgmt_pool); iscsi_remove_session(cls_session); @@ -3090,9 +3078,8 @@ struct iscsi_cls_conn * /* allocate login_task used for the login/text sequences */ spin_lock_bh(&session->frwd_lock); - if (!kfifo_out(&session->cmdpool.queue, - (void*)&conn->login_task, - sizeof(void*))) { + if (!kfifo_out(&session->mgmt_pool.queue, (void *)&conn->login_task, + sizeof(void *))) { spin_unlock_bh(&session->frwd_lock); goto login_task_alloc_fail; } @@ -3116,8 +3103,8 @@ struct iscsi_cls_conn * iscsi_free_itt(session, conn->login_task); login_itt_fail: spin_lock_bh(&session->frwd_lock); - kfifo_in(&session->cmdpool.queue, (void*)&conn->login_task, - sizeof(void*)); + kfifo_in(&session->mgmt_pool.queue, (void *)&conn->login_task, + sizeof(void *)); spin_unlock_bh(&session->frwd_lock); login_task_alloc_fail: iscsi_destroy_conn(cls_conn); @@ -3161,8 +3148,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) kfree(conn->local_ipaddr); /* regular RX path uses back_lock */ spin_lock_bh(&session->back_lock); - kfifo_in(&session->cmdpool.queue, (void*)&conn->login_task, - sizeof(void*)); + kfifo_in(&session->mgmt_pool.queue, (void *)&conn->login_task, + sizeof(void *)); spin_unlock_bh(&session->back_lock); iscsi_free_itt(session, conn->login_task); if (session->leadconn == conn) diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 406e8a2..8a8d491 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -331,19 +331,22 @@ struct iscsi_session { * in the eh paths, cmdsn * * suspend bit and session * * resources: * - * - cmdpool kfifo_out , * - * - mgmtpool, queues */ + * - kfifo_out mgmt_pool, * + * - queues */ spinlock_t back_lock; /* protects cmdsn_exp * * cmdsn_max, * - * cmdpool kfifo_in */ + * mgmt_pool kfifo_in */ int state; /* session state */ int age; /* counts session re-opens */ int scsi_cmds_max; /* max scsi commands */ int cmds_max; /* size of cmds array */ - struct iscsi_task **cmds; /* Original Cmds arr */ - struct iscsi_pool cmdpool; /* PDU's pool */ + struct iscsi_task **cmds; /* Lookup map of all tasks */ struct sbitmap itts; + + struct iscsi_task **mgmt_cmds; + struct iscsi_pool mgmt_pool; + void *dd_data; /* LLD private data */ }; -- 1.8.3.1