public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
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

  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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox