RE: [PATCH v7 06/11] scsi: ufshpb: Region inactivation in host mode

2021-04-09 Thread Avri Altman


> > >> On 2021-04-06 13:20, Avri Altman wrote:
> > >> >> > -static void __ufshpb_evict_region(struct ufshpb_lu *hpb,
> > >> >> > -   struct ufshpb_region *rgn)
> > >> >> > +static int __ufshpb_evict_region(struct ufshpb_lu *hpb,
> > >> >> > +  struct ufshpb_region *rgn)
> > >> >> >  {
> > >> >> >   struct victim_select_info *lru_info;
> > >> >> >   struct ufshpb_subregion *srgn;
> > >> >> >   int srgn_idx;
> > >> >> >
> > >> >> > + lockdep_assert_held(>rgn_state_lock);
> > >> >> > +
> > >> >> > + if (hpb->is_hcm) {
> > >> >> > + unsigned long flags;
> > >> >> > + int ret;
> > >> >> > +
> > >> >> > + spin_unlock_irqrestore(>rgn_state_lock, flags);
> > >> >>
> > >> >> Never seen a usage like this... Here flags is used without being
> > >> >> intialized.
> > >> >> The flag is needed when spin_unlock_irqrestore ->
> > >> >> local_irq_restore(flags) to
> > >> >> restore the DAIF register (in terms of ARM).
> > >> > OK.
> > >>
> > >> Hi Avri,
> > >>
> > >> Checked on my setup, this lead to compilation error. Will you fix it
> > >> in
> > >> next version?
> > >>
> > >> warning: variable 'flags' is uninitialized when used here
> > >> [-Wuninitialized]
> > > Yeah - I will pass it to __ufshpb_evict_region and drop the
> > > lockdep_assert call.
Please ignore it.  This of course won't do.
Will fix it in v8.

Thanks,
Avri


RE: [PATCH v7 06/11] scsi: ufshpb: Region inactivation in host mode

2021-04-06 Thread Avri Altman
> >>
> >> On 2021-04-06 13:20, Avri Altman wrote:
> >> >> > -static void __ufshpb_evict_region(struct ufshpb_lu *hpb,
> >> >> > -   struct ufshpb_region *rgn)
> >> >> > +static int __ufshpb_evict_region(struct ufshpb_lu *hpb,
> >> >> > +  struct ufshpb_region *rgn)
> >> >> >  {
> >> >> >   struct victim_select_info *lru_info;
> >> >> >   struct ufshpb_subregion *srgn;
> >> >> >   int srgn_idx;
> >> >> >
> >> >> > + lockdep_assert_held(>rgn_state_lock);
> >> >> > +
> >> >> > + if (hpb->is_hcm) {
> >> >> > + unsigned long flags;
> >> >> > + int ret;
> >> >> > +
> >> >> > + spin_unlock_irqrestore(>rgn_state_lock, flags);
> >> >>
> >> >> Never seen a usage like this... Here flags is used without being
> >> >> intialized.
> >> >> The flag is needed when spin_unlock_irqrestore ->
> >> >> local_irq_restore(flags) to
> >> >> restore the DAIF register (in terms of ARM).
> >> > OK.
> >>
> >> Hi Avri,
> >>
> >> Checked on my setup, this lead to compilation error. Will you fix it
> >> in
> >> next version?
> >>
> >> warning: variable 'flags' is uninitialized when used here
> >> [-Wuninitialized]
> > Yeah - I will pass it to __ufshpb_evict_region and drop the
> > lockdep_assert call.
> >
> 
> Please paste the sample code/change here so that I can move forward
> quickly.
Thanks a lot.  Also attaching the patch if its more convenient.

Thanks,
Avri

$ git show 5d33d36e8704
commit 5d33d36e87047d27a546ad3529cb7837186b47b2
Author: Avri Altman 
Date:   Tue Jun 30 15:14:31 2020 +0300

scsi: ufshpb: Region inactivation in host mode

In 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 
Reviewed-by: Daejun Park 
Change-Id: I1a6696b38d4abfb4d9fbe44e84016a6238825125

diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
index aefb6dc160ee..54a3ea9f5732 100644
--- a/drivers/scsi/ufs/ufshpb.c
+++ b/drivers/scsi/ufs/ufshpb.c
@@ -914,6 +914,7 @@ static int ufshpb_execute_umap_req(struct ufshpb_lu *hpb,
 
blk_execute_rq_nowait(NULL, req, 1, ufshpb_umap_req_compl_fn);
 
+   hpb->stats.umap_req_cnt++;
return 0;
 }
 
@@ -1110,18 +,35 @@ 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);
 }
 
-static void __ufshpb_evict_region(struct ufshpb_lu *hpb,
- struct ufshpb_region *rgn)
+static int __ufshpb_evict_region(struct ufshpb_lu *hpb,
+struct ufshpb_region *rgn,
+unsigned long flags)
 {
struct victim_select_info *lru_info;
struct ufshpb_subregion *srgn;
int srgn_idx;
 
+   if (hpb->is_hcm) {
+   int ret;
+
+   spin_unlock_irqrestore(>rgn_state_lock, flags);
+   ret = ufshpb_issue_umap_single_req(hpb, rgn);
+   spin_lock_irqsave(>rgn_state_lock, flags);
+   if (ret)
+   return ret;
+   }
+
lru_info = >lru_info;
 
dev_dbg(>sdev_ufs_lu->sdev_dev, "evict region %d\n", rgn->rgn_idx);
@@ -1130,6 +1148,8 @@ static void __ufshpb_evict_region(struct ufshpb_lu *hpb,
 
for_each_sub_region(rgn, srgn_idx, srgn)
ufshpb_purge_active_subregion(hpb, srgn);
+
+   return 0;
 }
 
 static int ufshpb_evict_region(struct ufshpb_lu *hpb, struct ufshpb_region 
*rgn)
@@ -1151,7 +1171,7 @@ static int ufshpb_evict_region(struct ufshpb_lu *hpb, 
struct ufshpb_region *rgn)
goto out;
}
 
-   __ufshpb_evict_region(hpb, rgn);
+   ret = __ufshpb_evict_region(hpb, rgn, flags);
}
 out:
spin_unlock_irqrestore(>rgn_state_lock, flags);
@@ -1285,7 +1305,9 @@ static int ufshpb_add_region(struct ufshpb_lu *hpb, 
struct ufshpb_region *rgn)
"LRU full (%d), choose victim %d\n",
atomic_read(_info->active_cnt),
victim_rgn->rgn_idx);
-   __ufshpb_evict_region(hpb, victim_rgn);
+   ret = __ufshpb_evict_region(hpb, victim_rgn, flags);
+   if (ret)
+   goto out;
}
 
/*
@@ -1856,6 +1878,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);
 

Re: [PATCH v7 06/11] scsi: ufshpb: Region inactivation in host mode

2021-04-06 Thread Can Guo

On 2021-04-06 14:16, Avri Altman wrote:


On 2021-04-06 13:20, Avri Altman wrote:
>> > -static void __ufshpb_evict_region(struct ufshpb_lu *hpb,
>> > -   struct ufshpb_region *rgn)
>> > +static int __ufshpb_evict_region(struct ufshpb_lu *hpb,
>> > +  struct ufshpb_region *rgn)
>> >  {
>> >   struct victim_select_info *lru_info;
>> >   struct ufshpb_subregion *srgn;
>> >   int srgn_idx;
>> >
>> > + lockdep_assert_held(>rgn_state_lock);
>> > +
>> > + if (hpb->is_hcm) {
>> > + unsigned long flags;
>> > + int ret;
>> > +
>> > + spin_unlock_irqrestore(>rgn_state_lock, flags);
>>
>> Never seen a usage like this... Here flags is used without being
>> intialized.
>> The flag is needed when spin_unlock_irqrestore ->
>> local_irq_restore(flags) to
>> restore the DAIF register (in terms of ARM).
> OK.

Hi Avri,

Checked on my setup, this lead to compilation error. Will you fix it 
in

next version?

warning: variable 'flags' is uninitialized when used here
[-Wuninitialized]
Yeah - I will pass it to __ufshpb_evict_region and drop the 
lockdep_assert call.




Please paste the sample code/change here so that I can move forward 
quickly.



I don't want to block your testing - are there any other things you
want me to change?


Currently, no. I will try to review and test this series these days and
post comments at once.

Thanks,
Can Guo.



Thanks,
Avri



Thanks,
Can Guo.

>
> Thanks,
> Avri
>
>>
>> Thanks,
>>
>> Can Guo.
>>
>> > + ret = ufshpb_issue_umap_single_req(hpb, rgn);
>> > + spin_lock_irqsave(>rgn_state_lock, flags);
>> > + if (ret)
>> > + return ret;
>> > + }
>> > +
>> >   lru_info = >lru_info;
>> >
>> >   dev_dbg(>sdev_ufs_lu->sdev_dev, "evict region %d\n",
>> > rgn->rgn_idx);
>> > @@ -1130,6 +1150,8 @@ static void __ufshpb_evict_region(struct
>> > ufshpb_lu *hpb,
>> >
>> >   for_each_sub_region(rgn, srgn_idx, srgn)
>> >   ufshpb_purge_active_subregion(hpb, srgn);
>> > +
>> > + return 0;
>> >  }
>> >
>> >  static int ufshpb_evict_region(struct ufshpb_lu *hpb, struct
>> > ufshpb_region *rgn)
>> > @@ -1151,7 +1173,7 @@ static int ufshpb_evict_region(struct ufshpb_lu
>> > *hpb, struct ufshpb_region *rgn)
>> >   goto out;
>> >   }
>> >
>> > - __ufshpb_evict_region(hpb, rgn);
>> > + ret = __ufshpb_evict_region(hpb, rgn);
>> >   }
>> >  out:
>> >   spin_unlock_irqrestore(>rgn_state_lock, flags);
>> > @@ -1285,7 +1307,9 @@ static int ufshpb_add_region(struct ufshpb_lu
>> > *hpb, struct ufshpb_region *rgn)
>> >   "LRU full (%d), choose victim %d\n",
>> >   atomic_read(_info->active_cnt),
>> >   victim_rgn->rgn_idx);
>> > - __ufshpb_evict_region(hpb, victim_rgn);
>> > + ret = __ufshpb_evict_region(hpb, victim_rgn);
>> > + if (ret)
>> > + goto out;
>> >   }
>> >
>> >   /*
>> > @@ -1856,6 +1880,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[] = {
>> >   _attr_hit_cnt.attr,
>> > @@ -1864,6 +1889,7 @@ static struct attribute *hpb_dev_stat_attrs[] = {
>> >   _attr_rb_active_cnt.attr,
>> >   _attr_rb_inactive_cnt.attr,
>> >   _attr_map_req_cnt.attr,
>> > + _attr_umap_req_cnt.attr,
>> >   NULL,
>> >  };
>> >
>> > @@ -1988,6 +2014,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 87495e59fcf1..1ea58c17a4de 100644
>> > --- a/drivers/scsi/ufs/ufshpb.h
>> > +++ b/drivers/scsi/ufs/ufshpb.h
>> > @@ -191,6 +191,7 @@ struct ufshpb_stats {
>> >   u64 rb_inactive_cnt;
>> >   u64 map_req_cnt;
>> >   u64 pre_req_cnt;
>> > + u64 umap_req_cnt;
>> >  };
>> >
>> >  struct ufshpb_lu {


RE: [PATCH v7 06/11] scsi: ufshpb: Region inactivation in host mode

2021-04-06 Thread Avri Altman
 
> 
> On 2021-04-06 13:20, Avri Altman wrote:
> >> > -static void __ufshpb_evict_region(struct ufshpb_lu *hpb,
> >> > -   struct ufshpb_region *rgn)
> >> > +static int __ufshpb_evict_region(struct ufshpb_lu *hpb,
> >> > +  struct ufshpb_region *rgn)
> >> >  {
> >> >   struct victim_select_info *lru_info;
> >> >   struct ufshpb_subregion *srgn;
> >> >   int srgn_idx;
> >> >
> >> > + lockdep_assert_held(>rgn_state_lock);
> >> > +
> >> > + if (hpb->is_hcm) {
> >> > + unsigned long flags;
> >> > + int ret;
> >> > +
> >> > + spin_unlock_irqrestore(>rgn_state_lock, flags);
> >>
> >> Never seen a usage like this... Here flags is used without being
> >> intialized.
> >> The flag is needed when spin_unlock_irqrestore ->
> >> local_irq_restore(flags) to
> >> restore the DAIF register (in terms of ARM).
> > OK.
> 
> Hi Avri,
> 
> Checked on my setup, this lead to compilation error. Will you fix it in
> next version?
> 
> warning: variable 'flags' is uninitialized when used here
> [-Wuninitialized]
Yeah - I will pass it to __ufshpb_evict_region and drop the lockdep_assert call.

I don't want to block your testing - are there any other things you want me to 
change?

Thanks,
Avri

> 
> Thanks,
> Can Guo.
> 
> >
> > Thanks,
> > Avri
> >
> >>
> >> Thanks,
> >>
> >> Can Guo.
> >>
> >> > + ret = ufshpb_issue_umap_single_req(hpb, rgn);
> >> > + spin_lock_irqsave(>rgn_state_lock, flags);
> >> > + if (ret)
> >> > + return ret;
> >> > + }
> >> > +
> >> >   lru_info = >lru_info;
> >> >
> >> >   dev_dbg(>sdev_ufs_lu->sdev_dev, "evict region %d\n",
> >> > rgn->rgn_idx);
> >> > @@ -1130,6 +1150,8 @@ static void __ufshpb_evict_region(struct
> >> > ufshpb_lu *hpb,
> >> >
> >> >   for_each_sub_region(rgn, srgn_idx, srgn)
> >> >   ufshpb_purge_active_subregion(hpb, srgn);
> >> > +
> >> > + return 0;
> >> >  }
> >> >
> >> >  static int ufshpb_evict_region(struct ufshpb_lu *hpb, struct
> >> > ufshpb_region *rgn)
> >> > @@ -1151,7 +1173,7 @@ static int ufshpb_evict_region(struct ufshpb_lu
> >> > *hpb, struct ufshpb_region *rgn)
> >> >   goto out;
> >> >   }
> >> >
> >> > - __ufshpb_evict_region(hpb, rgn);
> >> > + ret = __ufshpb_evict_region(hpb, rgn);
> >> >   }
> >> >  out:
> >> >   spin_unlock_irqrestore(>rgn_state_lock, flags);
> >> > @@ -1285,7 +1307,9 @@ static int ufshpb_add_region(struct ufshpb_lu
> >> > *hpb, struct ufshpb_region *rgn)
> >> >   "LRU full (%d), choose victim %d\n",
> >> >   atomic_read(_info->active_cnt),
> >> >   victim_rgn->rgn_idx);
> >> > - __ufshpb_evict_region(hpb, victim_rgn);
> >> > + ret = __ufshpb_evict_region(hpb, victim_rgn);
> >> > + if (ret)
> >> > + goto out;
> >> >   }
> >> >
> >> >   /*
> >> > @@ -1856,6 +1880,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[] = {
> >> >   _attr_hit_cnt.attr,
> >> > @@ -1864,6 +1889,7 @@ static struct attribute *hpb_dev_stat_attrs[] = {
> >> >   _attr_rb_active_cnt.attr,
> >> >   _attr_rb_inactive_cnt.attr,
> >> >   _attr_map_req_cnt.attr,
> >> > + _attr_umap_req_cnt.attr,
> >> >   NULL,
> >> >  };
> >> >
> >> > @@ -1988,6 +2014,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 87495e59fcf1..1ea58c17a4de 100644
> >> > --- a/drivers/scsi/ufs/ufshpb.h
> >> > +++ b/drivers/scsi/ufs/ufshpb.h
> >> > @@ -191,6 +191,7 @@ struct ufshpb_stats {
> >> >   u64 rb_inactive_cnt;
> >> >   u64 map_req_cnt;
> >> >   u64 pre_req_cnt;
> >> > + u64 umap_req_cnt;
> >> >  };
> >> >
> >> >  struct ufshpb_lu {


Re: [PATCH v7 06/11] scsi: ufshpb: Region inactivation in host mode

2021-04-06 Thread Can Guo

On 2021-04-06 13:20, Avri Altman wrote:

> -static void __ufshpb_evict_region(struct ufshpb_lu *hpb,
> -   struct ufshpb_region *rgn)
> +static int __ufshpb_evict_region(struct ufshpb_lu *hpb,
> +  struct ufshpb_region *rgn)
>  {
>   struct victim_select_info *lru_info;
>   struct ufshpb_subregion *srgn;
>   int srgn_idx;
>
> + lockdep_assert_held(>rgn_state_lock);
> +
> + if (hpb->is_hcm) {
> + unsigned long flags;
> + int ret;
> +
> + spin_unlock_irqrestore(>rgn_state_lock, flags);

Never seen a usage like this... Here flags is used without being
intialized.
The flag is needed when spin_unlock_irqrestore ->
local_irq_restore(flags) to
restore the DAIF register (in terms of ARM).

OK.


Hi Avri,

Checked on my setup, this lead to compilation error. Will you fix it in 
next version?


warning: variable 'flags' is uninitialized when used here 
[-Wuninitialized]


Thanks,
Can Guo.



Thanks,
Avri



Thanks,

Can Guo.

> + ret = ufshpb_issue_umap_single_req(hpb, rgn);
> + spin_lock_irqsave(>rgn_state_lock, flags);
> + if (ret)
> + return ret;
> + }
> +
>   lru_info = >lru_info;
>
>   dev_dbg(>sdev_ufs_lu->sdev_dev, "evict region %d\n",
> rgn->rgn_idx);
> @@ -1130,6 +1150,8 @@ static void __ufshpb_evict_region(struct
> ufshpb_lu *hpb,
>
>   for_each_sub_region(rgn, srgn_idx, srgn)
>   ufshpb_purge_active_subregion(hpb, srgn);
> +
> + return 0;
>  }
>
>  static int ufshpb_evict_region(struct ufshpb_lu *hpb, struct
> ufshpb_region *rgn)
> @@ -1151,7 +1173,7 @@ static int ufshpb_evict_region(struct ufshpb_lu
> *hpb, struct ufshpb_region *rgn)
>   goto out;
>   }
>
> - __ufshpb_evict_region(hpb, rgn);
> + ret = __ufshpb_evict_region(hpb, rgn);
>   }
>  out:
>   spin_unlock_irqrestore(>rgn_state_lock, flags);
> @@ -1285,7 +1307,9 @@ static int ufshpb_add_region(struct ufshpb_lu
> *hpb, struct ufshpb_region *rgn)
>   "LRU full (%d), choose victim %d\n",
>   atomic_read(_info->active_cnt),
>   victim_rgn->rgn_idx);
> - __ufshpb_evict_region(hpb, victim_rgn);
> + ret = __ufshpb_evict_region(hpb, victim_rgn);
> + if (ret)
> + goto out;
>   }
>
>   /*
> @@ -1856,6 +1880,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[] = {
>   _attr_hit_cnt.attr,
> @@ -1864,6 +1889,7 @@ static struct attribute *hpb_dev_stat_attrs[] = {
>   _attr_rb_active_cnt.attr,
>   _attr_rb_inactive_cnt.attr,
>   _attr_map_req_cnt.attr,
> + _attr_umap_req_cnt.attr,
>   NULL,
>  };
>
> @@ -1988,6 +2014,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 87495e59fcf1..1ea58c17a4de 100644
> --- a/drivers/scsi/ufs/ufshpb.h
> +++ b/drivers/scsi/ufs/ufshpb.h
> @@ -191,6 +191,7 @@ struct ufshpb_stats {
>   u64 rb_inactive_cnt;
>   u64 map_req_cnt;
>   u64 pre_req_cnt;
> + u64 umap_req_cnt;
>  };
>
>  struct ufshpb_lu {


RE: [PATCH v7 06/11] scsi: ufshpb: Region inactivation in host mode

2021-04-05 Thread Avri Altman
> > -static void __ufshpb_evict_region(struct ufshpb_lu *hpb,
> > -   struct ufshpb_region *rgn)
> > +static int __ufshpb_evict_region(struct ufshpb_lu *hpb,
> > +  struct ufshpb_region *rgn)
> >  {
> >   struct victim_select_info *lru_info;
> >   struct ufshpb_subregion *srgn;
> >   int srgn_idx;
> >
> > + lockdep_assert_held(>rgn_state_lock);
> > +
> > + if (hpb->is_hcm) {
> > + unsigned long flags;
> > + int ret;
> > +
> > + spin_unlock_irqrestore(>rgn_state_lock, flags);
> 
> Never seen a usage like this... Here flags is used without being
> intialized.
> The flag is needed when spin_unlock_irqrestore ->
> local_irq_restore(flags) to
> restore the DAIF register (in terms of ARM).
OK.

Thanks,
Avri

> 
> Thanks,
> 
> Can Guo.
> 
> > + ret = ufshpb_issue_umap_single_req(hpb, rgn);
> > + spin_lock_irqsave(>rgn_state_lock, flags);
> > + if (ret)
> > + return ret;
> > + }
> > +
> >   lru_info = >lru_info;
> >
> >   dev_dbg(>sdev_ufs_lu->sdev_dev, "evict region %d\n",
> > rgn->rgn_idx);
> > @@ -1130,6 +1150,8 @@ static void __ufshpb_evict_region(struct
> > ufshpb_lu *hpb,
> >
> >   for_each_sub_region(rgn, srgn_idx, srgn)
> >   ufshpb_purge_active_subregion(hpb, srgn);
> > +
> > + return 0;
> >  }
> >
> >  static int ufshpb_evict_region(struct ufshpb_lu *hpb, struct
> > ufshpb_region *rgn)
> > @@ -1151,7 +1173,7 @@ static int ufshpb_evict_region(struct ufshpb_lu
> > *hpb, struct ufshpb_region *rgn)
> >   goto out;
> >   }
> >
> > - __ufshpb_evict_region(hpb, rgn);
> > + ret = __ufshpb_evict_region(hpb, rgn);
> >   }
> >  out:
> >   spin_unlock_irqrestore(>rgn_state_lock, flags);
> > @@ -1285,7 +1307,9 @@ static int ufshpb_add_region(struct ufshpb_lu
> > *hpb, struct ufshpb_region *rgn)
> >   "LRU full (%d), choose victim %d\n",
> >   atomic_read(_info->active_cnt),
> >   victim_rgn->rgn_idx);
> > - __ufshpb_evict_region(hpb, victim_rgn);
> > + ret = __ufshpb_evict_region(hpb, victim_rgn);
> > + if (ret)
> > + goto out;
> >   }
> >
> >   /*
> > @@ -1856,6 +1880,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[] = {
> >   _attr_hit_cnt.attr,
> > @@ -1864,6 +1889,7 @@ static struct attribute *hpb_dev_stat_attrs[] = {
> >   _attr_rb_active_cnt.attr,
> >   _attr_rb_inactive_cnt.attr,
> >   _attr_map_req_cnt.attr,
> > + _attr_umap_req_cnt.attr,
> >   NULL,
> >  };
> >
> > @@ -1988,6 +2014,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 87495e59fcf1..1ea58c17a4de 100644
> > --- a/drivers/scsi/ufs/ufshpb.h
> > +++ b/drivers/scsi/ufs/ufshpb.h
> > @@ -191,6 +191,7 @@ struct ufshpb_stats {
> >   u64 rb_inactive_cnt;
> >   u64 map_req_cnt;
> >   u64 pre_req_cnt;
> > + u64 umap_req_cnt;
> >  };
> >
> >  struct ufshpb_lu {


Re: [PATCH v7 06/11] scsi: ufshpb: Region inactivation in host mode

2021-04-05 Thread Can Guo

On 2021-03-31 15:39, Avri Altman wrote:

In 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 
---
 drivers/scsi/ufs/ufshpb.c | 35 +++
 drivers/scsi/ufs/ufshpb.h |  1 +
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
index aefb6dc160ee..fcc954f51bcf 100644
--- a/drivers/scsi/ufs/ufshpb.c
+++ b/drivers/scsi/ufs/ufshpb.c
@@ -914,6 +914,7 @@ static int ufshpb_execute_umap_req(struct ufshpb_lu 
*hpb,


blk_execute_rq_nowait(NULL, req, 1, ufshpb_umap_req_compl_fn);

+   hpb->stats.umap_req_cnt++;
return 0;
 }

@@ -1110,18 +,37 @@ 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);
 }

-static void __ufshpb_evict_region(struct ufshpb_lu *hpb,
- struct ufshpb_region *rgn)
+static int __ufshpb_evict_region(struct ufshpb_lu *hpb,
+struct ufshpb_region *rgn)
 {
struct victim_select_info *lru_info;
struct ufshpb_subregion *srgn;
int srgn_idx;

+   lockdep_assert_held(>rgn_state_lock);
+
+   if (hpb->is_hcm) {
+   unsigned long flags;
+   int ret;
+
+   spin_unlock_irqrestore(>rgn_state_lock, flags);


Never seen a usage like this... Here flags is used without being 
intialized.
The flag is needed when spin_unlock_irqrestore -> 
local_irq_restore(flags) to

restore the DAIF register (in terms of ARM).

Thanks,

Can Guo.


+   ret = ufshpb_issue_umap_single_req(hpb, rgn);
+   spin_lock_irqsave(>rgn_state_lock, flags);
+   if (ret)
+   return ret;
+   }
+
lru_info = >lru_info;

 	dev_dbg(>sdev_ufs_lu->sdev_dev, "evict region %d\n", 
rgn->rgn_idx);
@@ -1130,6 +1150,8 @@ static void __ufshpb_evict_region(struct 
ufshpb_lu *hpb,


for_each_sub_region(rgn, srgn_idx, srgn)
ufshpb_purge_active_subregion(hpb, srgn);
+
+   return 0;
 }

 static int ufshpb_evict_region(struct ufshpb_lu *hpb, struct
ufshpb_region *rgn)
@@ -1151,7 +1173,7 @@ static int ufshpb_evict_region(struct ufshpb_lu
*hpb, struct ufshpb_region *rgn)
goto out;
}

-   __ufshpb_evict_region(hpb, rgn);
+   ret = __ufshpb_evict_region(hpb, rgn);
}
 out:
spin_unlock_irqrestore(>rgn_state_lock, flags);
@@ -1285,7 +1307,9 @@ static int ufshpb_add_region(struct ufshpb_lu
*hpb, struct ufshpb_region *rgn)
"LRU full (%d), choose victim %d\n",
atomic_read(_info->active_cnt),
victim_rgn->rgn_idx);
-   __ufshpb_evict_region(hpb, victim_rgn);
+   ret = __ufshpb_evict_region(hpb, victim_rgn);
+   if (ret)
+   goto out;
}

/*
@@ -1856,6 +1880,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[] = {
_attr_hit_cnt.attr,
@@ -1864,6 +1889,7 @@ static struct attribute *hpb_dev_stat_attrs[] = {
_attr_rb_active_cnt.attr,
_attr_rb_inactive_cnt.attr,
_attr_map_req_cnt.attr,
+   _attr_umap_req_cnt.attr,
NULL,
 };

@@ -1988,6 +2014,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 87495e59fcf1..1ea58c17a4de 100644
--- a/drivers/scsi/ufs/ufshpb.h
+++ b/drivers/scsi/ufs/ufshpb.h
@@ -191,6 +191,7 @@ struct ufshpb_stats {
u64 rb_inactive_cnt;
u64 map_req_cnt;
u64 pre_req_cnt;
+   u64 umap_req_cnt;
 };

 struct ufshpb_lu {