diff mbox series

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

Message ID 20221102053058.21021-4-lijiaming3@xiaomi.corp-partner.google.com
State New
Headers show
Series Implement File-Based optimization functionality | expand

Commit Message

Jiaming Li Nov. 2, 2022, 5:30 a.m. UTC
From: lijiaming3 <lijiaming3@xiaomi.com>

add fbo module, determine whether the device supports
the FBO function and initialize FBO related info

Signed-off-by: lijiaming3 <lijiaming3@xiaomi.com>
---
 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

Comments

Avri Altman Nov. 2, 2022, 8:11 a.m. UTC | #1
> From: lijiaming3 <lijiaming3@xiaomi.com>
> 
> add fbo module, determine whether the device supports the FBO function
> and initialize FBO related info
> 
> Signed-off-by: lijiaming3 <lijiaming3@xiaomi.com>
Here also spaces missing in the header + minor nit below. 
Other than that:
Reviewed-by: Avri Altman <avri.altman@wdc.com>

> ---
>  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@xiaomi.com>
> + */
> +
> +#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@xiaomi.com>
> + */
> +
> +#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
kernel test robot Nov. 14, 2022, 9:21 p.m. UTC | #2
Hi Jiaming,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on mkp-scsi/for-next]
[also build test ERROR on jejb-scsi/for-next linus/master v6.1-rc5 next-20221114]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Jiaming-Li/Implement-File-Based-optimization-functionality/20221102-133247
base:   https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git for-next
patch link:    https://lore.kernel.org/r/20221102053058.21021-4-lijiaming3%40xiaomi.corp-partner.google.com
patch subject: [RESEND PATCH 3/4] scsi:ufs:add FBO module
config: arm64-randconfig-r013-20221114
compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 463da45892e2d2a262277b91b96f5f8c05dc25d0)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm64 cross compiling tool for clang build
        # apt-get install binutils-aarch64-linux-gnu
        # https://github.com/intel-lab-lkp/linux/commit/2f8ba92950b39a1758002a9461f4066b49b712fc
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Jiaming-Li/Implement-File-Based-optimization-functionality/20221102-133247
        git checkout 2f8ba92950b39a1758002a9461f4066b49b712fc
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm64 SHELL=/bin/bash drivers/ufs/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from drivers/ufs/core/ufshcd.c:38:
>> drivers/ufs/core/ufsfbo.h:19:74: error: non-void function does not return a value [-Werror,-Wreturn-type]
   static inline int ufsfbo_probe(struct ufs_hba *hba, const u8 *desc_buf) {}
                                                                            ^
   1 error generated.


vim +19 drivers/ufs/core/ufsfbo.h

    13	
    14	#ifdef CONFIG_SCSI_UFS_FBO
    15	int ufsfbo_probe(struct ufs_hba *hba, const u8 *desc_buf);
    16	void ufsfbo_remove(struct ufs_hba *hba);
    17	extern const struct attribute_group ufs_sysfs_fbo_param_group;
    18	#else
  > 19	static inline int ufsfbo_probe(struct ufs_hba *hba, const u8 *desc_buf) {}
    20	static inline void ufsfbo_remove(struct ufs_hba *hba) {}
    21	#endif
    22
diff mbox series

Patch

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
+	  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@xiaomi.com>
+ */
+
+#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@xiaomi.com>
+ */
+
+#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;
 };