xref: /spdk/lib/iscsi/task.c (revision 8afdeef3becfe9409cc9e7372bd0bc10e8b7d46d)
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
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 *
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