tcm: Add Thin Provisioning / UNMAP emulation and Block Limits VPD page
Subsystems (2)
PATCH 1/3 tcm: Add Thin Provisioning / UNMAP emulation and Block Limits VPD page
From: Nicholas Bellinger <[email protected]>
This patch adds a generic Thin Provisioning enabled (TPE=1) emulation and a new transport_generic_unmap() exported caller used by TCM/IBLOCK and TCM/FILEIO to issue blkdev_issue_discard() for a received LBA + Range to a struct block_device. This includes the addition of UNMAP in transport_generic_cmd_sequencer() for both the DEV_ATTRIB(dev)->emulate_tpe=1 case for IBLOCK/FILEIO and the passthrough case for TCM/pSCSI.
Tthis patch also adds the Block Limits VPD (0xb0) page for INQUIRY EVPD=1 to report both emulate_tpe=1 and emulate_tpe=0 cases. This page returns the these values, the ones related to TPE=1 have been added into struct se_dev_attrib:
*) OPTIMAL TRANSFER LENGTH GRANULARITY *) MAXIMUM TRANSFER LENGTH
*) OPTIMAL TRANSFER LENGTH
*) MAXIMUM UNMAP LBA COUNT (tpe=1)
*) MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT (tpe=1) *) OPTIMAL UNMAP GRANULARITY (tpe=1) *) UNMAP GRANULARITY ALIGNMENT (tpe=1)
the TPE=1 releated values in Block Limits VPD also now appear along with optimal_sectors as new configfs attributes in:
/sys/kernel/config/target/core/$HBA/$DEV/attrib/
Finally, this patch updates transport_generic_emulate_readcapacity() to signal SA READ_CAPACITY16 and updates transport_generic_emulate_readcapacity_16() to set TPE=1 bit when emulate_tpe=1.
--- drivers/target/target_core_configfs.c | 24 +++++ drivers/target/target_core_device.c | 90 +++++++++++++++++++ drivers/target/target_core_transport.c | 152 ++++++++++++++++++++++++++++++++ include/target/target_core_base.h | 9 ++- include/target/target_core_device.h | 6 ++ include/target/target_core_transport.h | 11 +++ 6 files changed, 291 insertions(+), 1 deletions(-)
drivers/target/target_core_configfs.c +24 -0
@@ -563,6 +563,9 @@ SE_DEV_ATTR(emulate_ua_intlck_ctrl, S_IRUGO | S_IWUSR);DEF_DEV_ATTRIB (emulate_tas);SE_DEV_ATTR (emulate_tas,S_IRUGO |S_IWUSR ); +DEF_DEV_ATTRIB (emulate_tpe); +SE_DEV_ATTR (emulate_tpe,S_IRUGO |S_IWUSR ); +DEF_DEV_ATTRIB (enforce_pr_isids);SE_DEV_ATTR (enforce_pr_isids,S_IRUGO |S_IWUSR );
@@ -578,6 +581,9 @@ SE_DEV_ATTR_RO(hw_max_sectors);DEF_DEV_ATTRIB (max_sectors);SE_DEV_ATTR (max_sectors,S_IRUGO |S_IWUSR ); +DEF_DEV_ATTRIB (optimal_sectors); +SE_DEV_ATTR (optimal_sectors,S_IRUGO |S_IWUSR ); +DEF_DEV_ATTRIB_RO (hw_queue_depth);SE_DEV_ATTR_RO (hw_queue_depth);
@@ -587,6 +593,18 @@ SE_DEV_ATTR(queue_depth, S_IRUGO | S_IWUSR);DEF_DEV_ATTRIB (task_timeout);SE_DEV_ATTR (task_timeout,S_IRUGO |S_IWUSR ); +DEF_DEV_ATTRIB (max_unmap_lba_count); +SE_DEV_ATTR (max_unmap_lba_count,S_IRUGO |S_IWUSR ); + +DEF_DEV_ATTRIB (max_unmap_block_desc_count); +SE_DEV_ATTR (max_unmap_block_desc_count,S_IRUGO |S_IWUSR ); + +DEF_DEV_ATTRIB (unmap_granularity); +SE_DEV_ATTR (unmap_granularity,S_IRUGO |S_IWUSR ); + +DEF_DEV_ATTRIB (unmap_granularity_alignment); +SE_DEV_ATTR (unmap_granularity_alignment,S_IRUGO |S_IWUSR ); +CONFIGFS_EATTR_OPS (target_core_dev_attrib, se_dev_attrib, da_group);static struct configfs_attribute *target_core_dev_attrib_attrs[] = {
@@ -596,14 +614,20 @@ static struct configfs_attribute *target_core_dev_attrib_attrs[] = { &target_core_dev_attrib_emulate_write_cache.attr, &target_core_dev_attrib_emulate_ua_intlck_ctrl.attr, &target_core_dev_attrib_emulate_tas.attr, + &target_core_dev_attrib_emulate_tpe.attr, &target_core_dev_attrib_enforce_pr_isids.attr, &target_core_dev_attrib_hw_block_size.attr, &target_core_dev_attrib_block_size.attr, &target_core_dev_attrib_hw_max_sectors.attr, &target_core_dev_attrib_max_sectors.attr, + &target_core_dev_attrib_optimal_sectors.attr, &target_core_dev_attrib_hw_queue_depth.attr, &target_core_dev_attrib_queue_depth.attr, &target_core_dev_attrib_task_timeout.attr, + &target_core_dev_attrib_max_unmap_lba_count.attr, + &target_core_dev_attrib_max_unmap_block_desc_count.attr, + &target_core_dev_attrib_unmap_granularity.attr, + &target_core_dev_attrib_unmap_granularity_alignment.attr, NULL, };
drivers/target/target_core_device.c +90 -0
123 lines not on this page · raw message
drivers/target/target_core_transport.c +152 -0
182 lines not on this page · raw message
include/target/target_core_base.h +8 -1
@@ -136,7 +136,8 @@ enum se_cmd_flags_table {SCF_PASSTHROUGH_CONTIG_TO_SG =0x00400000 ,SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC =0x00800000 ,SCF_EMULATE_SYNC_CACHE =0x01000000 , - SCF_EMULATE_CDB_ASYNC = 0x02000000 +SCF_EMULATE_CDB_ASYNC =0x02000000 , + SCF_EMULATE_SYNC_UNMAP = 0x04000000 };/* struct se_device->type for known subsystem plugins */
@@ -748,6 +749,7 @@ struct se_dev_attrib {int emulate_write_cache;int emulate_ua_intlck_ctrl;int emulate_tas; +int emulate_tpe;int emulate_reservations;int emulate_alua;int enforce_pr_isids;
@@ -755,9 +757,14 @@ struct se_dev_attrib {u32 block_size;u32 hw_max_sectors;u32 max_sectors; +u32 optimal_sectors;u32 hw_queue_depth;u32 queue_depth;u32 task_timeout; +u32 max_unmap_lba_count; +u32 max_unmap_block_desc_count; +u32 unmap_granularity; +u32 unmap_granularity_alignment;struct se_subsystem_dev *da_sub_dev;struct config_group da_group; }____cacheline_aligned ;
include/target/target_core_device.h +6 -0
@@ -38,15 +38,21 @@ extern int se_dev_check_online(struct se_device *);extern int se_dev_check_shutdown (struct se_device *);extern void se_dev_set_default_attribs (struct se_device *);extern int se_dev_set_task_timeout (struct se_device *,u32 ); +extern int se_dev_set_max_unmap_lba_count (struct se_device *,u32 ); +extern int se_dev_set_max_unmap_block_desc_count (struct se_device *,u32 ); +extern int se_dev_set_unmap_granularity (struct se_device *,u32 ); +extern int se_dev_set_unmap_granularity_alignment (struct se_device *,u32 );extern int se_dev_set_emulate_dpo (struct se_device *,int );extern int se_dev_set_emulate_fua_write (struct se_device *,int );extern int se_dev_set_emulate_fua_read (struct se_device *,int );extern int se_dev_set_emulate_write_cache (struct se_device *,int );extern int se_dev_set_emulate_ua_intlck_ctrl (struct se_device *,int );extern int se_dev_set_emulate_tas (struct se_device *,int ); +extern int se_dev_set_emulate_tpe (struct se_device *,int );extern int se_dev_set_enforce_pr_isids (struct se_device *,int );extern int se_dev_set_queue_depth (struct se_device *,u32 );extern int se_dev_set_max_sectors (struct se_device *,u32 ); +extern int se_dev_set_optimal_sectors (struct se_device *,u32 );extern int se_dev_set_block_size (struct se_device *,u32 );extern struct se_lun *core_dev_add_lun (struct se_portal_group *,struct se_hba *,struct se_device *,u32 );
include/target/target_core_transport.h +11 -0
@@ -87,6 +87,14 @@/* struct se_dev_attrib sanity values */ /* 10 Minutes, see transport_get_default_task_timeout() */ #define DA_TASK_TIMEOUT_MAX 600 +/* Default max_unmap_lba_count */ +#define DA_MAX_UNMAP_LBA_COUNT 0 +/* Default max_unmap_block_desc_count */ +#define DA_MAX_UNMAP_BLOCK_DESC_COUNT 0 +/* Default unmap_granularity */ +#define DA_UNMAP_GRANULARITY_DEFAULT 0 +/* Default unmap_granularity_alignment */ +#define DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT 0/* Emulation for Direct Page Out */ #define DA_EMULATE_DPO 0/* Emulation for Forced Unit Access WRITEs */
@@ -99,6 +107,8 @@#define DA_EMULATE_UA_INTLLCK_CTRL 0/* Emulation for TASK_ABORTED status (TAS) by default */ #define DA_EMULATE_TAS 1 +/* Emulation for Thin Provisioning Enabled using block/blk-lib.c:blkdev_issue_discard() */ +#define DA_EMULATE_TPE 0/* No Emulation for PSCSI by default */ #define DA_EMULATE_RESERVATIONS 0/* No Emulation for PSCSI by default */
@@ -224,6 +234,7 @@ extern int transport_generic_emulate_modesense(struct se_cmd *,extern int transport_generic_emulate_request_sense (struct se_cmd *,unsigned char *);extern int transport_get_sense_data (struct se_cmd *); +extern int transport_generic_unmap (struct se_cmd *,struct block_device *);extern struct se_cmd *transport_allocate_passthrough (unsigned char *,int ,u32 ,void *,u32 ,u32 ,void *);extern void transport_passthrough_release (struct se_cmd *);
Signature · 1 line
1.5.6.5
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
"nab" == Nicholas A Bellinger <[email protected]> writes:
nab> This patch also adds the Block Limits VPD (0xb0) page
You should add the Thin Provisioning VPD page as well and set TPU and/or TPWS.
Signature · 1 line
Martin K. Petersen Oracle Linux Engineering
Quoted 7 lines · Martin K. Petersen
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
"nab" == Nicholas A Bellinger <[email protected]> writes:
nab> This patch also adds the Block Limits VPD (
0xb0) pageYou should add the Thin Provisioning VPD page as well and set TPU and/or TPWS.
Greetings mkp,
So I was looking at adding this VPD page orginally to set TPU=1 w/ DP=0 (because I don't believe there is currently way to get build the PROVISIONING GROUP DESCRIPTORs from Block Discard knowledge), but I ended getting a bit confused by the THRESHOLD EXPONENT, and what value this should returned for the TCM/IBLOCK and TCM/FILEIO backstores when blk_queue_discard()==1 is enabled.
Since this is currently not implemented in scsi_debug.c or used in any way by sd.c AFAICT, do you have any additional information on how this should be determined together with the UNMAP -> blk_issue_discard() emulation bits..?
Thanks!
--nab