diff --git a/include/spdk/scsi.h b/include/spdk/scsi.h index 97ef2e9d6..d2457799d 100644 --- a/include/spdk/scsi.h +++ b/include/spdk/scsi.h @@ -141,16 +141,6 @@ struct spdk_scsi_task { TAILQ_ENTRY(spdk_scsi_task) scsi_link; - /* - * Pointer to scsi task owner's outstanding - * task counter. Inc/Dec by get/put task functions. - * Note: in the future, we could consider replacing this - * with an owner-provided task management fuction that - * could perform protocol specific task mangement - * operations (such as tracking outstanding tasks). - */ - uint32_t *owner_task_ctr; - uint32_t abort_id; }; @@ -212,7 +202,7 @@ void spdk_scsi_port_free(struct spdk_scsi_port **pport); const char *spdk_scsi_port_get_name(const struct spdk_scsi_port *port); -void spdk_scsi_task_construct(struct spdk_scsi_task *task, uint32_t *owner_task_ctr, +void spdk_scsi_task_construct(struct spdk_scsi_task *task, void (*free_fn)(struct spdk_scsi_task *task), struct spdk_scsi_task *parent); void spdk_scsi_task_put(struct spdk_scsi_task *task); diff --git a/lib/iscsi/iscsi.c b/lib/iscsi/iscsi.c index 3db515d04..2e3fdf57d 100644 --- a/lib/iscsi/iscsi.c +++ b/lib/iscsi/iscsi.c @@ -2863,7 +2863,7 @@ int spdk_iscsi_conn_handle_queued_tasks(struct spdk_iscsi_conn *conn) uint32_t remaining_size = 0; remaining_size = task->scsi.transfer_len - task->current_datain_offset; - subtask = spdk_iscsi_task_get(&conn->pending_task_cnt, task); + subtask = spdk_iscsi_task_get(conn, task); assert(subtask != NULL); subtask->scsi.offset = task->current_datain_offset; subtask->scsi.length = DMIN32(SPDK_BDEV_LARGE_BUF_MAX_SIZE, remaining_size); @@ -2934,7 +2934,7 @@ spdk_iscsi_op_scsi(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) SPDK_TRACEDUMP(SPDK_TRACE_DEBUG, "CDB", cdb, 16); - task = spdk_iscsi_task_get(&conn->pending_task_cnt, NULL); + task = spdk_iscsi_task_get(conn, NULL); if (!task) { SPDK_ERRLOG("Unable to acquire task\n"); return SPDK_ISCSI_CONNECTION_FATAL; @@ -3250,7 +3250,7 @@ spdk_iscsi_op_task(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) lun_i = spdk_islun2lun(lun); dev = conn->dev; - task = spdk_iscsi_task_get(&conn->pending_task_cnt, NULL); + task = spdk_iscsi_task_get(conn, NULL); if (!task) { SPDK_ERRLOG("Unable to acquire task\n"); return SPDK_ISCSI_CONNECTION_FATAL; @@ -4091,7 +4091,7 @@ static int spdk_iscsi_op_data(struct spdk_iscsi_conn *conn, task->current_r2t_length = 0; } - subtask = spdk_iscsi_task_get(&conn->pending_task_cnt, task); + subtask = spdk_iscsi_task_get(conn, task); if (subtask == NULL) { SPDK_ERRLOG("Unable to acquire subtask\n"); return SPDK_ISCSI_CONNECTION_FATAL; diff --git a/lib/iscsi/task.c b/lib/iscsi/task.c index f1d3c6735..ebcf7430d 100644 --- a/lib/iscsi/task.c +++ b/lib/iscsi/task.c @@ -36,17 +36,22 @@ #include #include "spdk/log.h" +#include "iscsi/conn.h" #include "iscsi/task.h" static void -spdk_iscsi_task_free(struct spdk_scsi_task *task) +spdk_iscsi_task_free(struct spdk_scsi_task *scsi_task) { - spdk_iscsi_task_disassociate_pdu((struct spdk_iscsi_task *)task); + struct spdk_iscsi_task *task = (struct spdk_iscsi_task *)scsi_task; + + spdk_iscsi_task_disassociate_pdu(task); rte_mempool_put(g_spdk_iscsi.task_pool, (void *)task); + assert(task->conn->pending_task_cnt > 0); + task->conn->pending_task_cnt--; } struct spdk_iscsi_task * -spdk_iscsi_task_get(uint32_t *owner_task_ctr, struct spdk_iscsi_task *parent) +spdk_iscsi_task_get(struct spdk_iscsi_conn *conn, struct spdk_iscsi_task *parent) { struct spdk_iscsi_task *task; int rc; @@ -58,7 +63,10 @@ spdk_iscsi_task_get(uint32_t *owner_task_ctr, struct spdk_iscsi_task *parent) } memset(task, 0, sizeof(*task)); - spdk_scsi_task_construct((struct spdk_scsi_task *)task, owner_task_ctr, + task->conn = conn; + assert(conn->pending_task_cnt < UINT32_MAX); + conn->pending_task_cnt++; + spdk_scsi_task_construct((struct spdk_scsi_task *)task, spdk_iscsi_task_free, (struct spdk_scsi_task *)parent); if (parent) { diff --git a/lib/iscsi/task.h b/lib/iscsi/task.h index d01a0933b..975766bc1 100644 --- a/lib/iscsi/task.h +++ b/lib/iscsi/task.h @@ -41,6 +41,7 @@ struct spdk_iscsi_task { struct spdk_scsi_task scsi; + struct spdk_iscsi_conn *conn; struct spdk_iscsi_pdu *pdu; uint32_t outstanding_r2t; @@ -153,7 +154,7 @@ spdk_iscsi_task_get_cmdsn(struct spdk_iscsi_task *task) return spdk_iscsi_task_get_pdu(task)->cmd_sn; } -struct spdk_iscsi_task *spdk_iscsi_task_get(uint32_t *owner_task_ctr, +struct spdk_iscsi_task *spdk_iscsi_task_get(struct spdk_iscsi_conn *conn, struct spdk_iscsi_task *parent); static inline struct spdk_iscsi_task * diff --git a/lib/iscsi/tgt_node.c b/lib/iscsi/tgt_node.c index bbd1869eb..93bb3fd1b 100644 --- a/lib/iscsi/tgt_node.c +++ b/lib/iscsi/tgt_node.c @@ -1058,7 +1058,7 @@ spdk_iscsi_tgt_node_cleanup_luns(struct spdk_iscsi_conn *conn, continue; /* we create a fake management task per LUN to cleanup */ - task = spdk_iscsi_task_get(&conn->pending_task_cnt, NULL); + task = spdk_iscsi_task_get(conn, NULL); if (!task) { SPDK_ERRLOG("Unable to acquire task\n"); return -1; diff --git a/lib/scsi/task.c b/lib/scsi/task.c index afc4f58dc..7ef8fa340 100644 --- a/lib/scsi/task.c +++ b/lib/scsi/task.c @@ -59,20 +59,13 @@ spdk_scsi_task_put(struct spdk_scsi_task *task) } spdk_scsi_task_free_data(task); - assert(task->owner_task_ctr != NULL); - - if (*(task->owner_task_ctr) > 0) { - *(task->owner_task_ctr) -= 1; - } else { - SPDK_ERRLOG("task counter already 0\n"); - } task->free_fn(task); } } void -spdk_scsi_task_construct(struct spdk_scsi_task *task, uint32_t *owner_task_ctr, +spdk_scsi_task_construct(struct spdk_scsi_task *task, void (*free_fn)(struct spdk_scsi_task *task), struct spdk_scsi_task *parent) { @@ -81,10 +74,6 @@ spdk_scsi_task_construct(struct spdk_scsi_task *task, uint32_t *owner_task_ctr, task->ref++; - assert(owner_task_ctr != NULL); - task->owner_task_ctr = owner_task_ctr; - *owner_task_ctr += 1; - /* * Pre-fill the iov_buffers to point to the embedded iov */ diff --git a/lib/vhost/task.c b/lib/vhost/task.c index 00ef01192..31d727f9a 100644 --- a/lib/vhost/task.c +++ b/lib/vhost/task.c @@ -68,10 +68,11 @@ spdk_vhost_task_free_cb(struct spdk_scsi_task *scsi_task) struct spdk_vhost_task *task = container_of(scsi_task, struct spdk_vhost_task, scsi); rte_mempool_put(g_task_pool, task); + spdk_vhost_scsi_ctrlr_task_unref(task->vdev); } struct spdk_vhost_task * -spdk_vhost_task_get(uint32_t *owner_task_ctr) +spdk_vhost_task_get(struct spdk_vhost_scsi_ctrlr *vdev) { struct spdk_vhost_task *task; int rc; @@ -83,7 +84,9 @@ spdk_vhost_task_get(uint32_t *owner_task_ctr) } memset(task, 0, sizeof(*task)); - spdk_scsi_task_construct(&task->scsi, owner_task_ctr, spdk_vhost_task_free_cb, NULL); + task->vdev = vdev; + spdk_vhost_scsi_ctrlr_task_ref(task->vdev); + spdk_scsi_task_construct(&task->scsi, spdk_vhost_task_free_cb, NULL); return task; } diff --git a/lib/vhost/task.h b/lib/vhost/task.h index 46bcffb17..1be79b491 100644 --- a/lib/vhost/task.h +++ b/lib/vhost/task.h @@ -61,7 +61,10 @@ void spdk_vhost_enqueue_task(struct spdk_vhost_task *task); struct spdk_vhost_task *spdk_vhost_dequeue_task(void); void spdk_vhost_task_put(struct spdk_vhost_task *task); -struct spdk_vhost_task *spdk_vhost_task_get(uint32_t *owner_task_ctr); +struct spdk_vhost_task *spdk_vhost_task_get(struct spdk_vhost_scsi_ctrlr *vdev); + +void spdk_vhost_scsi_ctrlr_task_ref(struct spdk_vhost_scsi_ctrlr *vdev); +void spdk_vhost_scsi_ctrlr_task_unref(struct spdk_vhost_scsi_ctrlr *vdev); void spdk_vhost_iovec_free(struct iovec *iov); struct iovec *spdk_vhost_iovec_alloc(void); diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c index dbbc1c63a..499481de2 100644 --- a/lib/vhost/vhost.c +++ b/lib/vhost/vhost.c @@ -398,6 +398,20 @@ get_scsi_lun(struct spdk_scsi_dev *scsi_dev, const __u8 *lun) return NULL; } +void +spdk_vhost_scsi_ctrlr_task_ref(struct spdk_vhost_scsi_ctrlr *vdev) +{ + assert(vdev->task_cnt < INT_MAX); + vdev->task_cnt++; +} + +void +spdk_vhost_scsi_ctrlr_task_unref(struct spdk_vhost_scsi_ctrlr *vdev) +{ + assert(vdev->task_cnt > 0); + vdev->task_cnt--; +} + static void process_ctrl_request(struct spdk_vhost_scsi_ctrlr *vdev, struct rte_vhost_vring *controlq, uint16_t req_idx) @@ -418,7 +432,7 @@ process_ctrl_request(struct spdk_vhost_scsi_ctrlr *vdev, struct rte_vhost_vring SPDK_TRACEDUMP(SPDK_TRACE_VHOST_QUEUE, "Request desriptor", (uint8_t *)ctrl_req, desc->len); - task = spdk_vhost_task_get(&vdev->task_cnt); + task = spdk_vhost_task_get(vdev); task->vq = controlq; task->vdev = vdev; task->req_idx = req_idx; @@ -662,7 +676,7 @@ process_requestq(struct spdk_vhost_scsi_ctrlr *vdev, struct rte_vhost_vring *vq) assert(reqs_cnt <= 32); for (i = 0; i < reqs_cnt; i++) { - task = spdk_vhost_task_get(&vdev->task_cnt); + task = spdk_vhost_task_get(vdev); SPDK_TRACELOG(SPDK_TRACE_VHOST, "====== Starting processing request idx %"PRIu16"======\n", reqs[i]); diff --git a/test/lib/iscsi/common.c b/test/lib/iscsi/common.c index 63d44ea38..99fdeebb1 100644 --- a/test/lib/iscsi/common.c +++ b/test/lib/iscsi/common.c @@ -12,7 +12,7 @@ SPDK_LOG_REGISTER_TRACE_FLAG("iscsi", SPDK_TRACE_ISCSI) struct spdk_iscsi_task * -spdk_iscsi_task_get(uint32_t *owner_task_ctr, struct spdk_iscsi_task *parent) +spdk_iscsi_task_get(struct spdk_iscsi_conn *conn, struct spdk_iscsi_task *parent) { struct spdk_iscsi_task *task; diff --git a/test/lib/scsi/lun/lun_ut.c b/test/lib/scsi/lun/lun_ut.c index 27e72e15f..81de68259 100644 --- a/test/lib/scsi/lun/lun_ut.c +++ b/test/lib/scsi/lun/lun_ut.c @@ -74,6 +74,8 @@ static void spdk_lun_ut_free_task(struct spdk_scsi_task *task) { free(task); + SPDK_CU_ASSERT_FATAL(g_task_count > 0); + g_task_count--; } static struct spdk_scsi_task * @@ -86,7 +88,8 @@ spdk_get_task(uint32_t *owner_task_ctr) return NULL; } - spdk_scsi_task_construct(task, &g_task_count, spdk_lun_ut_free_task, NULL); + spdk_scsi_task_construct(task, spdk_lun_ut_free_task, NULL); + g_task_count++; return task; }