aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target/target_core_pscsi.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2011-09-25 14:56:32 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2011-10-23 23:20:44 -0400
commit02b1a7463420e1cebe86c6755c44d3bd9489829e (patch)
tree59ec8003f5c8a7937c0b9faee84c926793814ba8 /drivers/target/target_core_pscsi.c
parentdbbf3e94c2b26988d3c41af63e50189e9133eb28 (diff)
target: cleanup pscsi request submission
Move the entirely request allocation, mapping and submission into ->do_task. This a) avoids blocking the I/O submission thread unessecarily, and b) simplifies the code greatly Note that the code seems to have various error handling issues, mostly related to bidi handling in the current form. I've added comments about those but not tried to fix them in this commit. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/target_core_pscsi.c')
-rw-r--r--drivers/target/target_core_pscsi.c265
1 files changed, 92 insertions, 173 deletions
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index 77d725886410..b6d609362d62 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -776,95 +776,6 @@ pscsi_alloc_task(unsigned char *cdb)
776 return &pt->pscsi_task; 776 return &pt->pscsi_task;
777} 777}
778 778
779static inline void pscsi_blk_init_request(
780 struct se_task *task,
781 struct pscsi_plugin_task *pt,
782 struct request *req,
783 int bidi_read)
784{
785 /*
786 * Defined as "scsi command" in include/linux/blkdev.h.
787 */
788 req->cmd_type = REQ_TYPE_BLOCK_PC;
789 /*
790 * For the extra BIDI-COMMAND READ struct request we do not
791 * need to setup the remaining structure members
792 */
793 if (bidi_read)
794 return;
795 /*
796 * Setup the done function pointer for struct request,
797 * also set the end_io_data pointer.to struct se_task.
798 */
799 req->end_io = pscsi_req_done;
800 req->end_io_data = task;
801 /*
802 * Load the referenced struct se_task's SCSI CDB into
803 * include/linux/blkdev.h:struct request->cmd
804 */
805 req->cmd_len = scsi_command_size(pt->pscsi_cdb);
806 req->cmd = &pt->pscsi_cdb[0];
807 /*
808 * Setup pointer for outgoing sense data.
809 */
810 req->sense = &pt->pscsi_sense[0];
811 req->sense_len = 0;
812}
813
814/*
815 * Used for pSCSI data payloads for all *NON* SCF_SCSI_DATA_SG_IO_CDB
816*/
817static int pscsi_blk_get_request(struct se_task *task)
818{
819 struct pscsi_plugin_task *pt = PSCSI_TASK(task);
820 struct pscsi_dev_virt *pdv = task->se_dev->dev_ptr;
821
822 pt->pscsi_req = blk_get_request(pdv->pdv_sd->request_queue,
823 (task->task_data_direction == DMA_TO_DEVICE),
824 GFP_KERNEL);
825 if (!pt->pscsi_req || IS_ERR(pt->pscsi_req)) {
826 pr_err("PSCSI: blk_get_request() failed: %ld\n",
827 IS_ERR(pt->pscsi_req));
828 return PYX_TRANSPORT_LU_COMM_FAILURE;
829 }
830 /*
831 * Setup the newly allocated struct request for REQ_TYPE_BLOCK_PC,
832 * and setup rq callback, CDB and sense.
833 */
834 pscsi_blk_init_request(task, pt, pt->pscsi_req, 0);
835 return 0;
836}
837
838/* pscsi_do_task(): (Part of se_subsystem_api_t template)
839 *
840 *
841 */
842static int pscsi_do_task(struct se_task *task)
843{
844 struct pscsi_plugin_task *pt = PSCSI_TASK(task);
845 struct pscsi_dev_virt *pdv = task->se_dev->dev_ptr;
846 /*
847 * Set the struct request->timeout value based on peripheral
848 * device type from SCSI.
849 */
850 if (pdv->pdv_sd->type == TYPE_DISK)
851 pt->pscsi_req->timeout = PS_TIMEOUT_DISK;
852 else
853 pt->pscsi_req->timeout = PS_TIMEOUT_OTHER;
854
855 pt->pscsi_req->retries = PS_RETRY;
856 /*
857 * Queue the struct request into the struct scsi_device->request_queue.
858 * Also check for HEAD_OF_QUEUE SAM TASK attr from received se_cmd
859 * descriptor
860 */
861 blk_execute_rq_nowait(pdv->pdv_sd->request_queue, NULL, pt->pscsi_req,
862 (task->task_se_cmd->sam_task_attr == MSG_HEAD_TAG),
863 pscsi_req_done);
864
865 return PYX_TRANSPORT_SENT_TO_TRANSPORT;
866}
867
868static void pscsi_free_task(struct se_task *task) 779static void pscsi_free_task(struct se_task *task)
869{ 780{
870 struct pscsi_plugin_task *pt = PSCSI_TASK(task); 781 struct pscsi_plugin_task *pt = PSCSI_TASK(task);
@@ -1048,15 +959,12 @@ static inline struct bio *pscsi_get_bio(int sg_num)
1048 return bio; 959 return bio;
1049} 960}
1050 961
1051static int __pscsi_map_SG( 962static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg,
1052 struct se_task *task, 963 struct bio **hbio)
1053 struct scatterlist *task_sg,
1054 u32 task_sg_num,
1055 int bidi_read)
1056{ 964{
1057 struct pscsi_plugin_task *pt = PSCSI_TASK(task);
1058 struct pscsi_dev_virt *pdv = task->se_dev->dev_ptr; 965 struct pscsi_dev_virt *pdv = task->se_dev->dev_ptr;
1059 struct bio *bio = NULL, *hbio = NULL, *tbio = NULL; 966 u32 task_sg_num = task->task_sg_nents;
967 struct bio *bio = NULL, *tbio = NULL;
1060 struct page *page; 968 struct page *page;
1061 struct scatterlist *sg; 969 struct scatterlist *sg;
1062 u32 data_len = task->task_size, i, len, bytes, off; 970 u32 data_len = task->task_size, i, len, bytes, off;
@@ -1065,19 +973,8 @@ static int __pscsi_map_SG(
1065 int nr_vecs = 0, rc, ret = PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; 973 int nr_vecs = 0, rc, ret = PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES;
1066 int rw = (task->task_data_direction == DMA_TO_DEVICE); 974 int rw = (task->task_data_direction == DMA_TO_DEVICE);
1067 975
1068 if (!task->task_size) 976 *hbio = NULL;
1069 return 0; 977
1070 /*
1071 * For SCF_SCSI_DATA_SG_IO_CDB, Use fs/bio.c:bio_add_page() to setup
1072 * the bio_vec maplist from task->task_sg ->
1073 * struct scatterlist memory. The struct se_task->task_sg[] currently needs
1074 * to be attached to struct bios for submission to Linux/SCSI using
1075 * struct request to struct scsi_device->request_queue.
1076 *
1077 * Note that this will be changing post v2.6.28 as Target_Core_Mod/pSCSI
1078 * is ported to upstream SCSI passthrough functionality that accepts
1079 * struct scatterlist->page_link or struct page as a paraemeter.
1080 */
1081 pr_debug("PSCSI: nr_pages: %d\n", nr_pages); 978 pr_debug("PSCSI: nr_pages: %d\n", nr_pages);
1082 979
1083 for_each_sg(task_sg, sg, task_sg_num, i) { 980 for_each_sg(task_sg, sg, task_sg_num, i) {
@@ -1114,8 +1011,8 @@ static int __pscsi_map_SG(
1114 * bios need to be added to complete a given 1011 * bios need to be added to complete a given
1115 * struct se_task 1012 * struct se_task
1116 */ 1013 */
1117 if (!hbio) 1014 if (!*hbio)
1118 hbio = tbio = bio; 1015 *hbio = tbio = bio;
1119 else 1016 else
1120 tbio = tbio->bi_next = bio; 1017 tbio = tbio->bi_next = bio;
1121 } 1018 }
@@ -1151,83 +1048,109 @@ static int __pscsi_map_SG(
1151 off = 0; 1048 off = 0;
1152 } 1049 }
1153 } 1050 }
1154 /*
1155 * Setup the primary pt->pscsi_req used for non BIDI and BIDI-COMMAND
1156 * primary SCSI WRITE poayload mapped for struct se_task->task_sg[]
1157 */
1158 if (!bidi_read) {
1159 /*
1160 * Starting with v2.6.31, call blk_make_request() passing in *hbio to
1161 * allocate the pSCSI task a struct request.
1162 */
1163 pt->pscsi_req = blk_make_request(pdv->pdv_sd->request_queue,
1164 hbio, GFP_KERNEL);
1165 if (!pt->pscsi_req) {
1166 pr_err("pSCSI: blk_make_request() failed\n");
1167 goto fail;
1168 }
1169 /*
1170 * Setup the newly allocated struct request for REQ_TYPE_BLOCK_PC,
1171 * and setup rq callback, CDB and sense.
1172 */
1173 pscsi_blk_init_request(task, pt, pt->pscsi_req, 0);
1174
1175 return task->task_sg_nents;
1176 }
1177 /*
1178 * Setup the secondary pt->pscsi_req->next_rq used for the extra BIDI-COMMAND
1179 * SCSI READ paylaod mapped for struct se_task->task_sg_bidi[]
1180 */
1181 pt->pscsi_req->next_rq = blk_make_request(pdv->pdv_sd->request_queue,
1182 hbio, GFP_KERNEL);
1183 if (!pt->pscsi_req->next_rq) {
1184 pr_err("pSCSI: blk_make_request() failed for BIDI\n");
1185 goto fail;
1186 }
1187 pscsi_blk_init_request(task, pt, pt->pscsi_req->next_rq, 1);
1188 1051
1189 return task->task_sg_nents; 1052 return task->task_sg_nents;
1190fail: 1053fail:
1191 while (hbio) { 1054 while (*hbio) {
1192 bio = hbio; 1055 bio = *hbio;
1193 hbio = hbio->bi_next; 1056 *hbio = (*hbio)->bi_next;
1194 bio->bi_next = NULL; 1057 bio->bi_next = NULL;
1195 bio_endio(bio, 0); 1058 bio_endio(bio, 0); /* XXX: should be error */
1196 } 1059 }
1197 return ret; 1060 return ret;
1198} 1061}
1199 1062
1200/* 1063static int pscsi_do_task(struct se_task *task)
1201 * pSCSI maps both ->map_control_SG() and ->map_data_SG() to a single call.
1202 */
1203static int pscsi_map_SG(struct se_task *task)
1204{ 1064{
1065 struct pscsi_dev_virt *pdv = task->se_dev->dev_ptr;
1066 struct pscsi_plugin_task *pt = PSCSI_TASK(task);
1067 struct request *req;
1068 struct bio *hbio;
1205 int ret; 1069 int ret;
1206 1070
1207 /* 1071 if (task->task_se_cmd->se_cmd_flags & SCF_SCSI_NON_DATA_CDB) {
1208 * Setup the main struct request for the task->task_sg[] payload 1072 req = blk_get_request(pdv->pdv_sd->request_queue,
1209 */ 1073 (task->task_data_direction == DMA_TO_DEVICE),
1074 GFP_KERNEL);
1075 if (!req || IS_ERR(req)) {
1076 pr_err("PSCSI: blk_get_request() failed: %ld\n",
1077 req ? IS_ERR(req) : -ENOMEM);
1078 return PYX_TRANSPORT_LU_COMM_FAILURE;
1079 }
1080 } else {
1081 BUG_ON(!task->task_size);
1210 1082
1211 ret = __pscsi_map_SG(task, task->task_sg, task->task_sg_nents, 0);
1212 if (ret >= 0 && task->task_sg_bidi) {
1213 /* 1083 /*
1214 * If present, set up the extra BIDI-COMMAND SCSI READ 1084 * Setup the main struct request for the task->task_sg[] payload
1215 * struct request and payload.
1216 */ 1085 */
1217 ret = __pscsi_map_SG(task, task->task_sg_bidi, 1086 ret = pscsi_map_sg(task, task->task_sg, &hbio);
1218 task->task_sg_nents, 1); 1087 if (ret < 0)
1088 return PYX_TRANSPORT_LU_COMM_FAILURE;
1089
1090 req = blk_make_request(pdv->pdv_sd->request_queue, hbio,
1091 GFP_KERNEL);
1092 if (!req) {
1093 pr_err("pSCSI: blk_make_request() failed\n");
1094 goto fail;
1095 }
1096
1097 if (task->task_sg_bidi) {
1098 /*
1099 * If present, set up the extra BIDI-COMMAND SCSI READ
1100 * struct request and payload.
1101 */
1102 ret = pscsi_map_sg(task, task->task_sg_bidi, &hbio);
1103 if (ret < 0) {
1104 /* XXX: free the main request? */
1105 return PYX_TRANSPORT_LU_COMM_FAILURE;
1106 }
1107
1108 /*
1109 * Setup the secondary pt->pscsi_req->next_rq used for the extra
1110 * BIDI READ payload.
1111 */
1112 req->next_rq = blk_make_request(pdv->pdv_sd->request_queue,
1113 hbio, GFP_KERNEL);
1114 if (!req) {
1115 pr_err("pSCSI: blk_make_request() failed for BIDI\n");
1116 /* XXX: free the main request? */
1117 goto fail;
1118 }
1119
1120 req->next_rq->cmd_type = REQ_TYPE_BLOCK_PC;
1121 }
1219 } 1122 }
1220 1123
1221 if (ret < 0) 1124 req->cmd_type = REQ_TYPE_BLOCK_PC;
1222 return PYX_TRANSPORT_LU_COMM_FAILURE; 1125 req->end_io = pscsi_req_done;
1223 return 0; 1126 req->end_io_data = task;
1224} 1127 req->cmd_len = scsi_command_size(pt->pscsi_cdb);
1128 req->cmd = &pt->pscsi_cdb[0];
1129 req->sense = &pt->pscsi_sense[0];
1130 req->sense_len = 0;
1131 if (pdv->pdv_sd->type == TYPE_DISK)
1132 req->timeout = PS_TIMEOUT_DISK;
1133 else
1134 req->timeout = PS_TIMEOUT_OTHER;
1135 req->retries = PS_RETRY;
1225 1136
1226static int pscsi_CDB_none(struct se_task *task) 1137 blk_execute_rq_nowait(pdv->pdv_sd->request_queue, NULL, req,
1227{ 1138 (task->task_se_cmd->sam_task_attr == MSG_HEAD_TAG),
1228 return pscsi_blk_get_request(task); 1139 pscsi_req_done);
1140
1141 return PYX_TRANSPORT_SENT_TO_TRANSPORT;
1142
1143fail:
1144 while (hbio) {
1145 struct bio *bio = hbio;
1146 hbio = hbio->bi_next;
1147 bio->bi_next = NULL;
1148 bio_endio(bio, 0); /* XXX: should be error */
1149 }
1150 return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES;
1229} 1151}
1230 1152
1153
1231/* pscsi_get_cdb(): 1154/* pscsi_get_cdb():
1232 * 1155 *
1233 * 1156 *
@@ -1334,16 +1257,12 @@ static void pscsi_req_done(struct request *req, int uptodate)
1334 __blk_put_request(req->q, req->next_rq); 1257 __blk_put_request(req->q, req->next_rq);
1335 1258
1336 __blk_put_request(req->q, req); 1259 __blk_put_request(req->q, req);
1337 pt->pscsi_req = NULL;
1338} 1260}
1339 1261
1340static struct se_subsystem_api pscsi_template = { 1262static struct se_subsystem_api pscsi_template = {
1341 .name = "pscsi", 1263 .name = "pscsi",
1342 .owner = THIS_MODULE, 1264 .owner = THIS_MODULE,
1343 .transport_type = TRANSPORT_PLUGIN_PHBA_PDEV, 1265 .transport_type = TRANSPORT_PLUGIN_PHBA_PDEV,
1344 .cdb_none = pscsi_CDB_none,
1345 .map_control_SG = pscsi_map_SG,
1346 .map_data_SG = pscsi_map_SG,
1347 .attach_hba = pscsi_attach_hba, 1266 .attach_hba = pscsi_attach_hba,
1348 .detach_hba = pscsi_detach_hba, 1267 .detach_hba = pscsi_detach_hba,
1349 .pmode_enable_hba = pscsi_pmode_enable_hba, 1268 .pmode_enable_hba = pscsi_pmode_enable_hba,