From: Daejun Park <daejun7.park@samsung.com>
To: Bart Van Assche <bvanassche@acm.org>,
Daejun Park <daejun7.park@samsung.com>,
"avri.altman@wdc.com" <avri.altman@wdc.com>,
"jejb@linux.ibm.com" <jejb@linux.ibm.com>,
"martin.petersen@oracle.com" <martin.petersen@oracle.com>,
"asutoshd@codeaurora.org" <asutoshd@codeaurora.org>,
"beanhuo@micron.com" <beanhuo@micron.com>,
"stanley.chu@mediatek.com" <stanley.chu@mediatek.com>,
"cang@codeaurora.org" <cang@codeaurora.org>,
"tomas.winkler@intel.com" <tomas.winkler@intel.com>,
ALIM AKHTAR <alim.akhtar@samsung.com>
Cc: "linux-scsi@vger.kernel.org" <linux-scsi@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
Sang-yoon Oh <sangyoon.oh@samsung.com>,
Sung-Jun Park <sungjun07.park@samsung.com>,
yongmyung lee <ymhungry.lee@samsung.com>,
Jinyoung CHOI <j-young.choi@samsung.com>,
Adel Choi <adel.choi@samsung.com>,
BoRam Shin <boram.shin@samsung.com>
Subject: Re: [PATCH v8 2/4] scsi: ufs: Introduce HPB feature
Date: Thu, 13 Aug 2020 12:00:31 +0900 [thread overview]
Message-ID: <231786897.01597287781957.JavaMail.epsvc@epcpadp2> (raw)
In-Reply-To: <2154d9c6-4b29-7d24-0261-26d2aa05caef@acm.org>
Hi Bart,
On 2020-08-06 02:11, Daejun Park wrote:
> > This is a patch for the HPB feature.
> > This patch adds HPB function calls to UFS core driver.
> >
> > The mininum size of the memory pool used in the HPB is implemented as a
> ^^^^^^^
> minimum?
I will fix it.
> > Kconfig parameter (SCSI_UFS_HPB_HOST_MEM), so that it can be configurable.
>
> > +config SCSI_UFS_HPB
> > + bool "Support UFS Host Performance Booster"
> > + depends on SCSI_UFSHCD
> > + help
> > + A UFS HPB Feature improves random read performance. It caches
> ^ ^^^^^^^
> The? feature?
I will fix it.
> > + L2P map of UFS to host DRAM. The driver uses HPB read command
> > + by piggybacking physical page number for bypassing FTL's L2P address
> > + translation.
>
> Please explain what L2P and FTL mean. Not everyone is familiar with SSD
> internals.
I added full name of the abbreviation.
L2P (logical to physical) map of UFS to host DRAM. The driver uses HPB read command
^^^^^^^^^^^^^^^^^^^
by piggybacking physical page number for bypassing FTL (flash translation layer)
^^^^^^^^^^^^^^^^^^^^^^^^
> > +config SCSI_UFS_HPB_HOST_MEM
> > + int "Host-side cached memory size (KB) for HPB support"
> > + default 32
> > + depends on SCSI_UFS_HPB
> > + help
> > + The mininum size of the memory pool used in the HPB module. It can
> > + be configurable by the user. If this value is larger than required
> > + memory size, kernel resizes cached memory size.
> ^^^^^^^ ^^^^^^^^^^^^^^^^^^
> reduces? cache size?
>
> Please make this a kernel module parameter instead of a compile-time constant.
OK, I will change it.
> > +#ifndef CONFIG_SCSI_UFS_HPB
> > +static void ufshpb_resume(struct ufs_hba *hba) {}
> > +static void ufshpb_suspend(struct ufs_hba *hba) {}
> > +static void ufshpb_reset(struct ufs_hba *hba) {}
> > +static void ufshpb_reset_host(struct ufs_hba *hba) {}
> > +static void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) {}
> > +static void ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) {}
> > +static void ufshpb_remove(struct ufs_hba *hba) {}
> > +static void ufshpb_scan_feature(struct ufs_hba *hba) {}
> > +#endif
>
> Please move these definitions into ufshpb.h since that is the
> recommended Linux kernel coding style.
OK, I will move them.
> > diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
> > index b2ef18f1b746..904c19796e09 100644
> > --- a/drivers/scsi/ufs/ufshcd.h
> > +++ b/drivers/scsi/ufs/ufshcd.h
> > @@ -47,6 +47,9 @@
> > #include "ufs.h"
> > #include "ufs_quirks.h"
> > #include "ufshci.h"
> > +#ifdef CONFIG_SCSI_UFS_HPB
> > +#include "ufshpb.h"
> > +#endif
>
> Please move #ifdef CONFIG_SCSI_UFS_HPB / #endif into ufshpb.h. From
> Documentation/process/4.Coding.rst: "As a general rule, #ifdef use
> should be confined to header files whenever possible."
OK, I will fix it.
> > +struct ufsf_feature_info {
> > + atomic_t slave_conf_cnt;
> > + wait_queue_head_t sdev_wait;
> > +};
>
> Please add a comment above this data structure that explains the role
> of this data structure and also what "ufsf" stands for.
"ufsf" is stands for ufs feature. I wiil add comments for the data structure.
> > +static int ufshpb_create_sysfs(struct ufs_hba *hba, struct ufshpb_lu *hpb);
>
> I don't think that this forward declaration is necessary so please leave it
> out.
OK, I will remove it.
> > +static inline int ufshpb_is_valid_srgn(struct ufshpb_region *rgn,
> > + struct ufshpb_subregion *srgn)
> > +{
> > + return rgn->rgn_state != HPB_RGN_INACTIVE &&
> > + srgn->srgn_state == HPB_SRGN_VALID;
> > +}
>
> Please do not declare functions inside .c files inline but instead let
> the compiler decide which functions to inline. Modern compilers are really
> good at this.
I didn't know about it. Thanks.
> > +static struct kobj_type ufshpb_ktype = {
> > + .sysfs_ops = &ufshpb_sysfs_ops,
> > + .release = NULL,
> > +};
>
> If the release method of a kobj_type is NULL that is a strong sign that
> there is something wrong ...
>
> > +static int ufshpb_create_sysfs(struct ufs_hba *hba, struct ufshpb_lu *hpb)
> > +{
> > + int ret;
> > +
> > + ufshpb_stat_init(hpb);
> > +
> > + kobject_init(&hpb->kobj, &ufshpb_ktype);
> > + mutex_init(&hpb->sysfs_lock);
> > +
> > + ret = kobject_add(&hpb->kobj, kobject_get(&hba->dev->kobj),
> > + "ufshpb_lu%d", hpb->lun);
> > +
> > + if (ret)
> > + return ret;
> > +
> > + ret = sysfs_create_group(&hpb->kobj, &ufshpb_sysfs_group);
> > +
> > + if (ret) {
> > + dev_err(hba->dev, "ufshpb_lu%d create file error\n", hpb->lun);
> > + return ret;
> > + }
> > +
> > + dev_info(hba->dev, "ufshpb_lu%d sysfs adds uevent", hpb->lun);
> > + kobject_uevent(&hpb->kobj, KOBJ_ADD);
> > +
> > + return 0;
> > +}
>
> Please attach these sysfs attributes to /sys/class/scsi_device/*/device
> instead of creating a new kobject. Consider using the following
> scsi_host_template member to define LUN sysfs attributes:
I am not rejecting your comment. But I added kobject for distinguishing
between other attributes and attributes related to HPB feature.
If you think it's pointless, I'll fix it.
> /*
> * Pointer to the SCSI device attribute groups for this host,
> * NULL terminated.
> */
> const struct attribute_group **sdev_groups;
>
> > +static void ufshpb_scan_hpb_lu(struct ufs_hba *hba,
> > + struct ufshpb_dev_info *hpb_dev_info,
> > + u8 *desc_buf)
> > +{
> > + struct scsi_device *sdev;
> > + struct ufshpb_lu *hpb;
> > + int find_hpb_lu = 0;
> > + int ret;
> > +
> > + shost_for_each_device(sdev, hba->host) {
> > + struct ufshpb_lu_info hpb_lu_info = { 0 };
> > + int lun = sdev->lun;
> > +
> > + if (lun >= hba->dev_info.max_lu_supported)
> > + continue;
> > +
> > + ret = ufshpb_get_lu_info(hba, lun, &hpb_lu_info, desc_buf);
> > + if (ret)
> > + continue;
> > +
> > + hpb = ufshpb_alloc_hpb_lu(hba, lun, hpb_dev_info,
> > + &hpb_lu_info);
> > + if (!hpb)
> > + continue;
> > +
> > + hpb->sdev_ufs_lu = sdev;
> > + sdev->hostdata = hpb;
> > +
> > + list_add_tail(&hpb->list_hpb_lu, &lh_hpb_lu);
> > + find_hpb_lu++;
> > + }
> > +
> > + if (!find_hpb_lu)
> > + return;
> > +
> > + ufshpb_check_hpb_reset_query(hba);
> > +
> > + list_for_each_entry(hpb, &lh_hpb_lu, list_hpb_lu) {
> > + dev_info(hba->dev, "set state to present\n");
> > + ufshpb_set_state(hpb, HPB_PRESENT);
> > + }
> > +}
>
> Please remove the loop from the above function, make this function accept a
> SCSI device pointer as argument and call this function from
> ufshcd_slave_configure() or ufshcd_hpb_configure().
I will move the loop to ufshcd_hpb_configure().
>
> > +static void ufshpb_init(void *data, async_cookie_t cookie)
> > +{
> > + struct ufsf_feature_info *ufsf = (struct ufsf_feature_info *)data;
> > + struct ufs_hba *hba;
> > + struct ufshpb_dev_info hpb_dev_info = { 0 };
> > + char *desc_buf;
> > + int ret;
> > +
> > + hba = container_of(ufsf, struct ufs_hba, ufsf);
> > +
> > + desc_buf = kzalloc(QUERY_DESC_MAX_SIZE, GFP_KERNEL);
> > + if (!desc_buf)
> > + goto release_desc_buf;
> > +
> > + ret = ufshpb_get_dev_info(hba, &hpb_dev_info, desc_buf);
> > + if (ret)
> > + goto release_desc_buf;
> > +
> > + /*
> > + * Because HPB driver uses scsi_device data structure,
> > + * we should wait at this point until finishing initialization of all
> > + * scsi devices. Even if timeout occurs, HPB driver will search
> > + * the scsi_device list on struct scsi_host (shost->__host list_head)
> > + * and can find out HPB logical units in all scsi_devices
> > + */
> > + wait_event_timeout(hba->ufsf.sdev_wait,
> > + (atomic_read(&hba->ufsf.slave_conf_cnt)
> > + == hpb_dev_info.num_lu),
> > + SDEV_WAIT_TIMEOUT);
> > +
> > + ufshpb_issue_hpb_reset_query(hba);
> > +
> > + dev_dbg(hba->dev, "ufshpb: slave count %d, lu count %d\n",
> > + atomic_read(&hba->ufsf.slave_conf_cnt), hpb_dev_info.num_lu);
> > +
> > + ufshpb_scan_hpb_lu(hba, &hpb_dev_info, desc_buf);
> > +
> > +release_desc_buf:
> > + kfree(desc_buf);
> > +}
>
> Since the UFS driver calls scsi_scan_host() from ufshcd_add_lus(), do you
> agree that the above wait_event_timeout() call can be eliminated by splitting
> ufshpb_init() into two functions and by calling the part below
> wait_event_timeout() after scsi_scan_host() has finished?
Yes, I agree the above wait_event_timeout() call can be eliminated.
I will change these functions.
> > +void ufshpb_remove(struct ufs_hba *hba)
> > +{
> > + struct ufshpb_lu *hpb, *n_hpb;
> > + struct ufsf_feature_info *ufsf;
> > + struct scsi_device *sdev;
> > +
> > + ufsf = &hba->ufsf;
> > +
> > + list_for_each_entry_safe(hpb, n_hpb, &lh_hpb_lu, list_hpb_lu) {
> > + ufshpb_set_state(hpb, HPB_FAILED);
> > +
> > + sdev = hpb->sdev_ufs_lu;
> > + sdev->hostdata = NULL;
> > +
> > + ufshpb_destroy_region_tbl(hpb);
> > +
> > + list_del_init(&hpb->list_hpb_lu);
> > + ufshpb_remove_sysfs(hpb);
> > +
> > + kfree(hpb);
> > + }
> > +
> > + dev_info(hba->dev, "ufshpb: remove success\n");
> > +}
>
> Should the code in the body of the above loop perhaps be called from inside
> ufshcd_slave_destroy()?
Moving other stuffs in the loop is good idea, but removing attributes is problem.
To avoid adding new kobject, I will try to use sysfs_merge_group()
for adding attributes. To delete merged attributes, sysfs_unmerge_group()
should be called. But sysfs_remove_groups() is called before calling ufshcd_slave_destroy().
> > +void ufshpb_scan_feature(struct ufs_hba *hba)
> > +{
> > + init_waitqueue_head(&hba->ufsf.sdev_wait);
> > + atomic_set(&hba->ufsf.slave_conf_cnt, 0);
> > +
> > + if (hba->dev_info.wspecversion >= HPB_SUPPORT_VERSION &&
> > + (hba->dev_info.b_ufs_feature_sup & UFS_DEV_HPB_SUPPORT))
> > + async_schedule(ufshpb_init, &hba->ufsf);
> > +}
>
> Why does this function use async_schedule()?
The wait_event_timeout() call will be removed, so it will be changed.
Thanks,
Daejun
next prev parent reply other threads:[~2020-08-13 3:03 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20200806073257epcms2p61564ed62e02fc42fc3c2b18fa92a038d@epcms2p6>
2020-08-06 7:32 ` [PATCH v8 0/4] scsi: ufs: Add Host Performance Booster Support Daejun Park
2020-08-06 9:02 ` [PATCH v8 1/4] scsi: ufs: Add UFS feature related parameter Daejun Park
2020-08-06 9:11 ` [PATCH v8 2/4] scsi: ufs: Introduce HPB feature Daejun Park
2020-08-06 9:15 ` [PATCH v8 3/4] scsi: ufs: L2P map management for HPB read Daejun Park
2020-08-06 9:18 ` [PATCH v8 4/4] scsi: ufs: Prepare HPB read for cached sub-region Daejun Park
2020-08-09 0:35 ` Bart Van Assche
2020-08-13 3:15 ` Daejun Park
2020-08-09 0:29 ` [PATCH v8 3/4] scsi: ufs: L2P map management for HPB read Bart Van Assche
2020-08-13 3:13 ` Daejun Park
2020-08-08 22:56 ` [PATCH v8 2/4] scsi: ufs: Introduce HPB feature Bart Van Assche
2020-08-13 2:13 ` Daejun Park
2020-08-09 0:07 ` Bart Van Assche
2020-08-13 3:00 ` Daejun Park [this message]
2020-08-13 3:22 ` Bart Van Assche
2020-08-08 23:00 ` [PATCH v8 1/4] scsi: ufs: Add UFS feature related parameter Bart Van Assche
2020-08-13 2:16 ` Daejun Park
2020-08-06 9:52 ` [PATCH v8 0/4] scsi: ufs: Add Host Performance Booster Support Bean Huo
2020-08-06 9:56 ` Avri Altman
2020-08-06 10:02 ` Bean Huo
2020-08-06 10:12 ` Avri Altman
2020-08-06 10:28 ` Bean Huo
2020-08-06 13:56 ` Avri Altman
2020-08-06 16:36 ` Alim Akhtar
2020-08-06 18:39 ` Bart Van Assche
2020-08-06 23:15 ` Daejun Park
2020-08-07 4:32 ` Martin K. Petersen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=231786897.01597287781957.JavaMail.epsvc@epcpadp2 \
--to=daejun7.park@samsung.com \
--cc=adel.choi@samsung.com \
--cc=alim.akhtar@samsung.com \
--cc=asutoshd@codeaurora.org \
--cc=avri.altman@wdc.com \
--cc=beanhuo@micron.com \
--cc=boram.shin@samsung.com \
--cc=bvanassche@acm.org \
--cc=cang@codeaurora.org \
--cc=j-young.choi@samsung.com \
--cc=jejb@linux.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=sangyoon.oh@samsung.com \
--cc=stanley.chu@mediatek.com \
--cc=sungjun07.park@samsung.com \
--cc=tomas.winkler@intel.com \
--cc=ymhungry.lee@samsung.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.