* [PATCH] scsi: ufs: Add batched WB buffer flush
[not found] <CGME20210420025012epcms2p4a850fa0017e7a152ec5e5f89350d66b9@epcms2p4>
@ 2021-04-20 2:50 ` Daejun Park
2021-04-20 6:23 ` kernel test robot
0 siblings, 1 reply; 2+ messages in thread
From: Daejun Park @ 2021-04-20 2:50 UTC (permalink / raw)
To: ALIM AKHTAR, avri.altman, jejb, martin.petersen, adrian.hunter,
asutoshd, mchehab+huawei, Keoseong Park, lukas.bulwahn, beanhuo,
stanley.chu, cang, nguyenb, jaegeuk, Daejun Park, Kiwoong Kim,
satyat
Cc: linux-kernel, linux-scsi, Sung-Jun Park, Jinyoung CHOI,
Jieon Seol, Jaemyung Lee, Dukhyun Kwon, JinHwan Park
Currently, WriteBooster (WB) buffer is always flushed during hibern8. However,
this is inefficient because data in the WB buffer can be invalid due to
spatial locality of IO workload.
If the WB buffer flush is flushed in a batched manner, the amount of data
migration and power consumption can be reduced because the overwritten data
of the WB buffer may be invalid due to spatial locality.
This patch supports batched flush of WB buffer. When batched flush is enabled,
fWriteBoosterBufferFlushDuringHibernate is set only when
b_rpm_dev_flush_capable is true during runtime suspend. When the device is
resumed, fWriteBoosterBufferFlushDuringHibernate is cleared to stop flush
during hibern8.
Co-developed-by: Keoseong Park <keosung.park@samsung.com>
Signed-off-by: Keoseong Park <keosung.park@samsung.com>
Signed-off-by: Daejun Park <daejun7.park@samsung.com>
---
Documentation/ABI/testing/sysfs-driver-ufs | 9 ++++
drivers/scsi/ufs/ufs-sysfs.c | 50 ++++++++++++++++++++++
drivers/scsi/ufs/ufshcd.c | 14 ++++--
drivers/scsi/ufs/ufshcd.h | 2 +
4 files changed, 71 insertions(+), 4 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs
index d1bc23cb6a9d..b67b8449e840 100644
--- a/Documentation/ABI/testing/sysfs-driver-ufs
+++ b/Documentation/ABI/testing/sysfs-driver-ufs
@@ -1172,3 +1172,12 @@ Description: This node is used to set or display whether UFS WriteBooster is
(if the platform supports UFSHCD_CAP_CLK_SCALING). For a
platform that doesn't support UFSHCD_CAP_CLK_SCALING, we can
disable/enable WriteBooster through this sysfs node.
+
+What: /sys/bus/platform/drivers/ufshcd/*/wb_batched_flush
+Date: April 2021
+Contact: Daejun Park <daejun7.park@samsung.com>
+Description: This entry shows whether batch flushing of UFS WriteBooster
+ buffers is enabled. Writing 1 to this entry allows the device to flush
+ the WriteBooster buffer only when it needs to perform a buffer flush
+ during runtime suspend. Writing 0 to this entry allows the device to
+ flush the WriteBooster buffer during link hibernation.
diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c
index d7c3cff9662f..943ac12e59c6 100644
--- a/drivers/scsi/ufs/ufs-sysfs.c
+++ b/drivers/scsi/ufs/ufs-sysfs.c
@@ -253,6 +253,54 @@ static ssize_t wb_on_store(struct device *dev, struct device_attribute *attr,
return res < 0 ? res : count;
}
+
+static ssize_t wb_batched_flush_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ufs_hba *hba = dev_get_drvdata(dev);
+
+ return sysfs_emit(buf, "%d\n", hba->vps->wb_batched_flush);
+}
+
+static ssize_t wb_batched_flush_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ufs_hba *hba = dev_get_drvdata(dev);
+ unsigned int wb_batched_flush;
+ ssize_t res;
+
+ if (!ufshcd_is_wb_allowed(hba)) {
+ dev_warn(dev, "To control WB through wb_batched_flush is not allowed!\n");
+ return -EOPNOTSUPP;
+ }
+
+ if (kstrtouint(buf, 0, &wb_batched_flush))
+ return -EINVAL;
+
+ if (wb_batched_flush != 0 && wb_batched_flush != 1)
+ return -EINVAL;
+
+ down(&hba->host_sem);
+ if (!ufshcd_is_user_access_allowed(hba)) {
+ res = -EBUSY;
+ goto out;
+ }
+
+ if (wb_batched_flush == hba->vps->wb_batched_flush)
+ goto out;
+
+ pm_runtime_get_sync(hba->dev);
+ res = ufshcd_wb_toggle_flush_during_h8(hba, !wb_batched_flush);
+ pm_runtime_put_sync(hba->dev);
+ if (!res)
+ hba->vps->wb_batched_flush = wb_batched_flush;
+
+out:
+ up(&hba->host_sem);
+ return res < 0 ? res : count;
+}
+
static DEVICE_ATTR_RW(rpm_lvl);
static DEVICE_ATTR_RO(rpm_target_dev_state);
static DEVICE_ATTR_RO(rpm_target_link_state);
@@ -261,6 +309,7 @@ static DEVICE_ATTR_RO(spm_target_dev_state);
static DEVICE_ATTR_RO(spm_target_link_state);
static DEVICE_ATTR_RW(auto_hibern8);
static DEVICE_ATTR_RW(wb_on);
+static DEVICE_ATTR_RW(wb_batched_flush);
static struct attribute *ufs_sysfs_ufshcd_attrs[] = {
&dev_attr_rpm_lvl.attr,
@@ -271,6 +320,7 @@ static struct attribute *ufs_sysfs_ufshcd_attrs[] = {
&dev_attr_spm_target_link_state.attr,
&dev_attr_auto_hibern8.attr,
&dev_attr_wb_on.attr,
+ &dev_attr_wb_batched_flush.attr,
NULL
};
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 0625da7a42ee..e11dc578a17c 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -244,7 +244,6 @@ static int ufshcd_setup_vreg(struct ufs_hba *hba, bool on);
static inline int ufshcd_config_vreg_hpm(struct ufs_hba *hba,
struct ufs_vreg *vreg);
static int ufshcd_try_to_abort_task(struct ufs_hba *hba, int tag);
-static void ufshcd_wb_toggle_flush_during_h8(struct ufs_hba *hba, bool set);
static inline void ufshcd_wb_toggle_flush(struct ufs_hba *hba, bool enable);
static void ufshcd_hba_vreg_set_lpm(struct ufs_hba *hba);
static void ufshcd_hba_vreg_set_hpm(struct ufs_hba *hba);
@@ -277,7 +276,8 @@ static inline void ufshcd_wb_config(struct ufs_hba *hba)
ufshcd_wb_toggle(hba, true);
- ufshcd_wb_toggle_flush_during_h8(hba, true);
+ ufshcd_wb_toggle_flush_during_h8(hba, !hba->vps->wb_batched_flush);
+
if (!(hba->quirks & UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL))
ufshcd_wb_toggle_flush(hba, true);
}
@@ -5472,7 +5472,7 @@ int ufshcd_wb_toggle(struct ufs_hba *hba, bool enable)
return ret;
}
-static void ufshcd_wb_toggle_flush_during_h8(struct ufs_hba *hba, bool set)
+int ufshcd_wb_toggle_flush_during_h8(struct ufs_hba *hba, bool set)
{
int ret;
@@ -5481,10 +5481,12 @@ static void ufshcd_wb_toggle_flush_during_h8(struct ufs_hba *hba, bool set)
if (ret) {
dev_err(hba->dev, "%s: WB-Buf Flush during H8 %s failed: %d\n",
__func__, set ? "enable" : "disable", ret);
- return;
+ return ret;
}
dev_dbg(hba->dev, "%s WB-Buf Flush during H8 %s\n",
__func__, set ? "enabled" : "disabled");
+
+ return ret;
}
static inline void ufshcd_wb_toggle_flush(struct ufs_hba *hba, bool enable)
@@ -8745,6 +8747,8 @@ static int ufshcd_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
ret = ufshcd_set_dev_pwr_mode(hba, req_dev_pwr_mode);
if (ret)
goto enable_gating;
+ } else if (hba->vps->wb_batched_flush) {
+ ufshcd_wb_toggle_flush_during_h8(hba, true);
}
}
@@ -8925,6 +8929,8 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
ufshcd_auto_hibern8_enable(hba);
if (hba->dev_info.b_rpm_dev_flush_capable) {
+ if (hba->vps->wb_batched_flush)
+ ufshcd_wb_toggle_flush_during_h8(hba, false);
hba->dev_info.b_rpm_dev_flush_capable = false;
cancel_delayed_work(&hba->rpm_dev_flush_recheck_work);
}
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 5eb66a8debc7..049f3f08506c 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -643,6 +643,7 @@ struct ufs_hba_variant_params {
struct devfreq_simple_ondemand_data ondemand_data;
u16 hba_enable_delay_us;
u32 wb_flush_threshold;
+ bool wb_batched_flush;
};
/**
@@ -1105,6 +1106,7 @@ int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba,
enum query_opcode desc_op);
int ufshcd_wb_toggle(struct ufs_hba *hba, bool enable);
+int ufshcd_wb_toggle_flush_during_h8(struct ufs_hba *hba, bool set);
/* Wrapper functions for safely calling variant operations */
static inline const char *ufshcd_get_var_name(struct ufs_hba *hba)
--
2.25.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] scsi: ufs: Add batched WB buffer flush
2021-04-20 2:50 ` [PATCH] scsi: ufs: Add batched WB buffer flush Daejun Park
@ 2021-04-20 6:23 ` kernel test robot
0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2021-04-20 6:23 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 3951 bytes --]
Hi Daejun,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on mkp-scsi/for-next]
[also build test WARNING on scsi/for-next next-20210419]
[cannot apply to linus/master v5.12-rc8]
[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]
url: https://github.com/0day-ci/linux/commits/Daejun-Park/scsi-ufs-Add-batched-WB-buffer-flush/20210420-105527
base: https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git for-next
config: x86_64-randconfig-a012-20210419 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project ca8eef7e3da8f750d7c7aa004fe426d1d34787ea)
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 x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# https://github.com/0day-ci/linux/commit/9f59814819c3a0ab46c3f1faf61332a03a158de2
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Daejun-Park/scsi-ufs-Add-batched-WB-buffer-flush/20210420-105527
git checkout 9f59814819c3a0ab46c3f1faf61332a03a158de2
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
>> drivers/scsi/ufs/ufs-sysfs.c:290:6: warning: variable 'res' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
if (wb_batched_flush == hba->vps->wb_batched_flush)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/scsi/ufs/ufs-sysfs.c:301:9: note: uninitialized use occurs here
return res < 0 ? res : count;
^~~
drivers/scsi/ufs/ufs-sysfs.c:290:2: note: remove the 'if' if its condition is always false
if (wb_batched_flush == hba->vps->wb_batched_flush)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/scsi/ufs/ufs-sysfs.c:271:13: note: initialize the variable 'res' to silence this warning
ssize_t res;
^
= 0
1 warning generated.
vim +290 drivers/scsi/ufs/ufs-sysfs.c
264
265 static ssize_t wb_batched_flush_store(struct device *dev,
266 struct device_attribute *attr,
267 const char *buf, size_t count)
268 {
269 struct ufs_hba *hba = dev_get_drvdata(dev);
270 unsigned int wb_batched_flush;
271 ssize_t res;
272
273 if (!ufshcd_is_wb_allowed(hba)) {
274 dev_warn(dev, "To control WB through wb_batched_flush is not allowed!\n");
275 return -EOPNOTSUPP;
276 }
277
278 if (kstrtouint(buf, 0, &wb_batched_flush))
279 return -EINVAL;
280
281 if (wb_batched_flush != 0 && wb_batched_flush != 1)
282 return -EINVAL;
283
284 down(&hba->host_sem);
285 if (!ufshcd_is_user_access_allowed(hba)) {
286 res = -EBUSY;
287 goto out;
288 }
289
> 290 if (wb_batched_flush == hba->vps->wb_batched_flush)
291 goto out;
292
293 pm_runtime_get_sync(hba->dev);
294 res = ufshcd_wb_toggle_flush_during_h8(hba, !wb_batched_flush);
295 pm_runtime_put_sync(hba->dev);
296 if (!res)
297 hba->vps->wb_batched_flush = wb_batched_flush;
298
299 out:
300 up(&hba->host_sem);
301 return res < 0 ? res : count;
302 }
303
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 37697 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2021-04-20 6:23 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <CGME20210420025012epcms2p4a850fa0017e7a152ec5e5f89350d66b9@epcms2p4>
2021-04-20 2:50 ` [PATCH] scsi: ufs: Add batched WB buffer flush Daejun Park
2021-04-20 6:23 ` kernel test robot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.