RE: [RESEND PATCH 3/4] scsi:ufs:add FBO module

From: Avri Altman
Date: Wed Nov 02 2022 - 04:12:04 EST


> From: lijiaming3 <lijiaming3@xxxxxxxxxx>
>
> add fbo module, determine whether the device supports the FBO function
> and initialize FBO related info
>
> Signed-off-by: lijiaming3 <lijiaming3@xxxxxxxxxx>
Here also spaces missing in the header + minor nit below.
Other than that:
Reviewed-by: Avri Altman <avri.altman@xxxxxxx>

> ---
> drivers/ufs/core/Kconfig | 12 ++++
> drivers/ufs/core/Makefile | 1 +
> drivers/ufs/core/ufsfbo.c | 120
> ++++++++++++++++++++++++++++++++++++++
> drivers/ufs/core/ufsfbo.h | 23 ++++++++
> drivers/ufs/core/ufshcd.c | 4 ++
> include/ufs/ufs.h | 3 +
> include/ufs/ufshcd.h | 1 +
> 7 files changed, 164 insertions(+)
> create mode 100644 drivers/ufs/core/ufsfbo.c create mode 100644
> drivers/ufs/core/ufsfbo.h
>
> diff --git a/drivers/ufs/core/Kconfig b/drivers/ufs/core/Kconfig index
> e11978171403..30d3b6f07f5b 100644
> --- a/drivers/ufs/core/Kconfig
> +++ b/drivers/ufs/core/Kconfig
> @@ -58,3 +58,15 @@ config SCSI_UFS_HWMON
> a hardware monitoring device will be created for the UFS device.
>
> If unsure, say N.
> +
> +config SCSI_UFS_FBO
> + bool "Support UFS File-based Optimization"
> + depends on SCSI_UFSHCD
> + help
> + The UFS FBO feature improves sequential read performance. The host
> send
> + the LBA info to device first. And then instrut the device to analyse the
Instrut -> instruct, analyse -> analyze

> + LBA fragment info. After the analysis, the host can instruct the device
> to
> + return the LBA's fragmented state. Then the host can decide whether
> to
> + optimize based on the fragmentation status. After the
> defragmentation is
> + concluded, it is expected that the sequential read performance will be
> + improved.
> diff --git a/drivers/ufs/core/Makefile b/drivers/ufs/core/Makefile index
> 62f38c5bf857..af7870126815 100644
> --- a/drivers/ufs/core/Makefile
> +++ b/drivers/ufs/core/Makefile
> @@ -8,3 +8,4 @@ ufshcd-core-$(CONFIG_SCSI_UFS_CRYPTO) += ufshcd-
> crypto.o
> ufshcd-core-$(CONFIG_SCSI_UFS_HPB) += ufshpb.o
> ufshcd-core-$(CONFIG_SCSI_UFS_FAULT_INJECTION) += ufs-fault-injection.o
> ufshcd-core-$(CONFIG_SCSI_UFS_HWMON) += ufs-hwmon.o
> +ufshcd-core-$(CONFIG_SCSI_UFS_FBO) += ufsfbo.o
> \ No newline at end of file
> diff --git a/drivers/ufs/core/ufsfbo.c b/drivers/ufs/core/ufsfbo.c new file
> mode 100644 index 000000000000..81326fd2fb3d
> --- /dev/null
> +++ b/drivers/ufs/core/ufsfbo.c
> @@ -0,0 +1,120 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Universal Flash Storage File-based Optimization
> + *
> + * Copyright (C) 2022 Xiaomi Mobile Software Co., Ltd
> + *
> + * Authors:
> + * lijiaming <lijiaming3@xxxxxxxxxx>
> + */
> +
> +#include "ufshcd-priv.h"
> +#include "ufsfbo.h"
> +#include <scsi/scsi_cmnd.h>
> +#include <scsi/scsi_device.h>
> +#include <asm/unaligned.h>
> +
> +/**
> + * struct ufsfbo_dev_info - FBO device related info
> + * @fbo_version: UFS file-based optimization Version
> + * @fbo_rec_lrs: Recommended LBA Range Size In Bytes
> + * @fbo_max_lrs: The Max LBA Range Size To Be Used By The Host
> + * @fbo_min_lrs: The Min LBA Range Size To Be Used By The Host
> + * @fbo_max_lrc: The Max Number Of LBA Ranges Supported By
> Read/Write
> +Buffer Cmd
> + * @fbo_lra: Alignment Requirement. 0 Means No Align Requirement
> + * @fbo_exec_threshold: the execute level of UFS file-based
> +optimization */ struct ufsfbo_dev_info {
> + u16 fbo_version;
> + u32 fbo_rec_lrs;
> + u32 fbo_max_lrs;
> + u32 fbo_min_lrs;
> + int fbo_max_lrc;
> + int fbo_lra;
> + u8 fbo_exec_threshold;
> +};
> +/**
> + * struct ufsfbo_ctrl - FBO ctrl structure
> + * @hba: Per adapter private structure
> + * @fbo_dev_info: FBO device related info
> + * @fbo_lba_cnt: Number of LBA required to do FBO */ struct
> +ufsfbo_ctrl {
> + struct ufs_hba *hba;
> + struct ufsfbo_dev_info fbo_dev_info;
> + int fbo_lba_cnt;
> +};
> +
> +static int ufsfbo_get_dev_info(struct ufs_hba *hba, struct ufsfbo_ctrl
> +*fbo_ctrl) {
> + int ret;
> + u32 val;
> + u8 *desc_buf;
> + int buf_len;
> + struct ufsfbo_dev_info *fbo_info = &fbo_ctrl->fbo_dev_info;
> +
> + buf_len = hba->desc_size[QUERY_DESC_IDN_FBO];
> + desc_buf = kmalloc(buf_len, GFP_KERNEL);
> + if (!desc_buf)
> + return -ENOMEM;
> +
> + ret = ufshcd_query_descriptor_retry(hba,
> UPIU_QUERY_OPCODE_READ_DESC,
> + QUERY_DESC_IDN_FBO, 0, 0, desc_buf, &buf_len);
> + if (ret) {
> + dev_err(hba->dev, "%s: Failed reading FBO Desc. ret = %d\n",
> + __func__, ret);
> + goto out;
> + }
> +
> + fbo_info->fbo_version = get_unaligned_be16(desc_buf +
> FBO_DESC_PARAM_VERSION);
> + fbo_info->fbo_rec_lrs = get_unaligned_be32(desc_buf +
> FBO_DESC_PARAM_REC_LBA_RANGE_SIZE);
> + fbo_info->fbo_max_lrs = get_unaligned_be32(desc_buf +
> FBO_DESC_PARAM_MAX_LBA_RANGE_SIZE);
> + fbo_info->fbo_min_lrs = get_unaligned_be32(desc_buf +
> FBO_DESC_PARAM_MIN_LBA_RANGE_SIZE);
> + fbo_info->fbo_max_lrc =
> desc_buf[FBO_DESC_PARAM_MAX_LBA_RANGE_CONUT];
> + fbo_info->fbo_lra = get_unaligned_be16(desc_buf +
> + FBO_DESC_PARAM_MAX_LBA_RANGE_ALIGNMENT);
> +
> + ret = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR,
> + QUERY_ATTR_IDN_FBO_LEVEL_EXE, 0, 0, &val);
> + if (ret) {
> + dev_err(hba->dev, "%s: Failed reading FBO Attr. ret = %d\n",
> + __func__, ret);
> + goto out;
> + }
> +
> + fbo_info->fbo_exec_threshold = val;
> +
> +out:
> + kfree(desc_buf);
> + return ret;
> +}
> +
> +int ufsfbo_probe(struct ufs_hba *hba, const u8 *desc_buf) {
> + struct ufsfbo_ctrl *fbo_ctrl;
> + u32 ext_ufs_feature;
> +
> + ext_ufs_feature = get_unaligned_be32(desc_buf +
> + DEVICE_DESC_PARAM_EXT_UFS_FEATURE_SUP);
> +
> + if (!(ext_ufs_feature & UFS_DEV_FBO_SUP))
> + return -EOPNOTSUPP;
> +
> + fbo_ctrl = kzalloc(sizeof(struct ufsfbo_ctrl), GFP_KERNEL);
> + if (!fbo_ctrl)
> + return -ENOMEM;
> +
> + if (ufsfbo_get_dev_info(hba, fbo_ctrl))
> + return -EOPNOTSUPP;
> +
> + hba->fbo_ctrl = fbo_ctrl;
> + fbo_ctrl->hba = hba;
> +
> + return 0;
> +}
> +
> +void ufsfbo_remove(struct ufs_hba *hba) {
> + if (!hba->fbo_ctrl)
> + return;
> +
> + kfree(hba->fbo_ctrl);
> +}
> diff --git a/drivers/ufs/core/ufsfbo.h b/drivers/ufs/core/ufsfbo.h new file
> mode 100644 index 000000000000..843fa8a75c2c
> --- /dev/null
> +++ b/drivers/ufs/core/ufsfbo.h
> @@ -0,0 +1,23 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Universal Flash Storage File-based Optimization
> + *
> + * Copyright (C) 2022 Xiaomi Mobile Software Co., Ltd
> + *
> + * Authors:
> + * lijiaming <lijiaming3@xxxxxxxxxx>
> + */
> +
> +#ifndef _UFSFBO_H_
> +#define _UFSFBO_H_
> +
> +#ifdef CONFIG_SCSI_UFS_FBO
> +int ufsfbo_probe(struct ufs_hba *hba, const u8 *desc_buf); void
> +ufsfbo_remove(struct ufs_hba *hba); extern const struct attribute_group
> +ufs_sysfs_fbo_param_group; #else static inline int ufsfbo_probe(struct
> +ufs_hba *hba, const u8 *desc_buf) {} static inline void
> +ufsfbo_remove(struct ufs_hba *hba) {} #endif
> +
> +#endif /* _UFSFBO_H_ */
> diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index
> 4bc5b8563a62..f769fcb72392 100644
> --- a/drivers/ufs/core/ufshcd.c
> +++ b/drivers/ufs/core/ufshcd.c
> @@ -35,6 +35,7 @@
> #include "ufs_bsg.h"
> #include "ufshcd-crypto.h"
> #include "ufshpb.h"
> +#include "ufsfbo.h"
> #include <asm/unaligned.h>
>
> #define CREATE_TRACE_POINTS
> @@ -7778,6 +7779,8 @@ static int ufs_get_device_desc(struct ufs_hba
> *hba)
>
> ufshcd_wb_probe(hba, desc_buf);
>
> + ufsfbo_probe(hba, desc_buf);
> +
> ufshcd_temp_notif_probe(hba, desc_buf);
>
> /*
> @@ -9534,6 +9537,7 @@ void ufshcd_remove(struct ufs_hba *hba)
> ufs_hwmon_remove(hba);
> ufs_bsg_remove(hba);
> ufshpb_remove(hba);
> + ufsfbo_remove(hba);
> ufs_sysfs_remove_nodes(hba->dev);
> blk_mq_destroy_queue(hba->tmf_queue);
> blk_mq_free_tag_set(&hba->tmf_tag_set);
> diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h index
> c3fd954ce005..2ab79760dafe 100644
> --- a/include/ufs/ufs.h
> +++ b/include/ufs/ufs.h
> @@ -165,6 +165,9 @@ enum attr_idn {
> QUERY_ATTR_IDN_AVAIL_WB_BUFF_SIZE = 0x1D,
> QUERY_ATTR_IDN_WB_BUFF_LIFE_TIME_EST = 0x1E,
> QUERY_ATTR_IDN_CURR_WB_BUFF_SIZE = 0x1F,
> + QUERY_ATTR_IDN_FBO_CONTROL = 0x31,
> + QUERY_ATTR_IDN_FBO_LEVEL_EXE = 0X32,
> + QUERY_ATTR_IDN_FBO_PROG_STATE = 0x33,
> };
>
> /* Descriptor idn for Query requests */ diff --git a/include/ufs/ufshcd.h
> b/include/ufs/ufshcd.h index 9f28349ebcff..5c7367a54bbb 100644
> --- a/include/ufs/ufshcd.h
> +++ b/include/ufs/ufshcd.h
> @@ -973,6 +973,7 @@ struct ufs_hba {
> struct delayed_work debugfs_ee_work;
> u32 debugfs_ee_rate_limit_ms;
> #endif
> + struct ufsfbo_ctrl *fbo_ctrl;
> u32 luns_avail;
> bool complete_put;
> };
> --
> 2.38.1