This allows userspace to request the fabric drivers do direct submissions if they support it. With the new device file, submit_type, users can write 0 - 2 to control how commands are submitted to the backend: 0 - TARGET_FABRIC_DEFAULT_SUBMIT - LIO will use the fabric's default submission type. This is the default for compat. 1 - TARGET_DIRECT_SUBMIT - LIO will submit the cmd to the backend from the calling context if the fabric the cmd was received on supports it, else it will use the fabric's default type. 2 - TARGET_QUEUE_SUBMIT - LIO will queue the cmd to the LIO submission workqueue which will pass it to the backend. When using an NVMe drive and vhost-scsi with direct submission we see around a 20% improvement in 4K I/Os: fio jobs 1 2 4 8 10 -------------------------------------------------- defer 94K 190K 394K 770K 890K direct 128K 252K 488K 950K - And when using the queueing mode, we now no longer see issues like where the iSCSI tx thread is blocked in the block layer waiting on a tag so it can't respond to a nop or perform I/Os for other LUs.
Unified · Split
| @@ -154,7 +154,7 @@ static void tcm_loop_target_queue_cmd(struct tcm_loop_cmd *tl_cmd) · 153 unmodified lines | ||
| 154 | 154 | GFP_ATOMIC)) |
| 155 | 155 | return; |
| 156 | 156 | |
| 157 | − target_queue_submission(se_cmd); | |
| 157 | + target_submit(se_cmd); | |
| 158 | 158 | return; |
| 159 | 159 | |
| 160 | 160 | out_done: |
| @@ -577,6 +577,7 @@ DEF_CONFIGFS_ATTRIB_SHOW(unmap_granularity_alignment); · 576 unmodified lines | ||
| 577 | 577 | DEF_CONFIGFS_ATTRIB_SHOW(unmap_zeroes_data); |
| 578 | 578 | DEF_CONFIGFS_ATTRIB_SHOW(max_write_same_len); |
| 579 | 579 | DEF_CONFIGFS_ATTRIB_SHOW(emulate_rsoc); |
| 580 | +DEF_CONFIGFS_ATTRIB_SHOW(submit_type); | |
| 580 | 581 | |
| 581 | 582 | #define DEF_CONFIGFS_ATTRIB_STORE_U32(_name) \ |
| 582 | 583 | static ssize_t _name##_store(struct config_item *item, const char *page,\ |
| @@ -1231,6 +1232,24 @@ static ssize_t emulate_rsoc_store(struct config_item *item, · 648 unmodified lines | ||
| 1231 | 1232 | return count; |
| 1232 | 1233 | } |
| 1233 | 1234 | |
| 1235 | +static ssize_t submit_type_store(struct config_item *item, const char *page, | |
| 1236 | + size_t count) | |
| 1237 | +{ | |
| 1238 | + struct se_dev_attrib *da = to_attrib(item); | |
| 1239 | + int ret; | |
| 1240 | + u8 val; | |
| 1241 | + | |
| 1242 | + ret = kstrtou8(page, 0, &val); | |
| 1243 | + if (ret < 0) | |
| 1244 | + return ret; | |
| 1245 | + | |
| 1246 | + if (val > TARGET_QUEUE_SUBMIT) | |
| 1247 | + return -EINVAL; | |
| 1248 | + | |
| 1249 | + da->submit_type = val; | |
| 1250 | + return count; | |
| 1251 | +} | |
| 1252 | + | |
| 1234 | 1253 | CONFIGFS_ATTR(, emulate_model_alias); |
| 1235 | 1254 | CONFIGFS_ATTR(, emulate_dpo); |
| 1236 | 1255 | CONFIGFS_ATTR(, emulate_fua_write); |
| @@ -1266,6 +1285,7 @@ CONFIGFS_ATTR(, unmap_zeroes_data); · 29 unmodified lines | ||
| 1266 | 1285 | CONFIGFS_ATTR(, max_write_same_len); |
| 1267 | 1286 | CONFIGFS_ATTR(, alua_support); |
| 1268 | 1287 | CONFIGFS_ATTR(, pgr_support); |
| 1288 | +CONFIGFS_ATTR(, submit_type); | |
| 1269 | 1289 | |
| 1270 | 1290 | /* |
| 1271 | 1291 | * dev_attrib attributes for devices using the target core SBC/SPC |
| @@ -1308,6 +1328,7 @@ struct configfs_attribute *sbc_attrib_attrs[] = { · 36 unmodified lines | ||
| 1308 | 1328 | &attr_alua_support, |
| 1309 | 1329 | &attr_pgr_support, |
| 1310 | 1330 | &attr_emulate_rsoc, |
| 1331 | + &attr_submit_type, | |
| 1311 | 1332 | NULL, |
| 1312 | 1333 | }; |
| 1313 | 1334 | EXPORT_SYMBOL(sbc_attrib_attrs); |
| @@ -1325,6 +1346,7 @@ struct configfs_attribute *passthrough_attrib_attrs[] = { · 11 unmodified lines | ||
| 1325 | 1346 | &attr_emulate_pr, |
| 1326 | 1347 | &attr_alua_support, |
| 1327 | 1348 | &attr_pgr_support, |
| 1349 | + &attr_submit_type, | |
| 1328 | 1350 | NULL, |
| 1329 | 1351 | }; |
| 1330 | 1352 | EXPORT_SYMBOL(passthrough_attrib_attrs); |
| @@ -779,6 +779,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) · 778 unmodified lines | ||
| 779 | 779 | dev->dev_attrib.unmap_zeroes_data = |
| 780 | 780 | DA_UNMAP_ZEROES_DATA_DEFAULT; |
| 781 | 781 | dev->dev_attrib.max_write_same_len = DA_MAX_WRITE_SAME_LEN; |
| 782 | + dev->dev_attrib.submit_type = TARGET_FABRIC_DEFAULT_SUBMIT; | |
| 782 | 783 | |
| 783 | 784 | xcopy_lun = &dev->xcopy_lun; |
| 784 | 785 | rcu_assign_pointer(xcopy_lun->lun_se_dev, dev); |
| @@ -1575,14 +1575,7 @@ target_cmd_parse_cdb(struct se_cmd *cmd) · 1574 unmodified lines | ||
| 1575 | 1575 | } |
| 1576 | 1576 | EXPORT_SYMBOL(target_cmd_parse_cdb); |
| 1577 | 1577 | |
| 1578 | −/** | |
| 1579 | − * target_submit - perform final initialization and submit cmd to LIO core | |
| 1580 | − * @cmd: command descriptor to submit | |
| 1581 | − * | |
| 1582 | − * target_submit_prep or something similar must have been called on the cmd, | |
| 1583 | − * and this must be called from process context. | |
| 1584 | − */ | |
| 1585 | −int target_submit(struct se_cmd *cmd) | |
| 1578 | +static int __target_submit(struct se_cmd *cmd) | |
| 1586 | 1579 | { |
| 1587 | 1580 | sense_reason_t ret; |
| 1588 | 1581 | |
| @@ -1642,7 +1635,6 @@ int target_submit(struct se_cmd *cmd) · 53 unmodified lines | ||
| 1642 | 1635 | transport_generic_request_failure(cmd, ret); |
| 1643 | 1636 | return 0; |
| 1644 | 1637 | } |
| 1645 | −EXPORT_SYMBOL_GPL(target_submit); | |
| 1646 | 1638 | |
| 1647 | 1639 | sense_reason_t |
| 1648 | 1640 | transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *sgl, |
| @@ -1904,7 +1896,7 @@ void target_queued_submit_work(struct work_struct *work) · 255 unmodified lines | ||
| 1904 | 1896 | se_plug = target_plug_device(se_dev); |
| 1905 | 1897 | } |
| 1906 | 1898 | |
| 1907 | − target_submit(se_cmd); | |
| 1899 | + __target_submit(se_cmd); | |
| 1908 | 1900 | } |
| 1909 | 1901 | |
| 1910 | 1902 | if (se_plug) |
| @@ -1927,6 +1919,35 @@ void target_queue_submission(struct se_cmd *se_cmd) · 16 unmodified lines | ||
| 1927 | 1919 | } |
| 1928 | 1920 | EXPORT_SYMBOL_GPL(target_queue_submission); |
| 1929 | 1921 | |
| 1922 | +/** | |
| 1923 | + * target_submit - perform final initialization and submit cmd to LIO core | |
| 1924 | + * @cmd: command descriptor to submit | |
| 1925 | + * | |
| 1926 | + * target_submit_prep or something similar must have been called on the cmd, | |
| 1927 | + * and this must be called from process context. | |
| 1928 | + */ | |
| 1929 | +int target_submit(struct se_cmd *se_cmd) | |
| 1930 | +{ | |
| 1931 | + const struct target_core_fabric_ops *tfo = se_cmd->se_sess->se_tpg->se_tpg_tfo; | |
| 1932 | + struct se_dev_attrib *da = &se_cmd->se_dev->dev_attrib; | |
| 1933 | + u8 submit_type; | |
| 1934 | + | |
| 1935 | + if (da->submit_type == TARGET_FABRIC_DEFAULT_SUBMIT) | |
| 1936 | + submit_type = tfo->default_submit_type; | |
| 1937 | + else if (da->submit_type == TARGET_DIRECT_SUBMIT && | |
| 1938 | + tfo->direct_submit_supp) | |
| 1939 | + submit_type = TARGET_DIRECT_SUBMIT; | |
| 1940 | + else | |
| 1941 | + submit_type = TARGET_QUEUE_SUBMIT; | |
| 1942 | + | |
| 1943 | + if (submit_type == TARGET_DIRECT_SUBMIT) | |
| 1944 | + return __target_submit(se_cmd); | |
| 1945 | + | |
| 1946 | + target_queue_submission(se_cmd); | |
| 1947 | + return 0; | |
| 1948 | +} | |
| 1949 | +EXPORT_SYMBOL_GPL(target_submit); | |
| 1950 | + | |
| 1930 | 1951 | static void target_complete_tmr_failure(struct work_struct *work) |
| 1931 | 1952 | { |
| 1932 | 1953 | struct se_cmd *se_cmd = container_of(work, struct se_cmd, work); |
| @@ -909,7 +909,7 @@ static void vhost_scsi_target_queue_cmd(struct vhost_scsi_cmd *cmd) · 908 unmodified lines | ||
| 909 | 909 | cmd->tvc_prot_sgl_count, GFP_KERNEL)) |
| 910 | 910 | return; |
| 911 | 911 | |
| 912 | − target_queue_submission(se_cmd); | |
| 912 | + target_submit(se_cmd); | |
| 913 | 913 | } |
| 914 | 914 | |
| 915 | 915 | static void |
| @@ -726,6 +726,7 @@ struct se_dev_attrib { · 725 unmodified lines | ||
| 726 | 726 | u32 unmap_granularity; |
| 727 | 727 | u32 unmap_granularity_alignment; |
| 728 | 728 | u32 max_write_same_len; |
| 729 | + u8 submit_type; | |
| 729 | 730 | struct se_device *da_dev; |
| 730 | 731 | struct config_group da_group; |
| 731 | 732 | }; |