1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
3 * Copyright (C) 2016 Intel Corporation.
4 * All rights reserved.
5 */
6
7 #include "spdk/env.h"
8 #include "spdk/log.h"
9 #include "iscsi/conn.h"
10 #include "iscsi/task.h"
11 #include "iscsi/tgt_node.h"
12
13 static void
iscsi_task_free(struct spdk_scsi_task * scsi_task)14 iscsi_task_free(struct spdk_scsi_task *scsi_task)
15 {
16 uint64_t tsc_diff;
17 struct spdk_iscsi_task *task = iscsi_task_from_scsi_task(scsi_task);
18
19 if (task->conn->target->histogram) {
20 tsc_diff = spdk_get_ticks() - task->start_tsc;
21 spdk_histogram_data_tally(task->conn->target->histogram, tsc_diff);
22 }
23
24 if (task->parent) {
25 if (task->scsi.dxfer_dir == SPDK_SCSI_DIR_FROM_DEV) {
26 assert(task->conn->data_in_cnt > 0);
27 task->conn->data_in_cnt--;
28 }
29
30 spdk_scsi_task_put(&task->parent->scsi);
31 task->parent = NULL;
32 }
33
34 if (iscsi_task_get_mobj(task)) {
35 iscsi_datapool_put(iscsi_task_get_mobj(task));
36 }
37
38 iscsi_task_disassociate_pdu(task);
39 assert(task->conn->pending_task_cnt > 0);
40 task->conn->pending_task_cnt--;
41 spdk_mempool_put(g_iscsi.task_pool, (void *)task);
42 }
43
44 struct spdk_iscsi_task *
iscsi_task_get(struct spdk_iscsi_conn * conn,struct spdk_iscsi_task * parent,spdk_scsi_task_cpl cpl_fn)45 iscsi_task_get(struct spdk_iscsi_conn *conn, struct spdk_iscsi_task *parent,
46 spdk_scsi_task_cpl cpl_fn)
47 {
48 struct spdk_iscsi_task *task;
49
50 task = spdk_mempool_get(g_iscsi.task_pool);
51 if (!task) {
52 SPDK_ERRLOG("Unable to get task\n");
53 abort();
54 }
55
56 assert(conn != NULL);
57 memset(task, 0, sizeof(*task));
58 task->start_tsc = spdk_get_ticks();
59 task->conn = conn;
60 assert(conn->pending_task_cnt < UINT32_MAX);
61 conn->pending_task_cnt++;
62 spdk_scsi_task_construct(&task->scsi,
63 cpl_fn,
64 iscsi_task_free);
65 if (parent) {
66 parent->scsi.ref++;
67 task->parent = parent;
68 task->tag = parent->tag;
69 task->lun_id = parent->lun_id;
70 task->scsi.dxfer_dir = parent->scsi.dxfer_dir;
71 task->scsi.transfer_len = parent->scsi.transfer_len;
72 task->scsi.lun = parent->scsi.lun;
73 task->scsi.cdb = parent->scsi.cdb;
74 task->scsi.target_port = parent->scsi.target_port;
75 task->scsi.initiator_port = parent->scsi.initiator_port;
76 if (task->scsi.dxfer_dir == SPDK_SCSI_DIR_FROM_DEV) {
77 conn->data_in_cnt++;
78 }
79 }
80
81 return task;
82 }
83