diff mbox series

[v5,05/10] scsi: ufshpb: Region inactivation in host mode

Message ID 20210302132503.224670-6-avri.altman@wdc.com
State New
Headers show
Series Add Host control mode to HPB | expand

Commit Message

Avri Altman March 2, 2021, 1:24 p.m. UTC
I host mode, the host is expected to send HPB-WRITE-BUFFER with
buffer-id = 0x1 when it inactivates a region.

Use the map-requests pool as there is no point in assigning a
designated cache for umap-requests.

Signed-off-by: Avri Altman <avri.altman@wdc.com>
---
 drivers/scsi/ufs/ufshpb.c | 14 ++++++++++++++
 drivers/scsi/ufs/ufshpb.h |  1 +
 2 files changed, 15 insertions(+)

Comments

Can Guo March 11, 2021, 8:20 a.m. UTC | #1
On 2021-03-02 21:24, Avri Altman wrote:
> I host mode, the host is expected to send HPB-WRITE-BUFFER with


In host mode,

> buffer-id = 0x1 when it inactivates a region.

> 

> Use the map-requests pool as there is no point in assigning a

> designated cache for umap-requests.

> 

> Signed-off-by: Avri Altman <avri.altman@wdc.com>

> ---

>  drivers/scsi/ufs/ufshpb.c | 14 ++++++++++++++

>  drivers/scsi/ufs/ufshpb.h |  1 +

>  2 files changed, 15 insertions(+)

> 

> diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c

> index 6f4fd22eaf2f..0744feb4d484 100644

> --- a/drivers/scsi/ufs/ufshpb.c

> +++ b/drivers/scsi/ufs/ufshpb.c

> @@ -907,6 +907,7 @@ static int ufshpb_execute_umap_req(struct ufshpb_lu 

> *hpb,

> 

>  	blk_execute_rq_nowait(q, NULL, req, 1, ufshpb_umap_req_compl_fn);

> 

> +	hpb->stats.umap_req_cnt++;

>  	return 0;

>  }

> 

> @@ -1103,6 +1104,12 @@ static int ufshpb_issue_umap_req(struct 

> ufshpb_lu *hpb,

>  	return -EAGAIN;

>  }

> 

> +static int ufshpb_issue_umap_single_req(struct ufshpb_lu *hpb,

> +					struct ufshpb_region *rgn)

> +{

> +	return ufshpb_issue_umap_req(hpb, rgn);

> +}

> +

>  static int ufshpb_issue_umap_all_req(struct ufshpb_lu *hpb)

>  {

>  	return ufshpb_issue_umap_req(hpb, NULL);

> @@ -1115,6 +1122,10 @@ static void __ufshpb_evict_region(struct 

> ufshpb_lu *hpb,

>  	struct ufshpb_subregion *srgn;

>  	int srgn_idx;

> 

> +


No need of this blank line.

Regards,
Can Guo.

> +	if (hpb->is_hcm && ufshpb_issue_umap_single_req(hpb, rgn))

> +		return;

> +

>  	lru_info = &hpb->lru_info;

> 

>  	dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "evict region %d\n", 

> rgn->rgn_idx);

> @@ -1855,6 +1866,7 @@ ufshpb_sysfs_attr_show_func(rb_noti_cnt);

>  ufshpb_sysfs_attr_show_func(rb_active_cnt);

>  ufshpb_sysfs_attr_show_func(rb_inactive_cnt);

>  ufshpb_sysfs_attr_show_func(map_req_cnt);

> +ufshpb_sysfs_attr_show_func(umap_req_cnt);

> 

>  static struct attribute *hpb_dev_stat_attrs[] = {

>  	&dev_attr_hit_cnt.attr,

> @@ -1863,6 +1875,7 @@ static struct attribute *hpb_dev_stat_attrs[] = {

>  	&dev_attr_rb_active_cnt.attr,

>  	&dev_attr_rb_inactive_cnt.attr,

>  	&dev_attr_map_req_cnt.attr,

> +	&dev_attr_umap_req_cnt.attr,

>  	NULL,

>  };

> 

> @@ -1978,6 +1991,7 @@ static void ufshpb_stat_init(struct ufshpb_lu 

> *hpb)

>  	hpb->stats.rb_active_cnt = 0;

>  	hpb->stats.rb_inactive_cnt = 0;

>  	hpb->stats.map_req_cnt = 0;

> +	hpb->stats.umap_req_cnt = 0;

>  }

> 

>  static void ufshpb_param_init(struct ufshpb_lu *hpb)

> diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h

> index bd4308010466..84598a317897 100644

> --- a/drivers/scsi/ufs/ufshpb.h

> +++ b/drivers/scsi/ufs/ufshpb.h

> @@ -186,6 +186,7 @@ struct ufshpb_stats {

>  	u64 rb_inactive_cnt;

>  	u64 map_req_cnt;

>  	u64 pre_req_cnt;

> +	u64 umap_req_cnt;

>  };

> 

>  struct ufshpb_lu {
Avri Altman March 11, 2021, 9:03 a.m. UTC | #2
> 

> On 2021-03-02 21:24, Avri Altman wrote:

> > I host mode, the host is expected to send HPB-WRITE-BUFFER with

> 

> In host mode,

Done.

> >  static int ufshpb_issue_umap_all_req(struct ufshpb_lu *hpb)

> >  {

> >       return ufshpb_issue_umap_req(hpb, NULL);

> > @@ -1115,6 +1122,10 @@ static void __ufshpb_evict_region(struct

> > ufshpb_lu *hpb,

> >       struct ufshpb_subregion *srgn;

> >       int srgn_idx;

> >

> > +

> 

> No need of this blank line.

Done.

Thanks,
Avri

> 

> Regards,

> Can Guo.
Can Guo March 15, 2021, 4:02 a.m. UTC | #3
On 2021-03-02 21:24, Avri Altman wrote:
> I host mode, the host is expected to send HPB-WRITE-BUFFER with

> buffer-id = 0x1 when it inactivates a region.

> 

> Use the map-requests pool as there is no point in assigning a

> designated cache for umap-requests.

> 

> Signed-off-by: Avri Altman <avri.altman@wdc.com>

> ---

>  drivers/scsi/ufs/ufshpb.c | 14 ++++++++++++++

>  drivers/scsi/ufs/ufshpb.h |  1 +

>  2 files changed, 15 insertions(+)

> 

> diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c

> index 6f4fd22eaf2f..0744feb4d484 100644

> --- a/drivers/scsi/ufs/ufshpb.c

> +++ b/drivers/scsi/ufs/ufshpb.c

> @@ -907,6 +907,7 @@ static int ufshpb_execute_umap_req(struct ufshpb_lu 

> *hpb,

> 

>  	blk_execute_rq_nowait(q, NULL, req, 1, ufshpb_umap_req_compl_fn);

> 

> +	hpb->stats.umap_req_cnt++;

>  	return 0;

>  }

> 

> @@ -1103,6 +1104,12 @@ static int ufshpb_issue_umap_req(struct 

> ufshpb_lu *hpb,

>  	return -EAGAIN;

>  }

> 

> +static int ufshpb_issue_umap_single_req(struct ufshpb_lu *hpb,

> +					struct ufshpb_region *rgn)

> +{

> +	return ufshpb_issue_umap_req(hpb, rgn);

> +}

> +

>  static int ufshpb_issue_umap_all_req(struct ufshpb_lu *hpb)

>  {

>  	return ufshpb_issue_umap_req(hpb, NULL);

> @@ -1115,6 +1122,10 @@ static void __ufshpb_evict_region(struct 

> ufshpb_lu *hpb,

>  	struct ufshpb_subregion *srgn;

>  	int srgn_idx;

> 

> +

> +	if (hpb->is_hcm && ufshpb_issue_umap_single_req(hpb, rgn))


__ufshpb_evict_region() is called with rgn_state_lock held and IRQ 
disabled,
when ufshpb_issue_umap_single_req() invokes blk_execute_rq_nowait(), 
below
warning shall pop up every time, fix it?

void blk_execute_rq_nowait(struct request_queue *q, struct gendisk 
*bd_disk,
		   struct request *rq, int at_head,
			   rq_end_io_fn *done)
{
	WARN_ON(irqs_disabled());
...

Thanks.
Can Guo.

> +		return;

> +

>  	lru_info = &hpb->lru_info;

> 

>  	dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "evict region %d\n", 

> rgn->rgn_idx);

> @@ -1855,6 +1866,7 @@ ufshpb_sysfs_attr_show_func(rb_noti_cnt);

>  ufshpb_sysfs_attr_show_func(rb_active_cnt);

>  ufshpb_sysfs_attr_show_func(rb_inactive_cnt);

>  ufshpb_sysfs_attr_show_func(map_req_cnt);

> +ufshpb_sysfs_attr_show_func(umap_req_cnt);

> 

>  static struct attribute *hpb_dev_stat_attrs[] = {

>  	&dev_attr_hit_cnt.attr,

> @@ -1863,6 +1875,7 @@ static struct attribute *hpb_dev_stat_attrs[] = {

>  	&dev_attr_rb_active_cnt.attr,

>  	&dev_attr_rb_inactive_cnt.attr,

>  	&dev_attr_map_req_cnt.attr,

> +	&dev_attr_umap_req_cnt.attr,

>  	NULL,

>  };

> 

> @@ -1978,6 +1991,7 @@ static void ufshpb_stat_init(struct ufshpb_lu 

> *hpb)

>  	hpb->stats.rb_active_cnt = 0;

>  	hpb->stats.rb_inactive_cnt = 0;

>  	hpb->stats.map_req_cnt = 0;

> +	hpb->stats.umap_req_cnt = 0;

>  }

> 

>  static void ufshpb_param_init(struct ufshpb_lu *hpb)

> diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h

> index bd4308010466..84598a317897 100644

> --- a/drivers/scsi/ufs/ufshpb.h

> +++ b/drivers/scsi/ufs/ufshpb.h

> @@ -186,6 +186,7 @@ struct ufshpb_stats {

>  	u64 rb_inactive_cnt;

>  	u64 map_req_cnt;

>  	u64 pre_req_cnt;

> +	u64 umap_req_cnt;

>  };

> 

>  struct ufshpb_lu {
Can Guo March 15, 2021, 7:33 a.m. UTC | #4
On 2021-03-15 12:02, Can Guo wrote:
> On 2021-03-02 21:24, Avri Altman wrote:

>> I host mode, the host is expected to send HPB-WRITE-BUFFER with

>> buffer-id = 0x1 when it inactivates a region.

>> 

>> Use the map-requests pool as there is no point in assigning a

>> designated cache for umap-requests.

>> 

>> Signed-off-by: Avri Altman <avri.altman@wdc.com>

>> ---

>>  drivers/scsi/ufs/ufshpb.c | 14 ++++++++++++++

>>  drivers/scsi/ufs/ufshpb.h |  1 +

>>  2 files changed, 15 insertions(+)

>> 

>> diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c

>> index 6f4fd22eaf2f..0744feb4d484 100644

>> --- a/drivers/scsi/ufs/ufshpb.c

>> +++ b/drivers/scsi/ufs/ufshpb.c

>> @@ -907,6 +907,7 @@ static int ufshpb_execute_umap_req(struct 

>> ufshpb_lu *hpb,

>> 

>>  	blk_execute_rq_nowait(q, NULL, req, 1, ufshpb_umap_req_compl_fn);

>> 

>> +	hpb->stats.umap_req_cnt++;

>>  	return 0;

>>  }

>> 

>> @@ -1103,6 +1104,12 @@ static int ufshpb_issue_umap_req(struct 

>> ufshpb_lu *hpb,

>>  	return -EAGAIN;

>>  }

>> 

>> +static int ufshpb_issue_umap_single_req(struct ufshpb_lu *hpb,

>> +					struct ufshpb_region *rgn)

>> +{

>> +	return ufshpb_issue_umap_req(hpb, rgn);

>> +}

>> +

>>  static int ufshpb_issue_umap_all_req(struct ufshpb_lu *hpb)

>>  {

>>  	return ufshpb_issue_umap_req(hpb, NULL);

>> @@ -1115,6 +1122,10 @@ static void __ufshpb_evict_region(struct 

>> ufshpb_lu *hpb,

>>  	struct ufshpb_subregion *srgn;

>>  	int srgn_idx;

>> 

>> +

>> +	if (hpb->is_hcm && ufshpb_issue_umap_single_req(hpb, rgn))

> 

> __ufshpb_evict_region() is called with rgn_state_lock held and IRQ 

> disabled,

> when ufshpb_issue_umap_single_req() invokes blk_execute_rq_nowait(), 

> below

> warning shall pop up every time, fix it?

> 

> void blk_execute_rq_nowait(struct request_queue *q, struct gendisk 

> *bd_disk,

> 		   struct request *rq, int at_head,

> 			   rq_end_io_fn *done)

> {

> 	WARN_ON(irqs_disabled());

> ...

> 


Moreover, since we are here with rgn_state_lock held and IRQ disabled,
in ufshpb_get_req(), rq = kmem_cache_alloc(hpb->map_req_cache, 
GFP_KERNEL)
has the GFP_KERNEL flag, scheduling while atomic???

Can Guo.

> Thanks.

> Can Guo.

> 

>> +		return;

>> +

>>  	lru_info = &hpb->lru_info;

>> 

>>  	dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "evict region %d\n", 

>> rgn->rgn_idx);

>> @@ -1855,6 +1866,7 @@ ufshpb_sysfs_attr_show_func(rb_noti_cnt);

>>  ufshpb_sysfs_attr_show_func(rb_active_cnt);

>>  ufshpb_sysfs_attr_show_func(rb_inactive_cnt);

>>  ufshpb_sysfs_attr_show_func(map_req_cnt);

>> +ufshpb_sysfs_attr_show_func(umap_req_cnt);

>> 

>>  static struct attribute *hpb_dev_stat_attrs[] = {

>>  	&dev_attr_hit_cnt.attr,

>> @@ -1863,6 +1875,7 @@ static struct attribute *hpb_dev_stat_attrs[] = 

>> {

>>  	&dev_attr_rb_active_cnt.attr,

>>  	&dev_attr_rb_inactive_cnt.attr,

>>  	&dev_attr_map_req_cnt.attr,

>> +	&dev_attr_umap_req_cnt.attr,

>>  	NULL,

>>  };

>> 

>> @@ -1978,6 +1991,7 @@ static void ufshpb_stat_init(struct ufshpb_lu 

>> *hpb)

>>  	hpb->stats.rb_active_cnt = 0;

>>  	hpb->stats.rb_inactive_cnt = 0;

>>  	hpb->stats.map_req_cnt = 0;

>> +	hpb->stats.umap_req_cnt = 0;

>>  }

>> 

>>  static void ufshpb_param_init(struct ufshpb_lu *hpb)

>> diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h

>> index bd4308010466..84598a317897 100644

>> --- a/drivers/scsi/ufs/ufshpb.h

>> +++ b/drivers/scsi/ufs/ufshpb.h

>> @@ -186,6 +186,7 @@ struct ufshpb_stats {

>>  	u64 rb_inactive_cnt;

>>  	u64 map_req_cnt;

>>  	u64 pre_req_cnt;

>> +	u64 umap_req_cnt;

>>  };

>> 

>>  struct ufshpb_lu {
Avri Altman March 16, 2021, 8:30 a.m. UTC | #5
> >> ---

> >>  drivers/scsi/ufs/ufshpb.c | 14 ++++++++++++++

> >>  drivers/scsi/ufs/ufshpb.h |  1 +

> >>  2 files changed, 15 insertions(+)

> >>

> >> diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c

> >> index 6f4fd22eaf2f..0744feb4d484 100644

> >> --- a/drivers/scsi/ufs/ufshpb.c

> >> +++ b/drivers/scsi/ufs/ufshpb.c

> >> @@ -907,6 +907,7 @@ static int ufshpb_execute_umap_req(struct

> >> ufshpb_lu *hpb,

> >>

> >>      blk_execute_rq_nowait(q, NULL, req, 1, ufshpb_umap_req_compl_fn);

> >>

> >> +    hpb->stats.umap_req_cnt++;

> >>      return 0;

> >>  }

> >>

> >> @@ -1103,6 +1104,12 @@ static int ufshpb_issue_umap_req(struct

> >> ufshpb_lu *hpb,

> >>      return -EAGAIN;

> >>  }

> >>

> >> +static int ufshpb_issue_umap_single_req(struct ufshpb_lu *hpb,

> >> +                                    struct ufshpb_region *rgn)

> >> +{

> >> +    return ufshpb_issue_umap_req(hpb, rgn);

> >> +}

> >> +

> >>  static int ufshpb_issue_umap_all_req(struct ufshpb_lu *hpb)

> >>  {

> >>      return ufshpb_issue_umap_req(hpb, NULL);

> >> @@ -1115,6 +1122,10 @@ static void __ufshpb_evict_region(struct

> >> ufshpb_lu *hpb,

> >>      struct ufshpb_subregion *srgn;

> >>      int srgn_idx;

> >>

> >> +

> >> +    if (hpb->is_hcm && ufshpb_issue_umap_single_req(hpb, rgn))

> >

> > __ufshpb_evict_region() is called with rgn_state_lock held and IRQ

> > disabled,

> > when ufshpb_issue_umap_single_req() invokes blk_execute_rq_nowait(),

> > below

> > warning shall pop up every time, fix it?

> >

> > void blk_execute_rq_nowait(struct request_queue *q, struct gendisk

> > *bd_disk,

> >                  struct request *rq, int at_head,

> >                          rq_end_io_fn *done)

> > {

> >       WARN_ON(irqs_disabled());

> > ...

> >

> 

> Moreover, since we are here with rgn_state_lock held and IRQ disabled,

> in ufshpb_get_req(), rq = kmem_cache_alloc(hpb->map_req_cache,

> GFP_KERNEL)

> has the GFP_KERNEL flag, scheduling while atomic???

I think your comment applies to  ufshpb_issue_umap_all_req as well,
Which is called from slave_configure/scsi_add_lun.

Since the host-mode series is utilizing the framework laid by the device-mode,
Maybe you can add this comment to  Daejun's last version?

Thanks,
Avri

> 

> Can Guo.

> 

> > Thanks.

> > Can Guo.

> >

> >> +            return;

> >> +

> >>      lru_info = &hpb->lru_info;

> >>

> >>      dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "evict region %d\n",

> >> rgn->rgn_idx);

> >> @@ -1855,6 +1866,7 @@ ufshpb_sysfs_attr_show_func(rb_noti_cnt);

> >>  ufshpb_sysfs_attr_show_func(rb_active_cnt);

> >>  ufshpb_sysfs_attr_show_func(rb_inactive_cnt);

> >>  ufshpb_sysfs_attr_show_func(map_req_cnt);

> >> +ufshpb_sysfs_attr_show_func(umap_req_cnt);

> >>

> >>  static struct attribute *hpb_dev_stat_attrs[] = {

> >>      &dev_attr_hit_cnt.attr,

> >> @@ -1863,6 +1875,7 @@ static struct attribute *hpb_dev_stat_attrs[] =

> >> {

> >>      &dev_attr_rb_active_cnt.attr,

> >>      &dev_attr_rb_inactive_cnt.attr,

> >>      &dev_attr_map_req_cnt.attr,

> >> +    &dev_attr_umap_req_cnt.attr,

> >>      NULL,

> >>  };

> >>

> >> @@ -1978,6 +1991,7 @@ static void ufshpb_stat_init(struct ufshpb_lu

> >> *hpb)

> >>      hpb->stats.rb_active_cnt = 0;

> >>      hpb->stats.rb_inactive_cnt = 0;

> >>      hpb->stats.map_req_cnt = 0;

> >> +    hpb->stats.umap_req_cnt = 0;

> >>  }

> >>

> >>  static void ufshpb_param_init(struct ufshpb_lu *hpb)

> >> diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h

> >> index bd4308010466..84598a317897 100644

> >> --- a/drivers/scsi/ufs/ufshpb.h

> >> +++ b/drivers/scsi/ufs/ufshpb.h

> >> @@ -186,6 +186,7 @@ struct ufshpb_stats {

> >>      u64 rb_inactive_cnt;

> >>      u64 map_req_cnt;

> >>      u64 pre_req_cnt;

> >> +    u64 umap_req_cnt;

> >>  };

> >>

> >>  struct ufshpb_lu {
Can Guo March 17, 2021, 1:23 a.m. UTC | #6
On 2021-03-16 16:30, Avri Altman wrote:
>> >> ---

>> >>  drivers/scsi/ufs/ufshpb.c | 14 ++++++++++++++

>> >>  drivers/scsi/ufs/ufshpb.h |  1 +

>> >>  2 files changed, 15 insertions(+)

>> >>

>> >> diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c

>> >> index 6f4fd22eaf2f..0744feb4d484 100644

>> >> --- a/drivers/scsi/ufs/ufshpb.c

>> >> +++ b/drivers/scsi/ufs/ufshpb.c

>> >> @@ -907,6 +907,7 @@ static int ufshpb_execute_umap_req(struct

>> >> ufshpb_lu *hpb,

>> >>

>> >>      blk_execute_rq_nowait(q, NULL, req, 1, ufshpb_umap_req_compl_fn);

>> >>

>> >> +    hpb->stats.umap_req_cnt++;

>> >>      return 0;

>> >>  }

>> >>

>> >> @@ -1103,6 +1104,12 @@ static int ufshpb_issue_umap_req(struct

>> >> ufshpb_lu *hpb,

>> >>      return -EAGAIN;

>> >>  }

>> >>

>> >> +static int ufshpb_issue_umap_single_req(struct ufshpb_lu *hpb,

>> >> +                                    struct ufshpb_region *rgn)

>> >> +{

>> >> +    return ufshpb_issue_umap_req(hpb, rgn);

>> >> +}

>> >> +

>> >>  static int ufshpb_issue_umap_all_req(struct ufshpb_lu *hpb)

>> >>  {

>> >>      return ufshpb_issue_umap_req(hpb, NULL);

>> >> @@ -1115,6 +1122,10 @@ static void __ufshpb_evict_region(struct

>> >> ufshpb_lu *hpb,

>> >>      struct ufshpb_subregion *srgn;

>> >>      int srgn_idx;

>> >>

>> >> +

>> >> +    if (hpb->is_hcm && ufshpb_issue_umap_single_req(hpb, rgn))

>> >

>> > __ufshpb_evict_region() is called with rgn_state_lock held and IRQ

>> > disabled,

>> > when ufshpb_issue_umap_single_req() invokes blk_execute_rq_nowait(),

>> > below

>> > warning shall pop up every time, fix it?

>> >

>> > void blk_execute_rq_nowait(struct request_queue *q, struct gendisk

>> > *bd_disk,

>> >                  struct request *rq, int at_head,

>> >                          rq_end_io_fn *done)

>> > {

>> >       WARN_ON(irqs_disabled());

>> > ...

>> >

>> 

>> Moreover, since we are here with rgn_state_lock held and IRQ disabled,

>> in ufshpb_get_req(), rq = kmem_cache_alloc(hpb->map_req_cache,

>> GFP_KERNEL)

>> has the GFP_KERNEL flag, scheduling while atomic???

> I think your comment applies to  ufshpb_issue_umap_all_req as well,

> Which is called from slave_configure/scsi_add_lun.


ufshpb_issue_umap_all_req() is not called from atomic contexts,
so ufshpb_issue_umap_all_req() is fine.

Thanks,
Can Guo.

> 

> Since the host-mode series is utilizing the framework laid by the 

> device-mode,

> Maybe you can add this comment to  Daejun's last version?

> 

> Thanks,

> Avri

> 

>> 

>> Can Guo.

>> 

>> > Thanks.

>> > Can Guo.

>> >

>> >> +            return;

>> >> +

>> >>      lru_info = &hpb->lru_info;

>> >>

>> >>      dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "evict region %d\n",

>> >> rgn->rgn_idx);

>> >> @@ -1855,6 +1866,7 @@ ufshpb_sysfs_attr_show_func(rb_noti_cnt);

>> >>  ufshpb_sysfs_attr_show_func(rb_active_cnt);

>> >>  ufshpb_sysfs_attr_show_func(rb_inactive_cnt);

>> >>  ufshpb_sysfs_attr_show_func(map_req_cnt);

>> >> +ufshpb_sysfs_attr_show_func(umap_req_cnt);

>> >>

>> >>  static struct attribute *hpb_dev_stat_attrs[] = {

>> >>      &dev_attr_hit_cnt.attr,

>> >> @@ -1863,6 +1875,7 @@ static struct attribute *hpb_dev_stat_attrs[] =

>> >> {

>> >>      &dev_attr_rb_active_cnt.attr,

>> >>      &dev_attr_rb_inactive_cnt.attr,

>> >>      &dev_attr_map_req_cnt.attr,

>> >> +    &dev_attr_umap_req_cnt.attr,

>> >>      NULL,

>> >>  };

>> >>

>> >> @@ -1978,6 +1991,7 @@ static void ufshpb_stat_init(struct ufshpb_lu

>> >> *hpb)

>> >>      hpb->stats.rb_active_cnt = 0;

>> >>      hpb->stats.rb_inactive_cnt = 0;

>> >>      hpb->stats.map_req_cnt = 0;

>> >> +    hpb->stats.umap_req_cnt = 0;

>> >>  }

>> >>

>> >>  static void ufshpb_param_init(struct ufshpb_lu *hpb)

>> >> diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h

>> >> index bd4308010466..84598a317897 100644

>> >> --- a/drivers/scsi/ufs/ufshpb.h

>> >> +++ b/drivers/scsi/ufs/ufshpb.h

>> >> @@ -186,6 +186,7 @@ struct ufshpb_stats {

>> >>      u64 rb_inactive_cnt;

>> >>      u64 map_req_cnt;

>> >>      u64 pre_req_cnt;

>> >> +    u64 umap_req_cnt;

>> >>  };

>> >>

>> >>  struct ufshpb_lu {
Daejun Park March 17, 2021, 2:28 a.m. UTC | #7
>> >> ---

>> >>  drivers/scsi/ufs/ufshpb.c | 14 ++++++++++++++

>> >>  drivers/scsi/ufs/ufshpb.h |  1 +

>> >>  2 files changed, 15 insertions(+)

>> >>

>> >> diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c

>> >> index 6f4fd22eaf2f..0744feb4d484 100644

>> >> --- a/drivers/scsi/ufs/ufshpb.c

>> >> +++ b/drivers/scsi/ufs/ufshpb.c

>> >> @@ -907,6 +907,7 @@ static int ufshpb_execute_umap_req(struct

>> >> ufshpb_lu *hpb,

>> >>

>> >>      blk_execute_rq_nowait(q, NULL, req, 1, ufshpb_umap_req_compl_fn);

>> >>

>> >> +    hpb->stats.umap_req_cnt++;

>> >>      return 0;

>> >>  }

>> >>

>> >> @@ -1103,6 +1104,12 @@ static int ufshpb_issue_umap_req(struct

>> >> ufshpb_lu *hpb,

>> >>      return -EAGAIN;

>> >>  }

>> >>

>> >> +static int ufshpb_issue_umap_single_req(struct ufshpb_lu *hpb,

>> >> +                                    struct ufshpb_region *rgn)

>> >> +{

>> >> +    return ufshpb_issue_umap_req(hpb, rgn);

>> >> +}

>> >> +

>> >>  static int ufshpb_issue_umap_all_req(struct ufshpb_lu *hpb)

>> >>  {

>> >>      return ufshpb_issue_umap_req(hpb, NULL);

>> >> @@ -1115,6 +1122,10 @@ static void __ufshpb_evict_region(struct

>> >> ufshpb_lu *hpb,

>> >>      struct ufshpb_subregion *srgn;

>> >>      int srgn_idx;

>> >>

>> >> +

>> >> +    if (hpb->is_hcm && ufshpb_issue_umap_single_req(hpb, rgn))

>> >

>> > __ufshpb_evict_region() is called with rgn_state_lock held and IRQ

>> > disabled,

>> > when ufshpb_issue_umap_single_req() invokes blk_execute_rq_nowait(),

>> > below

>> > warning shall pop up every time, fix it?

>> >

>> > void blk_execute_rq_nowait(struct request_queue *q, struct gendisk

>> > *bd_disk,

>> >                  struct request *rq, int at_head,

>> >                          rq_end_io_fn *done)

>> > {

>> >       WARN_ON(irqs_disabled());

>> > ...

>> >

>> 

>> Moreover, since we are here with rgn_state_lock held and IRQ disabled,

>> in ufshpb_get_req(), rq = kmem_cache_alloc(hpb->map_req_cache,

>> GFP_KERNEL)

>> has the GFP_KERNEL flag, scheduling while atomic???

>I think your comment applies to  ufshpb_issue_umap_all_req as well,

>Which is called from slave_configure/scsi_add_lun.

> 

>Since the host-mode series is utilizing the framework laid by the device-mode,

>Maybe you can add this comment to  Daejun's last version?


Hi Avri, Can Guo

I think ufshpb_issue_umap_single_req() can be moved to end of ufshpb_evict_region().
Then we can avoid rgn_state_lock when it sends unmap command.

Thanks,
Daejun


>Thanks,

>Avri

> 

>> 

>> Can Guo.

>> 

>> > Thanks.

>> > Can Guo.

>> >

>> >> +            return;

>> >> +

>> >>      lru_info = &hpb->lru_info;

>> >>

>> >>      dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "evict region %d\n",

>> >> rgn->rgn_idx);

>> >> @@ -1855,6 +1866,7 @@ ufshpb_sysfs_attr_show_func(rb_noti_cnt);

>> >>  ufshpb_sysfs_attr_show_func(rb_active_cnt);

>> >>  ufshpb_sysfs_attr_show_func(rb_inactive_cnt);

>> >>  ufshpb_sysfs_attr_show_func(map_req_cnt);

>> >> +ufshpb_sysfs_attr_show_func(umap_req_cnt);

>> >>

>> >>  static struct attribute *hpb_dev_stat_attrs[] = {

>> >>      &dev_attr_hit_cnt.attr,

>> >> @@ -1863,6 +1875,7 @@ static struct attribute *hpb_dev_stat_attrs[] =

>> >> {

>> >>      &dev_attr_rb_active_cnt.attr,

>> >>      &dev_attr_rb_inactive_cnt.attr,

>> >>      &dev_attr_map_req_cnt.attr,

>> >> +    &dev_attr_umap_req_cnt.attr,

>> >>      NULL,

>> >>  };

>> >>

>> >> @@ -1978,6 +1991,7 @@ static void ufshpb_stat_init(struct ufshpb_lu

>> >> *hpb)

>> >>      hpb->stats.rb_active_cnt = 0;

>> >>      hpb->stats.rb_inactive_cnt = 0;

>> >>      hpb->stats.map_req_cnt = 0;

>> >> +    hpb->stats.umap_req_cnt = 0;

>> >>  }

>> >>

>> >>  static void ufshpb_param_init(struct ufshpb_lu *hpb)

>> >> diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h

>> >> index bd4308010466..84598a317897 100644

>> >> --- a/drivers/scsi/ufs/ufshpb.h

>> >> +++ b/drivers/scsi/ufs/ufshpb.h

>> >> @@ -186,6 +186,7 @@ struct ufshpb_stats {

>> >>      u64 rb_inactive_cnt;

>> >>      u64 map_req_cnt;

>> >>      u64 pre_req_cnt;

>> >> +    u64 umap_req_cnt;

>> >>  };

>> >>

>> >>  struct ufshpb_lu {

> 

> 

>
Can Guo March 17, 2021, 4:41 a.m. UTC | #8
On 2021-03-17 10:28, Daejun Park wrote:
>>> >> ---

>>> >>  drivers/scsi/ufs/ufshpb.c | 14 ++++++++++++++

>>> >>  drivers/scsi/ufs/ufshpb.h |  1 +

>>> >>  2 files changed, 15 insertions(+)

>>> >>

>>> >> diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c

>>> >> index 6f4fd22eaf2f..0744feb4d484 100644

>>> >> --- a/drivers/scsi/ufs/ufshpb.c

>>> >> +++ b/drivers/scsi/ufs/ufshpb.c

>>> >> @@ -907,6 +907,7 @@ static int ufshpb_execute_umap_req(struct

>>> >> ufshpb_lu *hpb,

>>> >>

>>> >>      blk_execute_rq_nowait(q, NULL, req, 1, ufshpb_umap_req_compl_fn);

>>> >>

>>> >> +    hpb->stats.umap_req_cnt++;

>>> >>      return 0;

>>> >>  }

>>> >>

>>> >> @@ -1103,6 +1104,12 @@ static int ufshpb_issue_umap_req(struct

>>> >> ufshpb_lu *hpb,

>>> >>      return -EAGAIN;

>>> >>  }

>>> >>

>>> >> +static int ufshpb_issue_umap_single_req(struct ufshpb_lu *hpb,

>>> >> +                                    struct ufshpb_region *rgn)

>>> >> +{

>>> >> +    return ufshpb_issue_umap_req(hpb, rgn);

>>> >> +}

>>> >> +

>>> >>  static int ufshpb_issue_umap_all_req(struct ufshpb_lu *hpb)

>>> >>  {

>>> >>      return ufshpb_issue_umap_req(hpb, NULL);

>>> >> @@ -1115,6 +1122,10 @@ static void __ufshpb_evict_region(struct

>>> >> ufshpb_lu *hpb,

>>> >>      struct ufshpb_subregion *srgn;

>>> >>      int srgn_idx;

>>> >>

>>> >> +

>>> >> +    if (hpb->is_hcm && ufshpb_issue_umap_single_req(hpb, rgn))

>>> >

>>> > __ufshpb_evict_region() is called with rgn_state_lock held and IRQ

>>> > disabled,

>>> > when ufshpb_issue_umap_single_req() invokes blk_execute_rq_nowait(),

>>> > below

>>> > warning shall pop up every time, fix it?

>>> >

>>> > void blk_execute_rq_nowait(struct request_queue *q, struct gendisk

>>> > *bd_disk,

>>> >                  struct request *rq, int at_head,

>>> >                          rq_end_io_fn *done)

>>> > {

>>> >       WARN_ON(irqs_disabled());

>>> > ...

>>> >

>>> 

>>> Moreover, since we are here with rgn_state_lock held and IRQ 

>>> disabled,

>>> in ufshpb_get_req(), rq = kmem_cache_alloc(hpb->map_req_cache,

>>> GFP_KERNEL)

>>> has the GFP_KERNEL flag, scheduling while atomic???

>> I think your comment applies to  ufshpb_issue_umap_all_req as well,

>> Which is called from slave_configure/scsi_add_lun.

>> 

>> Since the host-mode series is utilizing the framework laid by the 

>> device-mode,

>> Maybe you can add this comment to  Daejun's last version?

> 

> Hi Avri, Can Guo

> 

> I think ufshpb_issue_umap_single_req() can be moved to end of

> ufshpb_evict_region().

> Then we can avoid rgn_state_lock when it sends unmap command.


I am not the expert here, please you two fix it. I am just reporting
what can be wrong. Anyways, ufshpb_issue_umap_single_req() should not
be called with rgn_state_lock held - think about below (another deadly)
scenario.

lock(rgn_state_lock)
   ufshpb_issue_umap_single_req()
     ufshpb_prep()
        lock(rgn_state_lock)   <---------- recursive spin_lock

BTW, @Daejun shouldn't we stop passthrough cmds from stepping
into ufshpb_prep()? In current code, you are trying to use below
check to block cmds other than write/discard/read, but a passthrough
cmd can not be blocked by the check.

          if (!ufshpb_is_write_or_discard_cmd(cmd) &&
              !ufshpb_is_read_cmd(cmd))
                  return 0;

Thanks,
Can Guo.

> 

> Thanks,

> Daejun

> 

> 

>> Thanks,

>> Avri

>> 

>>> 

>>> Can Guo.

>>> 

>>> > Thanks.

>>> > Can Guo.

>>> >

>>> >> +            return;

>>> >> +

>>> >>      lru_info = &hpb->lru_info;

>>> >>

>>> >>      dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "evict region %d\n",

>>> >> rgn->rgn_idx);

>>> >> @@ -1855,6 +1866,7 @@ ufshpb_sysfs_attr_show_func(rb_noti_cnt);

>>> >>  ufshpb_sysfs_attr_show_func(rb_active_cnt);

>>> >>  ufshpb_sysfs_attr_show_func(rb_inactive_cnt);

>>> >>  ufshpb_sysfs_attr_show_func(map_req_cnt);

>>> >> +ufshpb_sysfs_attr_show_func(umap_req_cnt);

>>> >>

>>> >>  static struct attribute *hpb_dev_stat_attrs[] = {

>>> >>      &dev_attr_hit_cnt.attr,

>>> >> @@ -1863,6 +1875,7 @@ static struct attribute *hpb_dev_stat_attrs[] =

>>> >> {

>>> >>      &dev_attr_rb_active_cnt.attr,

>>> >>      &dev_attr_rb_inactive_cnt.attr,

>>> >>      &dev_attr_map_req_cnt.attr,

>>> >> +    &dev_attr_umap_req_cnt.attr,

>>> >>      NULL,

>>> >>  };

>>> >>

>>> >> @@ -1978,6 +1991,7 @@ static void ufshpb_stat_init(struct ufshpb_lu

>>> >> *hpb)

>>> >>      hpb->stats.rb_active_cnt = 0;

>>> >>      hpb->stats.rb_inactive_cnt = 0;

>>> >>      hpb->stats.map_req_cnt = 0;

>>> >> +    hpb->stats.umap_req_cnt = 0;

>>> >>  }

>>> >>

>>> >>  static void ufshpb_param_init(struct ufshpb_lu *hpb)

>>> >> diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h

>>> >> index bd4308010466..84598a317897 100644

>>> >> --- a/drivers/scsi/ufs/ufshpb.h

>>> >> +++ b/drivers/scsi/ufs/ufshpb.h

>>> >> @@ -186,6 +186,7 @@ struct ufshpb_stats {

>>> >>      u64 rb_inactive_cnt;

>>> >>      u64 map_req_cnt;

>>> >>      u64 pre_req_cnt;

>>> >> +    u64 umap_req_cnt;

>>> >>  };

>>> >>

>>> >>  struct ufshpb_lu {

>> 

>> 

>>
Daejun Park March 17, 2021, 5:19 a.m. UTC | #9
>>>> >> ---

>>>> >>  drivers/scsi/ufs/ufshpb.c | 14 ++++++++++++++

>>>> >>  drivers/scsi/ufs/ufshpb.h |  1 +

>>>> >>  2 files changed, 15 insertions(+)

>>>> >>

>>>> >> diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c

>>>> >> index 6f4fd22eaf2f..0744feb4d484 100644

>>>> >> --- a/drivers/scsi/ufs/ufshpb.c

>>>> >> +++ b/drivers/scsi/ufs/ufshpb.c

>>>> >> @@ -907,6 +907,7 @@ static int ufshpb_execute_umap_req(struct

>>>> >> ufshpb_lu *hpb,

>>>> >>

>>>> >>      blk_execute_rq_nowait(q, NULL, req, 1, ufshpb_umap_req_compl_fn);

>>>> >>

>>>> >> +    hpb->stats.umap_req_cnt++;

>>>> >>      return 0;

>>>> >>  }

>>>> >>

>>>> >> @@ -1103,6 +1104,12 @@ static int ufshpb_issue_umap_req(struct

>>>> >> ufshpb_lu *hpb,

>>>> >>      return -EAGAIN;

>>>> >>  }

>>>> >>

>>>> >> +static int ufshpb_issue_umap_single_req(struct ufshpb_lu *hpb,

>>>> >> +                                    struct ufshpb_region *rgn)

>>>> >> +{

>>>> >> +    return ufshpb_issue_umap_req(hpb, rgn);

>>>> >> +}

>>>> >> +

>>>> >>  static int ufshpb_issue_umap_all_req(struct ufshpb_lu *hpb)

>>>> >>  {

>>>> >>      return ufshpb_issue_umap_req(hpb, NULL);

>>>> >> @@ -1115,6 +1122,10 @@ static void __ufshpb_evict_region(struct

>>>> >> ufshpb_lu *hpb,

>>>> >>      struct ufshpb_subregion *srgn;

>>>> >>      int srgn_idx;

>>>> >>

>>>> >> +

>>>> >> +    if (hpb->is_hcm && ufshpb_issue_umap_single_req(hpb, rgn))

>>>> >

>>>> > __ufshpb_evict_region() is called with rgn_state_lock held and IRQ

>>>> > disabled,

>>>> > when ufshpb_issue_umap_single_req() invokes blk_execute_rq_nowait(),

>>>> > below

>>>> > warning shall pop up every time, fix it?

>>>> >

>>>> > void blk_execute_rq_nowait(struct request_queue *q, struct gendisk

>>>> > *bd_disk,

>>>> >                  struct request *rq, int at_head,

>>>> >                          rq_end_io_fn *done)

>>>> > {

>>>> >       WARN_ON(irqs_disabled());

>>>> > ...

>>>> >

>>>> 

>>>> Moreover, since we are here with rgn_state_lock held and IRQ 

>>>> disabled,

>>>> in ufshpb_get_req(), rq = kmem_cache_alloc(hpb->map_req_cache,

>>>> GFP_KERNEL)

>>>> has the GFP_KERNEL flag, scheduling while atomic???

>>> I think your comment applies to  ufshpb_issue_umap_all_req as well,

>>> Which is called from slave_configure/scsi_add_lun.

>>> 

>>> Since the host-mode series is utilizing the framework laid by the 

>>> device-mode,

>>> Maybe you can add this comment to  Daejun's last version?

>> 

>> Hi Avri, Can Guo

>> 

>> I think ufshpb_issue_umap_single_req() can be moved to end of

>> ufshpb_evict_region().

>> Then we can avoid rgn_state_lock when it sends unmap command.

> 

>I am not the expert here, please you two fix it. I am just reporting

>what can be wrong. Anyways, ufshpb_issue_umap_single_req() should not

>be called with rgn_state_lock held - think about below (another deadly)

>scenario.

> 

>lock(rgn_state_lock)

>   ufshpb_issue_umap_single_req()

>     ufshpb_prep()

>        lock(rgn_state_lock)   <---------- recursive spin_lock

> 

>BTW, @Daejun shouldn't we stop passthrough cmds from stepping

>into ufshpb_prep()? In current code, you are trying to use below

>check to block cmds other than write/discard/read, but a passthrough

>cmd can not be blocked by the check.

> 

>          if (!ufshpb_is_write_or_discard_cmd(cmd) &&

>              !ufshpb_is_read_cmd(cmd) )

>                  return 0;


I found this problem too. I fixed it and submit next patch.

if (blk_rq_is_scsi(cmd->request) ||
	    (!ufshpb_is_write_or_discard_cmd(cmd) &&
	    !ufshpb_is_read_cmd(cmd)))
		return 0;


Thanks,
Daejun

>Thanks,

>Can Guo.

> 

>> 

>> Thanks,

>> Daejun

>> 

>> 

>>> Thanks,

>>> Avri

>>> 

>>>> 

>>>> Can Guo.

>>>> 

>>>> > Thanks.

>>>> > Can Guo.

>>>> >

>>>> >> +            return;

>>>> >> +

>>>> >>      lru_info = &hpb->lru_info;

>>>> >>

>>>> >>      dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "evict region %d\n",

>>>> >> rgn->rgn_idx);

>>>> >> @@ -1855,6 +1866,7 @@ ufshpb_sysfs_attr_show_func(rb_noti_cnt);

>>>> >>  ufshpb_sysfs_attr_show_func(rb_active_cnt);

>>>> >>  ufshpb_sysfs_attr_show_func(rb_inactive_cnt);

>>>> >>  ufshpb_sysfs_attr_show_func(map_req_cnt);

>>>> >> +ufshpb_sysfs_attr_show_func(umap_req_cnt);

>>>> >>

>>>> >>  static struct attribute *hpb_dev_stat_attrs[] = {

>>>> >>      &dev_attr_hit_cnt.attr,

>>>> >> @@ -1863,6 +1875,7 @@ static struct attribute *hpb_dev_stat_attrs[] =

>>>> >> {

>>>> >>      &dev_attr_rb_active_cnt.attr,

>>>> >>      &dev_attr_rb_inactive_cnt.attr,

>>>> >>      &dev_attr_map_req_cnt.attr,

>>>> >> +    &dev_attr_umap_req_cnt.attr,

>>>> >>      NULL,

>>>> >>  };

>>>> >>

>>>> >> @@ -1978,6 +1991,7 @@ static void ufshpb_stat_init(struct ufshpb_lu

>>>> >> *hpb)

>>>> >>      hpb->stats.rb_active_cnt = 0;

>>>> >>      hpb->stats.rb_inactive_cnt = 0;

>>>> >>      hpb->stats.map_req_cnt = 0;

>>>> >> +    hpb->stats.umap_req_cnt = 0;

>>>> >>  }

>>>> >>

>>>> >>  static void ufshpb_param_init(struct ufshpb_lu *hpb)

>>>> >> diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h

>>>> >> index bd4308010466..84598a317897 100644

>>>> >> --- a/drivers/scsi/ufs/ufshpb.h

>>>> >> +++ b/drivers/scsi/ufs/ufshpb.h

>>>> >> @@ -186,6 +186,7 @@ struct ufshpb_stats {

>>>> >>      u64 rb_inactive_cnt;

>>>> >>      u64 map_req_cnt;

>>>> >>      u64 pre_req_cnt;

>>>> >> +    u64 umap_req_cnt;

>>>> >>  };

>>>> >>

>>>> >>  struct ufshpb_lu {

>>> 

>>> 

>>> 

> 

> 

>
Can Guo March 17, 2021, 5:34 a.m. UTC | #10
On 2021-03-17 13:19, Daejun Park wrote:
>>>>> >> ---

>>>>> >>  drivers/scsi/ufs/ufshpb.c | 14 ++++++++++++++

>>>>> >>  drivers/scsi/ufs/ufshpb.h |  1 +

>>>>> >>  2 files changed, 15 insertions(+)

>>>>> >>

>>>>> >> diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c

>>>>> >> index 6f4fd22eaf2f..0744feb4d484 100644

>>>>> >> --- a/drivers/scsi/ufs/ufshpb.c

>>>>> >> +++ b/drivers/scsi/ufs/ufshpb.c

>>>>> >> @@ -907,6 +907,7 @@ static int ufshpb_execute_umap_req(struct

>>>>> >> ufshpb_lu *hpb,

>>>>> >>

>>>>> >>      blk_execute_rq_nowait(q, NULL, req, 1, ufshpb_umap_req_compl_fn);

>>>>> >>

>>>>> >> +    hpb->stats.umap_req_cnt++;

>>>>> >>      return 0;

>>>>> >>  }

>>>>> >>

>>>>> >> @@ -1103,6 +1104,12 @@ static int ufshpb_issue_umap_req(struct

>>>>> >> ufshpb_lu *hpb,

>>>>> >>      return -EAGAIN;

>>>>> >>  }

>>>>> >>

>>>>> >> +static int ufshpb_issue_umap_single_req(struct ufshpb_lu *hpb,

>>>>> >> +                                    struct ufshpb_region *rgn)

>>>>> >> +{

>>>>> >> +    return ufshpb_issue_umap_req(hpb, rgn);

>>>>> >> +}

>>>>> >> +

>>>>> >>  static int ufshpb_issue_umap_all_req(struct ufshpb_lu *hpb)

>>>>> >>  {

>>>>> >>      return ufshpb_issue_umap_req(hpb, NULL);

>>>>> >> @@ -1115,6 +1122,10 @@ static void __ufshpb_evict_region(struct

>>>>> >> ufshpb_lu *hpb,

>>>>> >>      struct ufshpb_subregion *srgn;

>>>>> >>      int srgn_idx;

>>>>> >>

>>>>> >> +

>>>>> >> +    if (hpb->is_hcm && ufshpb_issue_umap_single_req(hpb, rgn))

>>>>> >

>>>>> > __ufshpb_evict_region() is called with rgn_state_lock held and IRQ

>>>>> > disabled,

>>>>> > when ufshpb_issue_umap_single_req() invokes blk_execute_rq_nowait(),

>>>>> > below

>>>>> > warning shall pop up every time, fix it?

>>>>> >

>>>>> > void blk_execute_rq_nowait(struct request_queue *q, struct gendisk

>>>>> > *bd_disk,

>>>>> >                  struct request *rq, int at_head,

>>>>> >                          rq_end_io_fn *done)

>>>>> > {

>>>>> >       WARN_ON(irqs_disabled());

>>>>> > ...

>>>>> >

>>>>> 

>>>>> Moreover, since we are here with rgn_state_lock held and IRQ

>>>>> disabled,

>>>>> in ufshpb_get_req(), rq = kmem_cache_alloc(hpb->map_req_cache,

>>>>> GFP_KERNEL)

>>>>> has the GFP_KERNEL flag, scheduling while atomic???

>>>> I think your comment applies to  ufshpb_issue_umap_all_req as well,

>>>> Which is called from slave_configure/scsi_add_lun.

>>>> 

>>>> Since the host-mode series is utilizing the framework laid by the

>>>> device-mode,

>>>> Maybe you can add this comment to  Daejun's last version?

>>> 

>>> Hi Avri, Can Guo

>>> 

>>> I think ufshpb_issue_umap_single_req() can be moved to end of

>>> ufshpb_evict_region().

>>> Then we can avoid rgn_state_lock when it sends unmap command.

>> 

>> I am not the expert here, please you two fix it. I am just reporting

>> what can be wrong. Anyways, ufshpb_issue_umap_single_req() should not

>> be called with rgn_state_lock held - think about below (another 

>> deadly)

>> scenario.

>> 

>> lock(rgn_state_lock)

>>   ufshpb_issue_umap_single_req()

>>     ufshpb_prep()

>>        lock(rgn_state_lock)   <---------- recursive spin_lock

>> 

>> BTW, @Daejun shouldn't we stop passthrough cmds from stepping

>> into ufshpb_prep()? In current code, you are trying to use below

>> check to block cmds other than write/discard/read, but a passthrough

>> cmd can not be blocked by the check.

>> 

>>          if (!ufshpb_is_write_or_discard_cmd(cmd) &&

>>              !ufshpb_is_read_cmd(cmd) )

>>                  return 0;

> 

> I found this problem too. I fixed it and submit next patch.


You mean in V30, which has not been uploaded yet, right?

Thanks,
Can Guo.

> 

> if (blk_rq_is_scsi(cmd->request) ||

> 	    (!ufshpb_is_write_or_discard_cmd(cmd) &&

> 	    !ufshpb_is_read_cmd(cmd)))

> 		return 0;

> 

> 

> Thanks,

> Daejun

> 

>> Thanks,

>> Can Guo.

>> 

>>> 

>>> Thanks,

>>> Daejun

>>> 

>>> 

>>>> Thanks,

>>>> Avri

>>>> 

>>>>> 

>>>>> Can Guo.

>>>>> 

>>>>> > Thanks.

>>>>> > Can Guo.

>>>>> >

>>>>> >> +            return;

>>>>> >> +

>>>>> >>      lru_info = &hpb->lru_info;

>>>>> >>

>>>>> >>      dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "evict region %d\n",

>>>>> >> rgn->rgn_idx);

>>>>> >> @@ -1855,6 +1866,7 @@ ufshpb_sysfs_attr_show_func(rb_noti_cnt);

>>>>> >>  ufshpb_sysfs_attr_show_func(rb_active_cnt);

>>>>> >>  ufshpb_sysfs_attr_show_func(rb_inactive_cnt);

>>>>> >>  ufshpb_sysfs_attr_show_func(map_req_cnt);

>>>>> >> +ufshpb_sysfs_attr_show_func(umap_req_cnt);

>>>>> >>

>>>>> >>  static struct attribute *hpb_dev_stat_attrs[] = {

>>>>> >>      &dev_attr_hit_cnt.attr,

>>>>> >> @@ -1863,6 +1875,7 @@ static struct attribute *hpb_dev_stat_attrs[] =

>>>>> >> {

>>>>> >>      &dev_attr_rb_active_cnt.attr,

>>>>> >>      &dev_attr_rb_inactive_cnt.attr,

>>>>> >>      &dev_attr_map_req_cnt.attr,

>>>>> >> +    &dev_attr_umap_req_cnt.attr,

>>>>> >>      NULL,

>>>>> >>  };

>>>>> >>

>>>>> >> @@ -1978,6 +1991,7 @@ static void ufshpb_stat_init(struct ufshpb_lu

>>>>> >> *hpb)

>>>>> >>      hpb->stats.rb_active_cnt = 0;

>>>>> >>      hpb->stats.rb_inactive_cnt = 0;

>>>>> >>      hpb->stats.map_req_cnt = 0;

>>>>> >> +    hpb->stats.umap_req_cnt = 0;

>>>>> >>  }

>>>>> >>

>>>>> >>  static void ufshpb_param_init(struct ufshpb_lu *hpb)

>>>>> >> diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h

>>>>> >> index bd4308010466..84598a317897 100644

>>>>> >> --- a/drivers/scsi/ufs/ufshpb.h

>>>>> >> +++ b/drivers/scsi/ufs/ufshpb.h

>>>>> >> @@ -186,6 +186,7 @@ struct ufshpb_stats {

>>>>> >>      u64 rb_inactive_cnt;

>>>>> >>      u64 map_req_cnt;

>>>>> >>      u64 pre_req_cnt;

>>>>> >> +    u64 umap_req_cnt;

>>>>> >>  };

>>>>> >>

>>>>> >>  struct ufshpb_lu {

>>>> 

>>>> 

>>>> 

>> 

>> 

>>
Daejun Park March 17, 2021, 5:42 a.m. UTC | #11
>>>>>> >> ---

>>>>>> >>  drivers/scsi/ufs/ufshpb.c | 14 ++++++++++++++

>>>>>> >>  drivers/scsi/ufs/ufshpb.h |  1 +

>>>>>> >>  2 files changed, 15 insertions(+)

>>>>>> >>

>>>>>> >> diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c

>>>>>> >> index 6f4fd22eaf2f..0744feb4d484 100644

>>>>>> >> --- a/drivers/scsi/ufs/ufshpb.c

>>>>>> >> +++ b/drivers/scsi/ufs/ufshpb.c

>>>>>> >> @@ -907,6 +907,7 @@ static int ufshpb_execute_umap_req(struct

>>>>>> >> ufshpb_lu *hpb,

>>>>>> >>

>>>>>> >>      blk_execute_rq_nowait(q, NULL, req, 1, ufshpb_umap_req_compl_fn);

>>>>>> >>

>>>>>> >> +    hpb->stats.umap_req_cnt++;

>>>>>> >>      return 0;

>>>>>> >>  }

>>>>>> >>

>>>>>> >> @@ -1103,6 +1104,12 @@ static int ufshpb_issue_umap_req(struct

>>>>>> >> ufshpb_lu *hpb,

>>>>>> >>      return -EAGAIN;

>>>>>> >>  }

>>>>>> >>

>>>>>> >> +static int ufshpb_issue_umap_single_req(struct ufshpb_lu *hpb,

>>>>>> >> +                                    struct ufshpb_region *rgn)

>>>>>> >> +{

>>>>>> >> +    return ufshpb_issue_umap_req(hpb, rgn);

>>>>>> >> +}

>>>>>> >> +

>>>>>> >>  static int ufshpb_issue_umap_all_req(struct ufshpb_lu *hpb)

>>>>>> >>  {

>>>>>> >>      return ufshpb_issue_umap_req(hpb, NULL);

>>>>>> >> @@ -1115,6 +1122,10 @@ static void __ufshpb_evict_region(struct

>>>>>> >> ufshpb_lu *hpb,

>>>>>> >>      struct ufshpb_subregion *srgn;

>>>>>> >>      int srgn_idx;

>>>>>> >>

>>>>>> >> +

>>>>>> >> +    if (hpb->is_hcm && ufshpb_issue_umap_single_req(hpb, rgn))

>>>>>> >

>>>>>> > __ufshpb_evict_region() is called with rgn_state_lock held and IRQ

>>>>>> > disabled,

>>>>>> > when ufshpb_issue_umap_single_req() invokes blk_execute_rq_nowait(),

>>>>>> > below

>>>>>> > warning shall pop up every time, fix it?

>>>>>> >

>>>>>> > void blk_execute_rq_nowait(struct request_queue *q, struct gendisk

>>>>>> > *bd_disk,

>>>>>> >                  struct request *rq, int at_head,

>>>>>> >                          rq_end_io_fn *done)

>>>>>> > {

>>>>>> >       WARN_ON(irqs_disabled());

>>>>>> > ...

>>>>>> >

>>>>>> 

>>>>>> Moreover, since we are here with rgn_state_lock held and IRQ

>>>>>> disabled,

>>>>>> in ufshpb_get_req(), rq = kmem_cache_alloc(hpb->map_req_cache,

>>>>>> GFP_KERNEL)

>>>>>> has the GFP_KERNEL flag, scheduling while atomic???

>>>>> I think your comment applies to  ufshpb_issue_umap_all_req as well,

>>>>> Which is called from slave_configure/scsi_add_lun.

>>>>> 

>>>>> Since the host-mode series is utilizing the framework laid by the

>>>>> device-mode,

>>>>> Maybe you can add this comment to  Daejun's last version?

>>>> 

>>>> Hi Avri, Can Guo

>>>> 

>>>> I think ufshpb_issue_umap_single_req() can be moved to end of

>>>> ufshpb_evict_region().

>>>> Then we can avoid rgn_state_lock when it sends unmap command.

>>> 

>>> I am not the expert here, please you two fix it. I am just reporting

>>> what can be wrong. Anyways, ufshpb_issue_umap_single_req() should not

>>> be called with rgn_state_lock held - think about below (another 

>>> deadly)

>>> scenario.

>>> 

>>> lock(rgn_state_lock)

>>>   ufshpb_issue_umap_single_req()

>>>     ufshpb_prep()

>>>        lock(rgn_state_lock)   <---------- recursive spin_lock

>>> 

>>> BTW, @Daejun shouldn't we stop passthrough cmds from stepping

>>> into ufshpb_prep()? In current code, you are trying to use below

>>> check to block cmds other than write/discard/read, but a passthrough

>>> cmd can not be blocked by the check.

>>> 

>>>          if (!ufshpb_is_write_or_discard_cmd(cmd) &&

>>>              !ufshpb_is_read_cmd(cmd) )

>>>                  return 0;

>> 

>> I found this problem too. I fixed it and submit next patch.

> 

>You mean in V30, which has not been uploaded yet, right?


Yes, it is about v30.

Thanks,
Daejun

>Thanks,

>Can Guo.

> 

>> 

>> if (blk_rq_is_scsi(cmd->request) ||

>>             (!ufshpb_is_write_or_discard_cmd(cmd) &&

>>             !ufshpb_is_read_cmd(cmd)))

>>                 return 0;

>> 

>> 

>> Thanks,

>> Daejun

>> 

>>> Thanks,

>>> Can Guo.

>>> 

>>>> 

>>>> Thanks,

>>>> Daejun

>>>> 

>>>> 

>>>>> Thanks,

>>>>> Avri

>>>>> 

>>>>>> 

>>>>>> Can Guo.

>>>>>> 

>>>>>> > Thanks.

>>>>>> > Can Guo.

>>>>>> >

>>>>>> >> +            return;

>>>>>> >> +

>>>>>> >>      lru_info = &hpb->lru_info;

>>>>>> >>

>>>>>> >>      dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "evict region %d\n",

>>>>>> >> rgn->rgn_idx);

>>>>>> >> @@ -1855,6 +1866,7 @@ ufshpb_sysfs_attr_show_func(rb_noti_cnt);

>>>>>> >>  ufshpb_sysfs_attr_show_func(rb_active_cnt);

>>>>>> >>  ufshpb_sysfs_attr_show_func(rb_inactive_cnt);

>>>>>> >>  ufshpb_sysfs_attr_show_func(map_req_cnt);

>>>>>> >> +ufshpb_sysfs_attr_show_func(umap_req_cnt);

>>>>>> >>

>>>>>> >>  static struct attribute *hpb_dev_stat_attrs[] = {

>>>>>> >>      &dev_attr_hit_cnt.attr,

>>>>>> >> @@ -1863,6 +1875,7 @@ static struct attribute *hpb_dev_stat_attrs[] =

>>>>>> >> {

>>>>>> >>      &dev_attr_rb_active_cnt.attr,

>>>>>> >>      &dev_attr_rb_inactive_cnt.attr,

>>>>>> >>      &dev_attr_map_req_cnt.attr,

>>>>>> >> +    &dev_attr_umap_req_cnt.attr,

>>>>>> >>      NULL,

>>>>>> >>  };

>>>>>> >>

>>>>>> >> @@ -1978,6 +1991,7 @@ static void ufshpb_stat_init(struct ufshpb_lu

>>>>>> >> *hpb)

>>>>>> >>      hpb->stats.rb_active_cnt = 0;

>>>>>> >>      hpb->stats.rb_inactive_cnt = 0;

>>>>>> >>      hpb->stats.map_req_cnt = 0;

>>>>>> >> +    hpb->stats.umap_req_cnt = 0;

>>>>>> >>  }

>>>>>> >>

>>>>>> >>  static void ufshpb_param_init(struct ufshpb_lu *hpb)

>>>>>> >> diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h

>>>>>> >> index bd4308010466..84598a317897 100644

>>>>>> >> --- a/drivers/scsi/ufs/ufshpb.h

>>>>>> >> +++ b/drivers/scsi/ufs/ufshpb.h

>>>>>> >> @@ -186,6 +186,7 @@ struct ufshpb_stats {

>>>>>> >>      u64 rb_inactive_cnt;

>>>>>> >>      u64 map_req_cnt;

>>>>>> >>      u64 pre_req_cnt;

>>>>>> >> +    u64 umap_req_cnt;

>>>>>> >>  };

>>>>>> >>

>>>>>> >>  struct ufshpb_lu {

>>>>> 

>>>>> 

>>>>> 

>>> 

>>> 

>>> 

> 

> 

>
Avri Altman March 17, 2021, 7:59 a.m. UTC | #12
> On 2021-03-17 10:28, Daejun Park wrote:

> >>> >> ---

> >>> >>  drivers/scsi/ufs/ufshpb.c | 14 ++++++++++++++

> >>> >>  drivers/scsi/ufs/ufshpb.h |  1 +

> >>> >>  2 files changed, 15 insertions(+)

> >>> >>

> >>> >> diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c

> >>> >> index 6f4fd22eaf2f..0744feb4d484 100644

> >>> >> --- a/drivers/scsi/ufs/ufshpb.c

> >>> >> +++ b/drivers/scsi/ufs/ufshpb.c

> >>> >> @@ -907,6 +907,7 @@ static int ufshpb_execute_umap_req(struct

> >>> >> ufshpb_lu *hpb,

> >>> >>

> >>> >>      blk_execute_rq_nowait(q, NULL, req, 1,

> ufshpb_umap_req_compl_fn);

> >>> >>

> >>> >> +    hpb->stats.umap_req_cnt++;

> >>> >>      return 0;

> >>> >>  }

> >>> >>

> >>> >> @@ -1103,6 +1104,12 @@ static int ufshpb_issue_umap_req(struct

> >>> >> ufshpb_lu *hpb,

> >>> >>      return -EAGAIN;

> >>> >>  }

> >>> >>

> >>> >> +static int ufshpb_issue_umap_single_req(struct ufshpb_lu *hpb,

> >>> >> +                                    struct ufshpb_region *rgn)

> >>> >> +{

> >>> >> +    return ufshpb_issue_umap_req(hpb, rgn);

> >>> >> +}

> >>> >> +

> >>> >>  static int ufshpb_issue_umap_all_req(struct ufshpb_lu *hpb)

> >>> >>  {

> >>> >>      return ufshpb_issue_umap_req(hpb, NULL);

> >>> >> @@ -1115,6 +1122,10 @@ static void __ufshpb_evict_region(struct

> >>> >> ufshpb_lu *hpb,

> >>> >>      struct ufshpb_subregion *srgn;

> >>> >>      int srgn_idx;

> >>> >>

> >>> >> +

> >>> >> +    if (hpb->is_hcm && ufshpb_issue_umap_single_req(hpb, rgn))

> >>> >

> >>> > __ufshpb_evict_region() is called with rgn_state_lock held and IRQ

> >>> > disabled,

> >>> > when ufshpb_issue_umap_single_req() invokes

> blk_execute_rq_nowait(),

> >>> > below

> >>> > warning shall pop up every time, fix it?

> >>> >

> >>> > void blk_execute_rq_nowait(struct request_queue *q, struct gendisk

> >>> > *bd_disk,

> >>> >                  struct request *rq, int at_head,

> >>> >                          rq_end_io_fn *done)

> >>> > {

> >>> >       WARN_ON(irqs_disabled());

> >>> > ...

> >>> >

> >>>

> >>> Moreover, since we are here with rgn_state_lock held and IRQ

> >>> disabled,

> >>> in ufshpb_get_req(), rq = kmem_cache_alloc(hpb->map_req_cache,

> >>> GFP_KERNEL)

> >>> has the GFP_KERNEL flag, scheduling while atomic???

> >> I think your comment applies to  ufshpb_issue_umap_all_req as well,

> >> Which is called from slave_configure/scsi_add_lun.

> >>

> >> Since the host-mode series is utilizing the framework laid by the

> >> device-mode,

> >> Maybe you can add this comment to  Daejun's last version?

> >

> > Hi Avri, Can Guo

> >

> > I think ufshpb_issue_umap_single_req() can be moved to end of

> > ufshpb_evict_region().

> > Then we can avoid rgn_state_lock when it sends unmap command.

> 

> I am not the expert here, please you two fix it. I am just reporting

> what can be wrong. Anyways, ufshpb_issue_umap_single_req() should not

> be called with rgn_state_lock held - think about below (another deadly)

> scenario.

> 

> lock(rgn_state_lock)

>    ufshpb_issue_umap_single_req()

>      ufshpb_prep()

>         lock(rgn_state_lock)   <---------- recursive spin_lock

Will fix.   Will wait for Daejun's v30 to see if anything applies to unmap_single.

Thanks,
Avri 

> 

> BTW, @Daejun shouldn't we stop passthrough cmds from stepping

> into ufshpb_prep()? In current code, you are trying to use below

> check to block cmds other than write/discard/read, but a passthrough

> cmd can not be blocked by the check.

> 

>           if (!ufshpb_is_write_or_discard_cmd(cmd) &&

>               !ufshpb_is_read_cmd(cmd))

>                   return 0;

> 

> Thanks,

> Can Guo.

> 

> >

> > Thanks,

> > Daejun

> >

> >

> >> Thanks,

> >> Avri

> >>

> >>>

> >>> Can Guo.

> >>>

> >>> > Thanks.

> >>> > Can Guo.

> >>> >

> >>> >> +            return;

> >>> >> +

> >>> >>      lru_info = &hpb->lru_info;

> >>> >>

> >>> >>      dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "evict region %d\n",

> >>> >> rgn->rgn_idx);

> >>> >> @@ -1855,6 +1866,7 @@ ufshpb_sysfs_attr_show_func(rb_noti_cnt);

> >>> >>  ufshpb_sysfs_attr_show_func(rb_active_cnt);

> >>> >>  ufshpb_sysfs_attr_show_func(rb_inactive_cnt);

> >>> >>  ufshpb_sysfs_attr_show_func(map_req_cnt);

> >>> >> +ufshpb_sysfs_attr_show_func(umap_req_cnt);

> >>> >>

> >>> >>  static struct attribute *hpb_dev_stat_attrs[] = {

> >>> >>      &dev_attr_hit_cnt.attr,

> >>> >> @@ -1863,6 +1875,7 @@ static struct attribute *hpb_dev_stat_attrs[]

> =

> >>> >> {

> >>> >>      &dev_attr_rb_active_cnt.attr,

> >>> >>      &dev_attr_rb_inactive_cnt.attr,

> >>> >>      &dev_attr_map_req_cnt.attr,

> >>> >> +    &dev_attr_umap_req_cnt.attr,

> >>> >>      NULL,

> >>> >>  };

> >>> >>

> >>> >> @@ -1978,6 +1991,7 @@ static void ufshpb_stat_init(struct ufshpb_lu

> >>> >> *hpb)

> >>> >>      hpb->stats.rb_active_cnt = 0;

> >>> >>      hpb->stats.rb_inactive_cnt = 0;

> >>> >>      hpb->stats.map_req_cnt = 0;

> >>> >> +    hpb->stats.umap_req_cnt = 0;

> >>> >>  }

> >>> >>

> >>> >>  static void ufshpb_param_init(struct ufshpb_lu *hpb)

> >>> >> diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h

> >>> >> index bd4308010466..84598a317897 100644

> >>> >> --- a/drivers/scsi/ufs/ufshpb.h

> >>> >> +++ b/drivers/scsi/ufs/ufshpb.h

> >>> >> @@ -186,6 +186,7 @@ struct ufshpb_stats {

> >>> >>      u64 rb_inactive_cnt;

> >>> >>      u64 map_req_cnt;

> >>> >>      u64 pre_req_cnt;

> >>> >> +    u64 umap_req_cnt;

> >>> >>  };

> >>> >>

> >>> >>  struct ufshpb_lu {

> >>

> >>

> >>
diff mbox series

Patch

diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
index 6f4fd22eaf2f..0744feb4d484 100644
--- a/drivers/scsi/ufs/ufshpb.c
+++ b/drivers/scsi/ufs/ufshpb.c
@@ -907,6 +907,7 @@  static int ufshpb_execute_umap_req(struct ufshpb_lu *hpb,
 
 	blk_execute_rq_nowait(q, NULL, req, 1, ufshpb_umap_req_compl_fn);
 
+	hpb->stats.umap_req_cnt++;
 	return 0;
 }
 
@@ -1103,6 +1104,12 @@  static int ufshpb_issue_umap_req(struct ufshpb_lu *hpb,
 	return -EAGAIN;
 }
 
+static int ufshpb_issue_umap_single_req(struct ufshpb_lu *hpb,
+					struct ufshpb_region *rgn)
+{
+	return ufshpb_issue_umap_req(hpb, rgn);
+}
+
 static int ufshpb_issue_umap_all_req(struct ufshpb_lu *hpb)
 {
 	return ufshpb_issue_umap_req(hpb, NULL);
@@ -1115,6 +1122,10 @@  static void __ufshpb_evict_region(struct ufshpb_lu *hpb,
 	struct ufshpb_subregion *srgn;
 	int srgn_idx;
 
+
+	if (hpb->is_hcm && ufshpb_issue_umap_single_req(hpb, rgn))
+		return;
+
 	lru_info = &hpb->lru_info;
 
 	dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "evict region %d\n", rgn->rgn_idx);
@@ -1855,6 +1866,7 @@  ufshpb_sysfs_attr_show_func(rb_noti_cnt);
 ufshpb_sysfs_attr_show_func(rb_active_cnt);
 ufshpb_sysfs_attr_show_func(rb_inactive_cnt);
 ufshpb_sysfs_attr_show_func(map_req_cnt);
+ufshpb_sysfs_attr_show_func(umap_req_cnt);
 
 static struct attribute *hpb_dev_stat_attrs[] = {
 	&dev_attr_hit_cnt.attr,
@@ -1863,6 +1875,7 @@  static struct attribute *hpb_dev_stat_attrs[] = {
 	&dev_attr_rb_active_cnt.attr,
 	&dev_attr_rb_inactive_cnt.attr,
 	&dev_attr_map_req_cnt.attr,
+	&dev_attr_umap_req_cnt.attr,
 	NULL,
 };
 
@@ -1978,6 +1991,7 @@  static void ufshpb_stat_init(struct ufshpb_lu *hpb)
 	hpb->stats.rb_active_cnt = 0;
 	hpb->stats.rb_inactive_cnt = 0;
 	hpb->stats.map_req_cnt = 0;
+	hpb->stats.umap_req_cnt = 0;
 }
 
 static void ufshpb_param_init(struct ufshpb_lu *hpb)
diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h
index bd4308010466..84598a317897 100644
--- a/drivers/scsi/ufs/ufshpb.h
+++ b/drivers/scsi/ufs/ufshpb.h
@@ -186,6 +186,7 @@  struct ufshpb_stats {
 	u64 rb_inactive_cnt;
 	u64 map_req_cnt;
 	u64 pre_req_cnt;
+	u64 umap_req_cnt;
 };
 
 struct ufshpb_lu {