Skip to content
Permalink
Browse files
scsi: ufs: Add HPB 2.0 support
This patch supports the HPB 2.0.

The HPB 2.0 supports read of varying sizes from 4KB to 512KB.
In the case of Read (<= 32KB) is supported as single HPB read.
In the case of Read (36KB ~ 512KB) is supported by as a combination of
write buffer command and HPB read command to deliver more PPN.
The write buffer commands may not be issued immediately due to busy tags.
To use HPB read more aggressively, the driver can requeue the write buffer
command. The requeue threshold is implemented as timeout and can be
modified with requeue_timeout_ms entry in sysfs.

Signed-off-by: Daejun Park <daejun7.park@samsung.com>
  • Loading branch information
Daejun Park authored and intel-lab-lkp committed Mar 12, 2021
1 parent f89c8a0 commit a13bf626769280445ff1c6c5b0ab8dffb9439aa8
Show file tree
Hide file tree
Showing 7 changed files with 700 additions and 81 deletions.
@@ -1253,49 +1253,84 @@ Description: This entry shows the number of HPB pinned regions assigned to

The file is read only.

What: /sys/class/scsi_device/*/device/hpb_sysfs/hit_cnt
What: /sys/class/scsi_device/*/device/hpb_stat_sysfs/hit_cnt
Date: March 2021
Contact: Daejun Park <daejun7.park@samsung.com>
Description: This entry shows the number of reads that changed to HPB read.

The file is read only.

What: /sys/class/scsi_device/*/device/hpb_sysfs/miss_cnt
What: /sys/class/scsi_device/*/device/hpb_stat_sysfs/miss_cnt
Date: March 2021
Contact: Daejun Park <daejun7.park@samsung.com>
Description: This entry shows the number of reads that cannot be changed to
HPB read.

The file is read only.

What: /sys/class/scsi_device/*/device/hpb_sysfs/rb_noti_cnt
What: /sys/class/scsi_device/*/device/hpb_stat_sysfs/rb_noti_cnt
Date: March 2021
Contact: Daejun Park <daejun7.park@samsung.com>
Description: This entry shows the number of response UPIUs that has
recommendations for activating sub-regions and/or inactivating region.

The file is read only.

What: /sys/class/scsi_device/*/device/hpb_sysfs/rb_active_cnt
What: /sys/class/scsi_device/*/device/hpb_stat_sysfs/rb_active_cnt
Date: March 2021
Contact: Daejun Park <daejun7.park@samsung.com>
Description: This entry shows the number of active sub-regions recommended by
response UPIUs.

The file is read only.

What: /sys/class/scsi_device/*/device/hpb_sysfs/rb_inactive_cnt
What: /sys/class/scsi_device/*/device/hpb_stat_sysfs/rb_inactive_cnt
Date: March 2021
Contact: Daejun Park <daejun7.park@samsung.com>
Description: This entry shows the number of inactive regions recommended by
response UPIUs.

The file is read only.

What: /sys/class/scsi_device/*/device/hpb_sysfs/map_req_cnt
What: /sys/class/scsi_device/*/device/hpb_stat_sysfs/map_req_cnt
Date: March 2021
Contact: Daejun Park <daejun7.park@samsung.com>
Description: This entry shows the number of read buffer commands for
activating sub-regions recommended by response UPIUs.

The file is read only.

What: /sys/class/scsi_device/*/device/hpb_param_sysfs/requeue_timeout_ms
Date: March 2021
Contact: Daejun Park <daejun7.park@samsung.com>
Description: This entry shows the requeue timeout threshold for write buffer
command in ms. This value can be changed by writing proper integer to
this entry.

What: /sys/bus/platform/drivers/ufshcd/*/attributes/max_data_size_hpb_single_cmd
Date: March 2021
Contact: Daejun Park <daejun7.park@samsung.com>
Description: This entry shows the maximum HPB data size for using single HPB
command.

=== ========
00h 4KB
01h 8KB
02h 12KB
...
FFh 1024KB
=== ========

The file is read only.

What: /sys/bus/platform/drivers/ufshcd/*/flags/wb_enable
Date: March 2021
Contact: Daejun Park <daejun7.park@samsung.com>
Description: This entry shows the status of HPB.

== ============================
0 HPB is not enabled.
1 HPB is enabled
== ============================

The file is read only.
@@ -782,6 +782,7 @@ UFS_FLAG(disable_fw_update, _PERMANENTLY_DISABLE_FW_UPDATE);
UFS_FLAG(wb_enable, _WB_EN);
UFS_FLAG(wb_flush_en, _WB_BUFF_FLUSH_EN);
UFS_FLAG(wb_flush_during_h8, _WB_BUFF_FLUSH_DURING_HIBERN8);
UFS_FLAG(hpb_enable, _HPB_EN);

static struct attribute *ufs_sysfs_device_flags[] = {
&dev_attr_device_init.attr,
@@ -795,6 +796,7 @@ static struct attribute *ufs_sysfs_device_flags[] = {
&dev_attr_wb_enable.attr,
&dev_attr_wb_flush_en.attr,
&dev_attr_wb_flush_during_h8.attr,
&dev_attr_hpb_enable.attr,
NULL,
};

@@ -841,6 +843,7 @@ out: \
static DEVICE_ATTR_RO(_name)

UFS_ATTRIBUTE(boot_lun_enabled, _BOOT_LU_EN);
UFS_ATTRIBUTE(max_data_size_hpb_single_cmd, _MAX_HPB_SINGLE_CMD);
UFS_ATTRIBUTE(current_power_mode, _POWER_MODE);
UFS_ATTRIBUTE(active_icc_level, _ACTIVE_ICC_LVL);
UFS_ATTRIBUTE(ooo_data_enabled, _OOO_DATA_EN);
@@ -864,6 +867,7 @@ UFS_ATTRIBUTE(wb_cur_buf, _CURR_WB_BUFF_SIZE);

static struct attribute *ufs_sysfs_attributes[] = {
&dev_attr_boot_lun_enabled.attr,
&dev_attr_max_data_size_hpb_single_cmd.attr,
&dev_attr_current_power_mode.attr,
&dev_attr_active_icc_level.attr,
&dev_attr_ooo_data_enabled.attr,
@@ -123,12 +123,13 @@ enum flag_idn {
QUERY_FLAG_IDN_WB_BUFF_FLUSH_EN = 0x0F,
QUERY_FLAG_IDN_WB_BUFF_FLUSH_DURING_HIBERN8 = 0x10,
QUERY_FLAG_IDN_HPB_RESET = 0x11,
QUERY_FLAG_IDN_HPB_EN = 0x12,
};

/* Attribute idn for Query requests */
enum attr_idn {
QUERY_ATTR_IDN_BOOT_LU_EN = 0x00,
QUERY_ATTR_IDN_RESERVED = 0x01,
QUERY_ATTR_IDN_MAX_HPB_SINGLE_CMD = 0x01,
QUERY_ATTR_IDN_POWER_MODE = 0x02,
QUERY_ATTR_IDN_ACTIVE_ICC_LVL = 0x03,
QUERY_ATTR_IDN_OOO_DATA_EN = 0x04,
@@ -2654,7 +2654,12 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)

lrbp->req_abort_skip = false;

ufshpb_prep(hba, lrbp);
err = ufshpb_prep(hba, lrbp);
if (err == -EAGAIN) {
lrbp->cmd = NULL;
ufshcd_release(hba);
goto out;
}

ufshcd_comp_scsi_upiu(hba, lrbp);

@@ -3108,7 +3113,7 @@ int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
*
* Returns 0 for success, non-zero in case of failure
*/
static int ufshcd_query_attr_retry(struct ufs_hba *hba,
int ufshcd_query_attr_retry(struct ufs_hba *hba,
enum query_opcode opcode, enum attr_idn idn, u8 index, u8 selector,
u32 *attr_val)
{
@@ -4863,7 +4868,8 @@ static int ufshcd_change_queue_depth(struct scsi_device *sdev, int depth)
static void ufshcd_hpb_destroy(struct ufs_hba *hba, struct scsi_device *sdev)
{
/* skip well-known LU */
if ((sdev->lun >= UFS_UPIU_MAX_UNIT_NUM_ID) || !ufshpb_is_allowed(hba))
if ((sdev->lun >= UFS_UPIU_MAX_UNIT_NUM_ID) ||
!(hba->dev_info.hpb_enabled) || !ufshpb_is_allowed(hba))
return;

ufshpb_destroy_lu(hba, sdev);
@@ -7464,8 +7470,18 @@ static int ufs_get_device_desc(struct ufs_hba *hba)

if (dev_info->wspecversion >= UFS_DEV_HPB_SUPPORT_VERSION &&
(b_ufs_feature_sup & UFS_DEV_HPB_SUPPORT)) {
dev_info->hpb_enabled = true;
bool hpb_en = false;

ufshpb_get_dev_info(hba, desc_buf);

if (!ufshpb_is_legacy(hba))
err = ufshcd_query_flag_retry(hba,
UPIU_QUERY_OPCODE_READ_FLAG,
QUERY_FLAG_IDN_HPB_EN, 0,
&hpb_en);

if (ufshpb_is_legacy(hba) || (!err && hpb_en))
dev_info->hpb_enabled = true;
}

err = ufshcd_read_string_desc(hba, model_index,
@@ -8040,6 +8056,7 @@ static const struct attribute_group *ufshcd_driver_groups[] = {
&ufs_sysfs_lun_attributes_group,
#ifdef CONFIG_SCSI_UFS_HPB
&ufs_sysfs_hpb_stat_group,
&ufs_sysfs_hpb_param_group,
#endif
NULL,
};
@@ -654,13 +654,17 @@ struct ufs_hba_variant_params {
* @srgn_size: device reported HPB sub-region size
* @slave_conf_cnt: counter to check all lu finished initialization
* @hpb_disabled: flag to check if HPB is disabled
* @max_hpb_single_cmd: maximum size of single HPB command
* @is_legacy: flag to check HPB 1.0
*/
struct ufshpb_dev_info {
int num_lu;
int rgn_size;
int srgn_size;
atomic_t slave_conf_cnt;
bool hpb_disabled;
int max_hpb_single_cmd;
bool is_legacy;
};
#endif

@@ -1096,6 +1100,9 @@ int ufshcd_read_desc_param(struct ufs_hba *hba,
u8 param_offset,
u8 *param_read_buf,
u8 param_size);
int ufshcd_query_attr_retry(struct ufs_hba *hba, enum query_opcode opcode,
enum attr_idn idn, u8 index, u8 selector,
u32 *attr_val);
int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
enum attr_idn idn, u8 index, u8 selector, u32 *attr_val);
int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,

0 comments on commit a13bf62

Please sign in to comment.