diff mbox series

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

Message ID 20210302132503.224670-6-avri.altman@wdc.com (mailing list archive)
State Superseded
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 {