Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge patch series "scsi: target: Add support for completing commands from backend context"

The following patches made over Linus's current tree allow users to
tell the target layer to perform direct completions instead of always
deferring to LIO's completion workqueue. When the frontend driver
already has multiple worker threads (or you are doing a LUN per target
with a single thread per target) then bypassing the LIO workqueue can
increase performance 20-30%.

Link: https://patch.msgid.link/20260222232946.7637-1-michael.christie@oracle.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

+129 -14
+1
drivers/infiniband/ulp/srpt/ib_srpt.c
··· 3925 3925 .tfc_wwn_attrs = srpt_wwn_attrs, 3926 3926 .tfc_tpg_attrib_attrs = srpt_tpg_attrib_attrs, 3927 3927 3928 + .default_compl_type = TARGET_QUEUE_COMPL, 3928 3929 .default_submit_type = TARGET_DIRECT_SUBMIT, 3929 3930 .direct_submit_supp = 1, 3930 3931 };
+2
drivers/scsi/elx/efct/efct_lio.c
··· 1612 1612 .sess_get_initiator_sid = NULL, 1613 1613 .tfc_tpg_base_attrs = efct_lio_tpg_attrs, 1614 1614 .tfc_tpg_attrib_attrs = efct_lio_tpg_attrib_attrs, 1615 + .default_compl_type = TARGET_QUEUE_COMPL, 1615 1616 .default_submit_type = TARGET_DIRECT_SUBMIT, 1616 1617 .direct_submit_supp = 1, 1617 1618 }; ··· 1651 1650 .tfc_tpg_base_attrs = efct_lio_npiv_tpg_attrs, 1652 1651 .tfc_tpg_attrib_attrs = efct_lio_npiv_tpg_attrib_attrs, 1653 1652 1653 + .default_compl_type = TARGET_QUEUE_COMPL, 1654 1654 .default_submit_type = TARGET_DIRECT_SUBMIT, 1655 1655 .direct_submit_supp = 1, 1656 1656 };
+1
drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
··· 3968 3968 3969 3969 .tfc_wwn_attrs = ibmvscsis_wwn_attrs, 3970 3970 3971 + .default_compl_type = TARGET_QUEUE_COMPL, 3971 3972 .default_submit_type = TARGET_DIRECT_SUBMIT, 3972 3973 .direct_submit_supp = 1, 3973 3974 };
+2
drivers/scsi/qla2xxx/tcm_qla2xxx.c
··· 1841 1841 .tfc_tpg_base_attrs = tcm_qla2xxx_tpg_attrs, 1842 1842 .tfc_tpg_attrib_attrs = tcm_qla2xxx_tpg_attrib_attrs, 1843 1843 1844 + .default_compl_type = TARGET_QUEUE_COMPL, 1844 1845 .default_submit_type = TARGET_DIRECT_SUBMIT, 1845 1846 .direct_submit_supp = 1, 1846 1847 }; ··· 1882 1881 1883 1882 .tfc_wwn_attrs = tcm_qla2xxx_wwn_attrs, 1884 1883 1884 + .default_compl_type = TARGET_QUEUE_COMPL, 1885 1885 .default_submit_type = TARGET_DIRECT_SUBMIT, 1886 1886 .direct_submit_supp = 1, 1887 1887 };
+1
drivers/target/iscsi/iscsi_target_configfs.c
··· 1591 1591 1592 1592 .write_pending_must_be_called = 1, 1593 1593 1594 + .default_compl_type = TARGET_QUEUE_COMPL, 1594 1595 .default_submit_type = TARGET_DIRECT_SUBMIT, 1595 1596 .direct_submit_supp = 1, 1596 1597 };
+1
drivers/target/loopback/tcm_loop.c
··· 1107 1107 .tfc_wwn_attrs = tcm_loop_wwn_attrs, 1108 1108 .tfc_tpg_base_attrs = tcm_loop_tpg_attrs, 1109 1109 .tfc_tpg_attrib_attrs = tcm_loop_tpg_attrib_attrs, 1110 + .default_compl_type = TARGET_QUEUE_COMPL, 1110 1111 .default_submit_type = TARGET_QUEUE_SUBMIT, 1111 1112 .direct_submit_supp = 0, 1112 1113 };
+1
drivers/target/sbp/sbp_target.c
··· 2278 2278 .tfc_tpg_base_attrs = sbp_tpg_base_attrs, 2279 2279 .tfc_tpg_attrib_attrs = sbp_tpg_attrib_attrs, 2280 2280 2281 + .default_compl_type = TARGET_QUEUE_COMPL, 2281 2282 .default_submit_type = TARGET_DIRECT_SUBMIT, 2282 2283 .direct_submit_supp = 1, 2283 2284 };
+22
drivers/target/target_core_configfs.c
··· 578 578 DEF_CONFIGFS_ATTRIB_SHOW(max_write_same_len); 579 579 DEF_CONFIGFS_ATTRIB_SHOW(emulate_rsoc); 580 580 DEF_CONFIGFS_ATTRIB_SHOW(submit_type); 581 + DEF_CONFIGFS_ATTRIB_SHOW(complete_type); 581 582 DEF_CONFIGFS_ATTRIB_SHOW(atomic_max_len); 582 583 DEF_CONFIGFS_ATTRIB_SHOW(atomic_alignment); 583 584 DEF_CONFIGFS_ATTRIB_SHOW(atomic_granularity); ··· 1270 1269 return count; 1271 1270 } 1272 1271 1272 + static ssize_t complete_type_store(struct config_item *item, const char *page, 1273 + size_t count) 1274 + { 1275 + struct se_dev_attrib *da = to_attrib(item); 1276 + int ret; 1277 + u8 val; 1278 + 1279 + ret = kstrtou8(page, 0, &val); 1280 + if (ret < 0) 1281 + return ret; 1282 + 1283 + if (val > TARGET_QUEUE_COMPL) 1284 + return -EINVAL; 1285 + 1286 + da->complete_type = val; 1287 + return count; 1288 + } 1289 + 1273 1290 CONFIGFS_ATTR(, emulate_model_alias); 1274 1291 CONFIGFS_ATTR(, emulate_dpo); 1275 1292 CONFIGFS_ATTR(, emulate_fua_write); ··· 1324 1305 CONFIGFS_ATTR(, alua_support); 1325 1306 CONFIGFS_ATTR(, pgr_support); 1326 1307 CONFIGFS_ATTR(, submit_type); 1308 + CONFIGFS_ATTR(, complete_type); 1327 1309 CONFIGFS_ATTR_RO(, atomic_max_len); 1328 1310 CONFIGFS_ATTR_RO(, atomic_alignment); 1329 1311 CONFIGFS_ATTR_RO(, atomic_granularity); ··· 1373 1353 &attr_pgr_support, 1374 1354 &attr_emulate_rsoc, 1375 1355 &attr_submit_type, 1356 + &attr_complete_type, 1376 1357 &attr_atomic_alignment, 1377 1358 &attr_atomic_max_len, 1378 1359 &attr_atomic_granularity, ··· 1397 1376 &attr_alua_support, 1398 1377 &attr_pgr_support, 1399 1378 &attr_submit_type, 1379 + &attr_complete_type, 1400 1380 NULL, 1401 1381 }; 1402 1382 EXPORT_SYMBOL(passthrough_attrib_attrs);
+1
drivers/target/target_core_device.c
··· 813 813 DA_UNMAP_ZEROES_DATA_DEFAULT; 814 814 dev->dev_attrib.max_write_same_len = DA_MAX_WRITE_SAME_LEN; 815 815 dev->dev_attrib.submit_type = TARGET_FABRIC_DEFAULT_SUBMIT; 816 + dev->dev_attrib.submit_type = TARGET_FABRIC_DEFAULT_COMPL; 816 817 817 818 /* Skip allocating lun_stats since we can't export them. */ 818 819 xcopy_lun = &dev->xcopy_lun;
+24
drivers/target/target_core_fabric_configfs.c
··· 1066 1066 CONFIGFS_ATTR(target_fabric_wwn_, cmd_completion_affinity); 1067 1067 1068 1068 static ssize_t 1069 + target_fabric_wwn_default_complete_type_show(struct config_item *item, 1070 + char *page) 1071 + { 1072 + struct se_wwn *wwn = container_of(to_config_group(item), struct se_wwn, 1073 + param_group); 1074 + return sysfs_emit(page, "%u\n", 1075 + wwn->wwn_tf->tf_ops->default_compl_type); 1076 + } 1077 + CONFIGFS_ATTR_RO(target_fabric_wwn_, default_complete_type); 1078 + 1079 + static ssize_t 1080 + target_fabric_wwn_direct_complete_supported_show(struct config_item *item, 1081 + char *page) 1082 + { 1083 + struct se_wwn *wwn = container_of(to_config_group(item), struct se_wwn, 1084 + param_group); 1085 + return sysfs_emit(page, "%u\n", 1086 + wwn->wwn_tf->tf_ops->direct_compl_supp); 1087 + } 1088 + CONFIGFS_ATTR_RO(target_fabric_wwn_, direct_complete_supported); 1089 + 1090 + static ssize_t 1069 1091 target_fabric_wwn_default_submit_type_show(struct config_item *item, 1070 1092 char *page) 1071 1093 { ··· 1111 1089 1112 1090 static struct configfs_attribute *target_fabric_wwn_param_attrs[] = { 1113 1091 &target_fabric_wwn_attr_cmd_completion_affinity, 1092 + &target_fabric_wwn_attr_default_complete_type, 1093 + &target_fabric_wwn_attr_direct_complete_supported, 1114 1094 &target_fabric_wwn_attr_default_submit_type, 1115 1095 &target_fabric_wwn_attr_direct_submit_supported, 1116 1096 NULL,
+49 -11
drivers/target/target_core_transport.c
··· 902 902 return false; 903 903 } 904 904 905 + static void target_complete(struct se_cmd *cmd, int success) 906 + { 907 + struct se_wwn *wwn = cmd->se_sess->se_tpg->se_tpg_wwn; 908 + struct se_dev_attrib *da; 909 + u8 compl_type; 910 + int cpu; 911 + 912 + if (!wwn) { 913 + cpu = cmd->cpuid; 914 + goto queue_work; 915 + } 916 + 917 + da = &cmd->se_dev->dev_attrib; 918 + if (da->complete_type == TARGET_FABRIC_DEFAULT_COMPL) 919 + compl_type = wwn->wwn_tf->tf_ops->default_compl_type; 920 + else if (da->complete_type == TARGET_DIRECT_SUBMIT && 921 + wwn->wwn_tf->tf_ops->direct_compl_supp) 922 + compl_type = TARGET_DIRECT_COMPL; 923 + else 924 + compl_type = TARGET_QUEUE_COMPL; 925 + 926 + if (compl_type == TARGET_DIRECT_COMPL) { 927 + /* 928 + * Failure handling and processing secondary stages of 929 + * complex commands can be too heavy to handle from the 930 + * fabric driver so always defer. 931 + */ 932 + if (success && !cmd->transport_complete_callback) { 933 + target_complete_ok_work(&cmd->work); 934 + return; 935 + } 936 + 937 + compl_type = TARGET_QUEUE_COMPL; 938 + } 939 + 940 + queue_work: 941 + INIT_WORK(&cmd->work, success ? target_complete_ok_work : 942 + target_complete_failure_work); 943 + 944 + if (!wwn || wwn->cmd_compl_affinity == SE_COMPL_AFFINITY_CPUID) 945 + cpu = cmd->cpuid; 946 + else 947 + cpu = wwn->cmd_compl_affinity; 948 + 949 + queue_work_on(cpu, target_completion_wq, &cmd->work); 950 + } 951 + 905 952 /* May be called from interrupt context so must not sleep. */ 906 953 void target_complete_cmd_with_sense(struct se_cmd *cmd, u8 scsi_status, 907 954 sense_reason_t sense_reason) 908 955 { 909 - struct se_wwn *wwn = cmd->se_sess->se_tpg->se_tpg_wwn; 910 - int success, cpu; 911 956 unsigned long flags; 957 + int success; 912 958 913 959 if (target_cmd_interrupted(cmd)) 914 960 return; ··· 979 933 cmd->transport_state |= (CMD_T_COMPLETE | CMD_T_ACTIVE); 980 934 spin_unlock_irqrestore(&cmd->t_state_lock, flags); 981 935 982 - INIT_WORK(&cmd->work, success ? target_complete_ok_work : 983 - target_complete_failure_work); 984 - 985 - if (!wwn || wwn->cmd_compl_affinity == SE_COMPL_AFFINITY_CPUID) 986 - cpu = cmd->cpuid; 987 - else 988 - cpu = wwn->cmd_compl_affinity; 989 - 990 - queue_work_on(cpu, target_completion_wq, &cmd->work); 936 + target_complete(cmd, success); 991 937 } 992 938 EXPORT_SYMBOL(target_complete_cmd_with_sense); 993 939
+1
drivers/target/tcm_fc/tfc_conf.c
··· 434 434 .tfc_wwn_attrs = ft_wwn_attrs, 435 435 .tfc_tpg_nacl_base_attrs = ft_nacl_base_attrs, 436 436 437 + .default_compl_type = TARGET_QUEUE_COMPL, 437 438 .default_submit_type = TARGET_DIRECT_SUBMIT, 438 439 .direct_submit_supp = 1, 439 440 };
+1
drivers/usb/gadget/function/f_tcm.c
··· 2016 2016 .tfc_wwn_attrs = usbg_wwn_attrs, 2017 2017 .tfc_tpg_base_attrs = usbg_base_attrs, 2018 2018 2019 + .default_compl_type = TARGET_QUEUE_COMPL, 2019 2020 .default_submit_type = TARGET_DIRECT_SUBMIT, 2020 2021 .direct_submit_supp = 1, 2021 2022 };
+2
drivers/vhost/scsi.c
··· 2950 2950 .tfc_tpg_base_attrs = vhost_scsi_tpg_attrs, 2951 2951 .tfc_tpg_attrib_attrs = vhost_scsi_tpg_attrib_attrs, 2952 2952 2953 + .default_compl_type = TARGET_QUEUE_COMPL, 2954 + .direct_compl_supp = 1, 2953 2955 .default_submit_type = TARGET_QUEUE_SUBMIT, 2954 2956 .direct_submit_supp = 1, 2955 2957 };
+1
drivers/xen/xen-scsiback.c
··· 1832 1832 .tfc_tpg_base_attrs = scsiback_tpg_attrs, 1833 1833 .tfc_tpg_param_attrs = scsiback_param_attrs, 1834 1834 1835 + .default_compl_type = TARGET_QUEUE_COMPL, 1835 1836 .default_submit_type = TARGET_DIRECT_SUBMIT, 1836 1837 .direct_submit_supp = 1, 1837 1838 };
+10
include/target/target_core_base.h
··· 111 111 /* Peripheral Device Text Identification Information */ 112 112 #define PD_TEXT_ID_INFO_LEN 256 113 113 114 + enum target_compl_type { 115 + /* Use the fabric driver's default completion type */ 116 + TARGET_FABRIC_DEFAULT_COMPL, 117 + /* Complete from the backend calling context */ 118 + TARGET_DIRECT_COMPL, 119 + /* Defer completion to the LIO workqueue */ 120 + TARGET_QUEUE_COMPL, 121 + }; 122 + 114 123 enum target_submit_type { 115 124 /* Use the fabric driver's default submission type */ 116 125 TARGET_FABRIC_DEFAULT_SUBMIT, ··· 750 741 u32 atomic_granularity; 751 742 u32 atomic_max_with_boundary; 752 743 u32 atomic_max_boundary; 744 + u8 complete_type; 753 745 u8 submit_type; 754 746 struct se_device *da_dev; 755 747 struct config_group da_group;
+9 -3
include/target/target_core_fabric.h
··· 119 119 */ 120 120 unsigned int write_pending_must_be_called:1; 121 121 /* 122 + * Set this if the driver does not require calling queue_data_in 123 + * queue_status and check_stop_free from a worker thread when 124 + * completing successful commands. 125 + */ 126 + unsigned int direct_compl_supp:1; 127 + /* 122 128 * Set this if the driver supports submitting commands to the backend 123 129 * from target_submit/target_submit_cmd. 124 130 */ 125 131 unsigned int direct_submit_supp:1; 126 - /* 127 - * Set this to a target_submit_type value. 128 - */ 132 + /* Set this to a target_submit_type value. */ 129 133 u8 default_submit_type; 134 + /* Set this to the target_compl_type value. */ 135 + u8 default_compl_type; 130 136 }; 131 137 132 138 int target_register_template(const struct target_core_fabric_ops *fo);