Skip to content

Commit

Permalink
scsi: target: Allow userspace to request direct submissions
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
Link: https://lore.kernel.org/r/20230928020907.5730-6-michael.christie@oracle.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
Mike Christie authored and Martin K. Petersen committed Oct 13, 2023
1 parent 4289267 commit e2f4ea4
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 12 deletions.
2 changes: 1 addition & 1 deletion drivers/target/loopback/tcm_loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ static void tcm_loop_target_queue_cmd(struct tcm_loop_cmd *tl_cmd)
GFP_ATOMIC))
return;

target_queue_submission(se_cmd);
target_submit(se_cmd);
return;

out_done:
Expand Down
22 changes: 22 additions & 0 deletions drivers/target/target_core_configfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,7 @@ DEF_CONFIGFS_ATTRIB_SHOW(unmap_granularity_alignment);
DEF_CONFIGFS_ATTRIB_SHOW(unmap_zeroes_data);
DEF_CONFIGFS_ATTRIB_SHOW(max_write_same_len);
DEF_CONFIGFS_ATTRIB_SHOW(emulate_rsoc);
DEF_CONFIGFS_ATTRIB_SHOW(submit_type);

#define DEF_CONFIGFS_ATTRIB_STORE_U32(_name) \
static ssize_t _name##_store(struct config_item *item, const char *page,\
Expand Down Expand Up @@ -1231,6 +1232,24 @@ static ssize_t emulate_rsoc_store(struct config_item *item,
return count;
}

static ssize_t submit_type_store(struct config_item *item, const char *page,
size_t count)
{
struct se_dev_attrib *da = to_attrib(item);
int ret;
u8 val;

ret = kstrtou8(page, 0, &val);
if (ret < 0)
return ret;

if (val > TARGET_QUEUE_SUBMIT)
return -EINVAL;

da->submit_type = val;
return count;
}

CONFIGFS_ATTR(, emulate_model_alias);
CONFIGFS_ATTR(, emulate_dpo);
CONFIGFS_ATTR(, emulate_fua_write);
Expand Down Expand Up @@ -1266,6 +1285,7 @@ CONFIGFS_ATTR(, unmap_zeroes_data);
CONFIGFS_ATTR(, max_write_same_len);
CONFIGFS_ATTR(, alua_support);
CONFIGFS_ATTR(, pgr_support);
CONFIGFS_ATTR(, submit_type);

/*
* dev_attrib attributes for devices using the target core SBC/SPC
Expand Down Expand Up @@ -1308,6 +1328,7 @@ struct configfs_attribute *sbc_attrib_attrs[] = {
&attr_alua_support,
&attr_pgr_support,
&attr_emulate_rsoc,
&attr_submit_type,
NULL,
};
EXPORT_SYMBOL(sbc_attrib_attrs);
Expand All @@ -1325,6 +1346,7 @@ struct configfs_attribute *passthrough_attrib_attrs[] = {
&attr_emulate_pr,
&attr_alua_support,
&attr_pgr_support,
&attr_submit_type,
NULL,
};
EXPORT_SYMBOL(passthrough_attrib_attrs);
Expand Down
1 change: 1 addition & 0 deletions drivers/target/target_core_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
dev->dev_attrib.unmap_zeroes_data =
DA_UNMAP_ZEROES_DATA_DEFAULT;
dev->dev_attrib.max_write_same_len = DA_MAX_WRITE_SAME_LEN;
dev->dev_attrib.submit_type = TARGET_FABRIC_DEFAULT_SUBMIT;

xcopy_lun = &dev->xcopy_lun;
rcu_assign_pointer(xcopy_lun->lun_se_dev, dev);
Expand Down
41 changes: 31 additions & 10 deletions drivers/target/target_core_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -1575,14 +1575,7 @@ target_cmd_parse_cdb(struct se_cmd *cmd)
}
EXPORT_SYMBOL(target_cmd_parse_cdb);

/**
* target_submit - perform final initialization and submit cmd to LIO core
* @cmd: command descriptor to submit
*
* target_submit_prep or something similar must have been called on the cmd,
* and this must be called from process context.
*/
int target_submit(struct se_cmd *cmd)
static int __target_submit(struct se_cmd *cmd)
{
sense_reason_t ret;

Expand Down Expand Up @@ -1642,7 +1635,6 @@ int target_submit(struct se_cmd *cmd)
transport_generic_request_failure(cmd, ret);
return 0;
}
EXPORT_SYMBOL_GPL(target_submit);

sense_reason_t
transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *sgl,
Expand Down Expand Up @@ -1904,7 +1896,7 @@ void target_queued_submit_work(struct work_struct *work)
se_plug = target_plug_device(se_dev);
}

target_submit(se_cmd);
__target_submit(se_cmd);
}

if (se_plug)
Expand All @@ -1927,6 +1919,35 @@ void target_queue_submission(struct se_cmd *se_cmd)
}
EXPORT_SYMBOL_GPL(target_queue_submission);

/**
* target_submit - perform final initialization and submit cmd to LIO core
* @cmd: command descriptor to submit
*
* target_submit_prep or something similar must have been called on the cmd,
* and this must be called from process context.
*/
int target_submit(struct se_cmd *se_cmd)
{
const struct target_core_fabric_ops *tfo = se_cmd->se_sess->se_tpg->se_tpg_tfo;
struct se_dev_attrib *da = &se_cmd->se_dev->dev_attrib;
u8 submit_type;

if (da->submit_type == TARGET_FABRIC_DEFAULT_SUBMIT)
submit_type = tfo->default_submit_type;
else if (da->submit_type == TARGET_DIRECT_SUBMIT &&
tfo->direct_submit_supp)
submit_type = TARGET_DIRECT_SUBMIT;
else
submit_type = TARGET_QUEUE_SUBMIT;

if (submit_type == TARGET_DIRECT_SUBMIT)
return __target_submit(se_cmd);

target_queue_submission(se_cmd);
return 0;
}
EXPORT_SYMBOL_GPL(target_submit);

static void target_complete_tmr_failure(struct work_struct *work)
{
struct se_cmd *se_cmd = container_of(work, struct se_cmd, work);
Expand Down
2 changes: 1 addition & 1 deletion drivers/vhost/scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,7 @@ static void vhost_scsi_target_queue_cmd(struct vhost_scsi_cmd *cmd)
cmd->tvc_prot_sgl_count, GFP_KERNEL))
return;

target_queue_submission(se_cmd);
target_submit(se_cmd);
}

static void
Expand Down
1 change: 1 addition & 0 deletions include/target/target_core_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,7 @@ struct se_dev_attrib {
u32 unmap_granularity;
u32 unmap_granularity_alignment;
u32 max_write_same_len;
u8 submit_type;
struct se_device *da_dev;
struct config_group da_group;
};
Expand Down

0 comments on commit e2f4ea4

Please sign in to comment.