RE: Re: [PATCH v26 2/4] scsi: ufs: L2P map management for HPB read

2021-03-14 Thread Daejun Park
> > This is a patch for managing L2P map in HPB module.
> >
> > The HPB divides logical addresses into several regions. A region
> > consists
> > of several sub-regions. The sub-region is a basic unit where L2P
> > mapping is
> > managed. The driver loads L2P mapping data of each sub-region. The
> > loaded
> > sub-region is called active-state. The HPB driver unloads L2P mapping
> > data
> > as region unit. The unloaded region is called inactive-state.
> >
> > Sub-region/region candidates to be loaded and unloaded are delivered
> > from
> > the UFS device. The UFS device delivers the recommended active
> > sub-region
> > and inactivate region to the driver using sensedata.
> > The HPB module performs L2P mapping management on the host through the
> > delivered information.
> >
> > A pinned region is a pre-set regions on the UFS device that is always
> > activate-state.
> >
> > The data structure for map data request and L2P map uses mempool API,
> > minimizing allocation overhead while avoiding static allocation.
> >
> > The mininum size of the memory pool used in the HPB is implemented
> > as a module parameter, so that it can be configurable by the user.
> >
> > To gurantee a minimum memory pool size of 4MB:
> > ufshpb_host_map_kbytes=4096
> >
> > The map_work manages active/inactive by 2 "to-do" lists.
> > Each hpb lun maintains 2 "to-do" lists:
> >   hpb->lh_inact_rgn - regions to be inactivated, and
> >   hpb->lh_act_srgn - subregions to be activated
> > Those lists are maintained on IO completion.
> >
> > Reviewed-by: Bart Van Assche 
> > Reviewed-by: Can Guo 
> > Acked-by: Avri Altman 
> > Tested-by: Bean Huo 
> > Signed-off-by: Daejun Park 
> > ---
> >  drivers/scsi/ufs/ufs.h|   36 ++
> >  drivers/scsi/ufs/ufshcd.c |4 +
> >  drivers/scsi/ufs/ufshpb.c | 1091 -
> >  drivers/scsi/ufs/ufshpb.h |   65 +++
> >  4 files changed, 1181 insertions(+), 15 deletions(-)
> >
> > diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
> > index 65563635e20e..957763db1006 100644
> > --- a/drivers/scsi/ufs/ufs.h
> > +++ b/drivers/scsi/ufs/ufs.h
> > @@ -472,6 +472,41 @@ struct utp_cmd_rsp {
> >  u8 sense_data[UFS_SENSE_SIZE];
> >  };
> >
> > +struct ufshpb_active_field {
> > +__be16 active_rgn;
> > +__be16 active_srgn;
> > +};
> > +#define HPB_ACT_FIELD_SIZE 4
> > +
> > +/**
> > + * struct utp_hpb_rsp - Response UPIU structure
> > + * @residual_transfer_count: Residual transfer count DW-3
> > + * @reserved1: Reserved double words DW-4 to DW-7
> > + * @sense_data_len: Sense data length DW-8 U16
> > + * @desc_type: Descriptor type of sense data
> > + * @additional_len: Additional length of sense data
> > + * @hpb_op: HPB operation type
> > + * @lun: LUN of response UPIU
> > + * @active_rgn_cnt: Active region count
> > + * @inactive_rgn_cnt: Inactive region count
> > + * @hpb_active_field: Recommended to read HPB region and subregion
> > + * @hpb_inactive_field: To be inactivated HPB region and subregion
> > + */
> > +struct utp_hpb_rsp {
> > +__be32 residual_transfer_count;
> > +__be32 reserved1[4];
> > +__be16 sense_data_len;
> > +u8 desc_type;
> > +u8 additional_len;
> > +u8 hpb_op;
> > +u8 lun;
> > +u8 active_rgn_cnt;
> > +u8 inactive_rgn_cnt;
> > +struct ufshpb_active_field hpb_active_field[2];
> > +__be16 hpb_inactive_field[2];
> > +};
> > +#define UTP_HPB_RSP_SIZE 40
> > +
> >  /**
> >   * struct utp_upiu_rsp - general upiu response structure
> >   * @header: UPIU header structure DW-0 to DW-2
> > @@ -482,6 +517,7 @@ struct utp_upiu_rsp {
> >  struct utp_upiu_header header;
> >  union {
> >  struct utp_cmd_rsp sr;
> > +struct utp_hpb_rsp hr;
> >  struct utp_upiu_query qr;
> >  };
> >  };
> > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> > index 49b3d5d24fa6..5852ff44c3cc 100644
> > --- a/drivers/scsi/ufs/ufshcd.c
> > +++ b/drivers/scsi/ufs/ufshcd.c
> > @@ -5021,6 +5021,9 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba,
> > struct ufshcd_lrb *lrbp)
> >   */
> >  pm_runtime_get_noresume(hba->dev);
> >  }
> > +
> > +if (scsi_status == SAM_STAT_GOOD)
> > +ufshpb_rsp_upiu(hba, lrbp);
> >  break;
> >  case 

Re: [PATCH v26 2/4] scsi: ufs: L2P map management for HPB read

2021-03-14 Thread Can Guo

On 2021-03-12 15:17, Daejun Park wrote:

> This is a patch for managing L2P map in HPB module.
>
> The HPB divides logical addresses into several regions. A region
> consists
> of several sub-regions. The sub-region is a basic unit where L2P
> mapping is
> managed. The driver loads L2P mapping data of each sub-region. The
> loaded
> sub-region is called active-state. The HPB driver unloads L2P mapping
> data
> as region unit. The unloaded region is called inactive-state.
>
> Sub-region/region candidates to be loaded and unloaded are delivered
> from
> the UFS device. The UFS device delivers the recommended active
> sub-region
> and inactivate region to the driver using sensedata.
> The HPB module performs L2P mapping management on the host through the
> delivered information.
>
> A pinned region is a pre-set regions on the UFS device that is always
> activate-state.
>
> The data structure for map data request and L2P map uses mempool API,
> minimizing allocation overhead while avoiding static allocation.
>
> The mininum size of the memory pool used in the HPB is implemented
> as a module parameter, so that it can be configurable by the user.
>
> To gurantee a minimum memory pool size of 4MB:
> ufshpb_host_map_kbytes=4096
>
> The map_work manages active/inactive by 2 "to-do" lists.
> Each hpb lun maintains 2 "to-do" lists:
>   hpb->lh_inact_rgn - regions to be inactivated, and
>   hpb->lh_act_srgn - subregions to be activated
> Those lists are maintained on IO completion.
>
> Reviewed-by: Bart Van Assche 
> Reviewed-by: Can Guo 
> Acked-by: Avri Altman 
> Tested-by: Bean Huo 
> Signed-off-by: Daejun Park 
> ---
>  drivers/scsi/ufs/ufs.h|   36 ++
>  drivers/scsi/ufs/ufshcd.c |4 +
>  drivers/scsi/ufs/ufshpb.c | 1091 -
>  drivers/scsi/ufs/ufshpb.h |   65 +++
>  4 files changed, 1181 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
> index 65563635e20e..957763db1006 100644
> --- a/drivers/scsi/ufs/ufs.h
> +++ b/drivers/scsi/ufs/ufs.h
> @@ -472,6 +472,41 @@ struct utp_cmd_rsp {
>  u8 sense_data[UFS_SENSE_SIZE];
>  };
>
> +struct ufshpb_active_field {
> +__be16 active_rgn;
> +__be16 active_srgn;
> +};
> +#define HPB_ACT_FIELD_SIZE 4
> +
> +/**
> + * struct utp_hpb_rsp - Response UPIU structure
> + * @residual_transfer_count: Residual transfer count DW-3
> + * @reserved1: Reserved double words DW-4 to DW-7
> + * @sense_data_len: Sense data length DW-8 U16
> + * @desc_type: Descriptor type of sense data
> + * @additional_len: Additional length of sense data
> + * @hpb_op: HPB operation type
> + * @lun: LUN of response UPIU
> + * @active_rgn_cnt: Active region count
> + * @inactive_rgn_cnt: Inactive region count
> + * @hpb_active_field: Recommended to read HPB region and subregion
> + * @hpb_inactive_field: To be inactivated HPB region and subregion
> + */
> +struct utp_hpb_rsp {
> +__be32 residual_transfer_count;
> +__be32 reserved1[4];
> +__be16 sense_data_len;
> +u8 desc_type;
> +u8 additional_len;
> +u8 hpb_op;
> +u8 lun;
> +u8 active_rgn_cnt;
> +u8 inactive_rgn_cnt;
> +struct ufshpb_active_field hpb_active_field[2];
> +__be16 hpb_inactive_field[2];
> +};
> +#define UTP_HPB_RSP_SIZE 40
> +
>  /**
>   * struct utp_upiu_rsp - general upiu response structure
>   * @header: UPIU header structure DW-0 to DW-2
> @@ -482,6 +517,7 @@ struct utp_upiu_rsp {
>  struct utp_upiu_header header;
>  union {
>  struct utp_cmd_rsp sr;
> +struct utp_hpb_rsp hr;
>  struct utp_upiu_query qr;
>  };
>  };
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> index 49b3d5d24fa6..5852ff44c3cc 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -5021,6 +5021,9 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba,
> struct ufshcd_lrb *lrbp)
>   */
>  pm_runtime_get_noresume(hba->dev);
>  }
> +
> +if (scsi_status == SAM_STAT_GOOD)
> +ufshpb_rsp_upiu(hba, lrbp);
>  break;
>  case UPIU_TRANSACTION_REJECT_UPIU:
>  /* TODO: handle Reject UPIU Response */
> @@ -9221,6 +9224,7 @@ EXPORT_SYMBOL(ufshcd_shutdown);
>  void ufshcd_remove(struct ufs_hba *hba)
>  {
>  ufs_bsg_remove(hba);
> +ufshpb_remove(hba);
>  ufs_sysfs_remove_nodes(hba->dev);
>  blk_cleanup_queue(hba->tmf_queue);
>  blk_mq_free_tag_set(>tmf_tag_set);
> diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
> index 1a72f6541510..8abadb0e010a 100644
> --- a/drivers/scsi/ufs/ufshpb.c
> +++ b/drivers/scsi/ufs/ufshpb.c
> @@ -16,6 +16,16 @@
>  #include "ufshpb.h"
>  #include "../sd.h"
>
> +/* memory management */
> 

RE: Re: [PATCH v26 2/4] scsi: ufs: L2P map management for HPB read

2021-03-11 Thread Daejun Park
>>> > This is a patch for managing L2P map in HPB module.
>>> >
>>> > The HPB divides logical addresses into several regions. A region
>>> > consists
>>> > of several sub-regions. The sub-region is a basic unit where L2P
>>> > mapping is
>>> > managed. The driver loads L2P mapping data of each sub-region. The
>>> > loaded
>>> > sub-region is called active-state. The HPB driver unloads L2P mapping
>>> > data
>>> > as region unit. The unloaded region is called inactive-state.
>>> >
>>> > Sub-region/region candidates to be loaded and unloaded are delivered
>>> > from
>>> > the UFS device. The UFS device delivers the recommended active
>>> > sub-region
>>> > and inactivate region to the driver using sensedata.
>>> > The HPB module performs L2P mapping management on the host through the
>>> > delivered information.
>>> >
>>> > A pinned region is a pre-set regions on the UFS device that is always
>>> > activate-state.
>>> >
>>> > The data structure for map data request and L2P map uses mempool API,
>>> > minimizing allocation overhead while avoiding static allocation.
>>> >
>>> > The mininum size of the memory pool used in the HPB is implemented
>>> > as a module parameter, so that it can be configurable by the user.
>>> >
>>> > To gurantee a minimum memory pool size of 4MB:
>>> > ufshpb_host_map_kbytes=4096
>>> >
>>> > The map_work manages active/inactive by 2 "to-do" lists.
>>> > Each hpb lun maintains 2 "to-do" lists:
>>> >   hpb->lh_inact_rgn - regions to be inactivated, and
>>> >   hpb->lh_act_srgn - subregions to be activated
>>> > Those lists are maintained on IO completion.
>>> >
>>> > Reviewed-by: Bart Van Assche 
>>> > Reviewed-by: Can Guo 
>>> > Acked-by: Avri Altman 
>>> > Tested-by: Bean Huo 
>>> > Signed-off-by: Daejun Park 
>>> > ---
>>> >  drivers/scsi/ufs/ufs.h|   36 ++
>>> >  drivers/scsi/ufs/ufshcd.c |4 +
>>> >  drivers/scsi/ufs/ufshpb.c | 1091 -
>>> >  drivers/scsi/ufs/ufshpb.h |   65 +++
>>> >  4 files changed, 1181 insertions(+), 15 deletions(-)
>>> >
>>> > diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
>>> > index 65563635e20e..957763db1006 100644
>>> > --- a/drivers/scsi/ufs/ufs.h
>>> > +++ b/drivers/scsi/ufs/ufs.h
>>> > @@ -472,6 +472,41 @@ struct utp_cmd_rsp {
>>> >  u8 sense_data[UFS_SENSE_SIZE];
>>> >  };
>>> >
>>> > +struct ufshpb_active_field {
>>> > +__be16 active_rgn;
>>> > +__be16 active_srgn;
>>> > +};
>>> > +#define HPB_ACT_FIELD_SIZE 4
>>> > +
>>> > +/**
>>> > + * struct utp_hpb_rsp - Response UPIU structure
>>> > + * @residual_transfer_count: Residual transfer count DW-3
>>> > + * @reserved1: Reserved double words DW-4 to DW-7
>>> > + * @sense_data_len: Sense data length DW-8 U16
>>> > + * @desc_type: Descriptor type of sense data
>>> > + * @additional_len: Additional length of sense data
>>> > + * @hpb_op: HPB operation type
>>> > + * @lun: LUN of response UPIU
>>> > + * @active_rgn_cnt: Active region count
>>> > + * @inactive_rgn_cnt: Inactive region count
>>> > + * @hpb_active_field: Recommended to read HPB region and subregion
>>> > + * @hpb_inactive_field: To be inactivated HPB region and subregion
>>> > + */
>>> > +struct utp_hpb_rsp {
>>> > +__be32 residual_transfer_count;
>>> > +__be32 reserved1[4];
>>> > +__be16 sense_data_len;
>>> > +u8 desc_type;
>>> > +u8 additional_len;
>>> > +u8 hpb_op;
>>> > +u8 lun;
>>> > +u8 active_rgn_cnt;
>>> > +u8 inactive_rgn_cnt;
>>> > +struct ufshpb_active_field hpb_active_field[2];
>>> > +__be16 hpb_inactive_field[2];
>>> > +};
>>> > +#define UTP_HPB_RSP_SIZE 40
>>> > +
>>> >  /**
>>> >   * struct utp_upiu_rsp - general upiu response structure
>>> >   * @header: UPIU header structure DW-0 to DW-2
>>> > @@ -482,6 +517,7 @@ struct utp_upiu_rsp {
>>> >  struct utp_upiu_header header;
>>> >  union {
>>> >  struct utp_cmd_rsp sr;
>>> > +struct utp_hpb_rsp hr;
>>> >  struct utp_upiu_query qr;
>>> >  };
>>> >  };
>>> > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
>>> > index 49b3d5d24fa6..5852ff44c3cc 100644
>>> > --- a/drivers/scsi/ufs/ufshcd.c
>>> > +++ b/drivers/scsi/ufs/ufshcd.c
>>> > @@ -5021,6 +5021,9 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba,
>>> > struct ufshcd_lrb *lrbp)
>>> >   */
>>> >  pm_runtime_get_noresume(hba->dev);
>>> >  }
>>> > +
>>> > +if (scsi_status == SAM_STAT_GOOD)
>>> > +ufshpb_rsp_upiu(hba, lrbp);
>>> >  break;
>>> >  case UPIU_TRANSACTION_REJECT_UPIU:
>>> >  /* TODO: handle Reject UPIU Response */
>>> > @@ -9221,6 +9224,7 @@ EXPORT_SYMBOL(ufshcd_shutdown);
>>> >  void ufshcd_remove(struct ufs_hba *hba)
>>> >  {
>>> >  

Re: [PATCH v26 2/4] scsi: ufs: L2P map management for HPB read

2021-03-11 Thread Can Guo

On 2021-03-12 09:48, Daejun Park wrote:

> This is a patch for managing L2P map in HPB module.
>
> The HPB divides logical addresses into several regions. A region
> consists
> of several sub-regions. The sub-region is a basic unit where L2P
> mapping is
> managed. The driver loads L2P mapping data of each sub-region. The
> loaded
> sub-region is called active-state. The HPB driver unloads L2P mapping
> data
> as region unit. The unloaded region is called inactive-state.
>
> Sub-region/region candidates to be loaded and unloaded are delivered
> from
> the UFS device. The UFS device delivers the recommended active
> sub-region
> and inactivate region to the driver using sensedata.
> The HPB module performs L2P mapping management on the host through the
> delivered information.
>
> A pinned region is a pre-set regions on the UFS device that is always
> activate-state.
>
> The data structure for map data request and L2P map uses mempool API,
> minimizing allocation overhead while avoiding static allocation.
>
> The mininum size of the memory pool used in the HPB is implemented
> as a module parameter, so that it can be configurable by the user.
>
> To gurantee a minimum memory pool size of 4MB:
> ufshpb_host_map_kbytes=4096
>
> The map_work manages active/inactive by 2 "to-do" lists.
> Each hpb lun maintains 2 "to-do" lists:
>   hpb->lh_inact_rgn - regions to be inactivated, and
>   hpb->lh_act_srgn - subregions to be activated
> Those lists are maintained on IO completion.
>
> Reviewed-by: Bart Van Assche 
> Reviewed-by: Can Guo 
> Acked-by: Avri Altman 
> Tested-by: Bean Huo 
> Signed-off-by: Daejun Park 
> ---
>  drivers/scsi/ufs/ufs.h|   36 ++
>  drivers/scsi/ufs/ufshcd.c |4 +
>  drivers/scsi/ufs/ufshpb.c | 1091 -
>  drivers/scsi/ufs/ufshpb.h |   65 +++
>  4 files changed, 1181 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
> index 65563635e20e..957763db1006 100644
> --- a/drivers/scsi/ufs/ufs.h
> +++ b/drivers/scsi/ufs/ufs.h
> @@ -472,6 +472,41 @@ struct utp_cmd_rsp {
>  u8 sense_data[UFS_SENSE_SIZE];
>  };
>
> +struct ufshpb_active_field {
> +__be16 active_rgn;
> +__be16 active_srgn;
> +};
> +#define HPB_ACT_FIELD_SIZE 4
> +
> +/**
> + * struct utp_hpb_rsp - Response UPIU structure
> + * @residual_transfer_count: Residual transfer count DW-3
> + * @reserved1: Reserved double words DW-4 to DW-7
> + * @sense_data_len: Sense data length DW-8 U16
> + * @desc_type: Descriptor type of sense data
> + * @additional_len: Additional length of sense data
> + * @hpb_op: HPB operation type
> + * @lun: LUN of response UPIU
> + * @active_rgn_cnt: Active region count
> + * @inactive_rgn_cnt: Inactive region count
> + * @hpb_active_field: Recommended to read HPB region and subregion
> + * @hpb_inactive_field: To be inactivated HPB region and subregion
> + */
> +struct utp_hpb_rsp {
> +__be32 residual_transfer_count;
> +__be32 reserved1[4];
> +__be16 sense_data_len;
> +u8 desc_type;
> +u8 additional_len;
> +u8 hpb_op;
> +u8 lun;
> +u8 active_rgn_cnt;
> +u8 inactive_rgn_cnt;
> +struct ufshpb_active_field hpb_active_field[2];
> +__be16 hpb_inactive_field[2];
> +};
> +#define UTP_HPB_RSP_SIZE 40
> +
>  /**
>   * struct utp_upiu_rsp - general upiu response structure
>   * @header: UPIU header structure DW-0 to DW-2
> @@ -482,6 +517,7 @@ struct utp_upiu_rsp {
>  struct utp_upiu_header header;
>  union {
>  struct utp_cmd_rsp sr;
> +struct utp_hpb_rsp hr;
>  struct utp_upiu_query qr;
>  };
>  };
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> index 49b3d5d24fa6..5852ff44c3cc 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -5021,6 +5021,9 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba,
> struct ufshcd_lrb *lrbp)
>   */
>  pm_runtime_get_noresume(hba->dev);
>  }
> +
> +if (scsi_status == SAM_STAT_GOOD)
> +ufshpb_rsp_upiu(hba, lrbp);
>  break;
>  case UPIU_TRANSACTION_REJECT_UPIU:
>  /* TODO: handle Reject UPIU Response */
> @@ -9221,6 +9224,7 @@ EXPORT_SYMBOL(ufshcd_shutdown);
>  void ufshcd_remove(struct ufs_hba *hba)
>  {
>  ufs_bsg_remove(hba);
> +ufshpb_remove(hba);
>  ufs_sysfs_remove_nodes(hba->dev);
>  blk_cleanup_queue(hba->tmf_queue);
>  blk_mq_free_tag_set(>tmf_tag_set);
> diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
> index 1a72f6541510..8abadb0e010a 100644
> --- a/drivers/scsi/ufs/ufshpb.c
> +++ b/drivers/scsi/ufs/ufshpb.c
> @@ -16,6 +16,16 @@
>  #include "ufshpb.h"
>  #include "../sd.h"
>
> +/* memory management */
> 

RE: Re: [PATCH v26 2/4] scsi: ufs: L2P map management for HPB read

2021-03-11 Thread Daejun Park
> > This is a patch for managing L2P map in HPB module.
> > 
> > The HPB divides logical addresses into several regions. A region 
> > consists
> > of several sub-regions. The sub-region is a basic unit where L2P 
> > mapping is
> > managed. The driver loads L2P mapping data of each sub-region. The 
> > loaded
> > sub-region is called active-state. The HPB driver unloads L2P mapping 
> > data
> > as region unit. The unloaded region is called inactive-state.
> > 
> > Sub-region/region candidates to be loaded and unloaded are delivered 
> > from
> > the UFS device. The UFS device delivers the recommended active 
> > sub-region
> > and inactivate region to the driver using sensedata.
> > The HPB module performs L2P mapping management on the host through the
> > delivered information.
> > 
> > A pinned region is a pre-set regions on the UFS device that is always
> > activate-state.
> > 
> > The data structure for map data request and L2P map uses mempool API,
> > minimizing allocation overhead while avoiding static allocation.
> > 
> > The mininum size of the memory pool used in the HPB is implemented
> > as a module parameter, so that it can be configurable by the user.
> > 
> > To gurantee a minimum memory pool size of 4MB: 
> > ufshpb_host_map_kbytes=4096
> > 
> > The map_work manages active/inactive by 2 "to-do" lists.
> > Each hpb lun maintains 2 "to-do" lists:
> >   hpb->lh_inact_rgn - regions to be inactivated, and
> >   hpb->lh_act_srgn - subregions to be activated
> > Those lists are maintained on IO completion.
> > 
> > Reviewed-by: Bart Van Assche 
> > Reviewed-by: Can Guo 
> > Acked-by: Avri Altman 
> > Tested-by: Bean Huo 
> > Signed-off-by: Daejun Park 
> > ---
> >  drivers/scsi/ufs/ufs.h|   36 ++
> >  drivers/scsi/ufs/ufshcd.c |4 +
> >  drivers/scsi/ufs/ufshpb.c | 1091 -
> >  drivers/scsi/ufs/ufshpb.h |   65 +++
> >  4 files changed, 1181 insertions(+), 15 deletions(-)
> > 
> > diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
> > index 65563635e20e..957763db1006 100644
> > --- a/drivers/scsi/ufs/ufs.h
> > +++ b/drivers/scsi/ufs/ufs.h
> > @@ -472,6 +472,41 @@ struct utp_cmd_rsp {
> >  u8 sense_data[UFS_SENSE_SIZE];
> >  };
> > 
> > +struct ufshpb_active_field {
> > +__be16 active_rgn;
> > +__be16 active_srgn;
> > +};
> > +#define HPB_ACT_FIELD_SIZE 4
> > +
> > +/**
> > + * struct utp_hpb_rsp - Response UPIU structure
> > + * @residual_transfer_count: Residual transfer count DW-3
> > + * @reserved1: Reserved double words DW-4 to DW-7
> > + * @sense_data_len: Sense data length DW-8 U16
> > + * @desc_type: Descriptor type of sense data
> > + * @additional_len: Additional length of sense data
> > + * @hpb_op: HPB operation type
> > + * @lun: LUN of response UPIU
> > + * @active_rgn_cnt: Active region count
> > + * @inactive_rgn_cnt: Inactive region count
> > + * @hpb_active_field: Recommended to read HPB region and subregion
> > + * @hpb_inactive_field: To be inactivated HPB region and subregion
> > + */
> > +struct utp_hpb_rsp {
> > +__be32 residual_transfer_count;
> > +__be32 reserved1[4];
> > +__be16 sense_data_len;
> > +u8 desc_type;
> > +u8 additional_len;
> > +u8 hpb_op;
> > +u8 lun;
> > +u8 active_rgn_cnt;
> > +u8 inactive_rgn_cnt;
> > +struct ufshpb_active_field hpb_active_field[2];
> > +__be16 hpb_inactive_field[2];
> > +};
> > +#define UTP_HPB_RSP_SIZE 40
> > +
> >  /**
> >   * struct utp_upiu_rsp - general upiu response structure
> >   * @header: UPIU header structure DW-0 to DW-2
> > @@ -482,6 +517,7 @@ struct utp_upiu_rsp {
> >  struct utp_upiu_header header;
> >  union {
> >  struct utp_cmd_rsp sr;
> > +struct utp_hpb_rsp hr;
> >  struct utp_upiu_query qr;
> >  };
> >  };
> > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> > index 49b3d5d24fa6..5852ff44c3cc 100644
> > --- a/drivers/scsi/ufs/ufshcd.c
> > +++ b/drivers/scsi/ufs/ufshcd.c
> > @@ -5021,6 +5021,9 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba,
> > struct ufshcd_lrb *lrbp)
> >   */
> >  pm_runtime_get_noresume(hba->dev);
> >  }
> > +
> > +if (scsi_status == SAM_STAT_GOOD)
> > +ufshpb_rsp_upiu(hba, lrbp);
> >  break;
> >  case UPIU_TRANSACTION_REJECT_UPIU:
> >  /* TODO: handle Reject UPIU Response */
> > @@ -9221,6 +9224,7 @@ EXPORT_SYMBOL(ufshcd_shutdown);
> >  void ufshcd_remove(struct ufs_hba *hba)
> >  {
> >  ufs_bsg_remove(hba);
> > +ufshpb_remove(hba);
> >  ufs_sysfs_remove_nodes(hba->dev);
> >  blk_cleanup_queue(hba->tmf_queue);
> >  blk_mq_free_tag_set(>tmf_tag_set);
> > diff --git a/drivers/scsi/ufs/ufshpb.c 

RE: Re: [PATCH v26 2/4] scsi: ufs: L2P map management for HPB read

2021-03-11 Thread Daejun Park
> > The HPB divides logical addresses into several regions. A region 
> > consists
> > of several sub-regions. The sub-region is a basic unit where L2P 
> > mapping is
> > managed. The driver loads L2P mapping data of each sub-region. The 
> > loaded
> > sub-region is called active-state. The HPB driver unloads L2P mapping 
> > data
> > as region unit. The unloaded region is called inactive-state.
> > 
> > Sub-region/region candidates to be loaded and unloaded are delivered 
> > from
> > the UFS device. The UFS device delivers the recommended active 
> > sub-region
> > and inactivate region to the driver using sensedata.
> > The HPB module performs L2P mapping management on the host through the
> > delivered information.
> > 
> > A pinned region is a pre-set regions on the UFS device that is always
> > activate-state.
> > 
> > The data structure for map data request and L2P map uses mempool API,
> > minimizing allocation overhead while avoiding static allocation.
> > 
> > The mininum size of the memory pool used in the HPB is implemented
> > as a module parameter, so that it can be configurable by the user.
> > 
> > To gurantee a minimum memory pool size of 4MB: 
> > ufshpb_host_map_kbytes=4096
> > 
> > The map_work manages active/inactive by 2 "to-do" lists.
> > Each hpb lun maintains 2 "to-do" lists:
> >   hpb->lh_inact_rgn - regions to be inactivated, and
> >   hpb->lh_act_srgn - subregions to be activated
> > Those lists are maintained on IO completion.
> > 
> > Reviewed-by: Bart Van Assche 
> > Reviewed-by: Can Guo 
> > Acked-by: Avri Altman 
> > Tested-by: Bean Huo 
> > Signed-off-by: Daejun Park 
> > ---
> >  drivers/scsi/ufs/ufs.h|   36 ++
> >  drivers/scsi/ufs/ufshcd.c |4 +
> >  drivers/scsi/ufs/ufshpb.c | 1091 -
> >  drivers/scsi/ufs/ufshpb.h |   65 +++
> >  4 files changed, 1181 insertions(+), 15 deletions(-)
> > 
> > diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
> > index 65563635e20e..957763db1006 100644
> > --- a/drivers/scsi/ufs/ufs.h
> > +++ b/drivers/scsi/ufs/ufs.h
> > @@ -472,6 +472,41 @@ struct utp_cmd_rsp {
> >  u8 sense_data[UFS_SENSE_SIZE];
> >  };
> > ...
> > +/*
> > + * This function will parse recommended active subregion information 
> > in sense
> > + * data field of response UPIU with SAM_STAT_GOOD state.
> > + */
> > +void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
> > +{
> > +struct ufshpb_lu *hpb = ufshpb_get_hpb_data(lrbp->cmd->device);
> > +struct utp_hpb_rsp *rsp_field = >ucd_rsp_ptr->hr;
> > +int data_seg_len;
> > +
> > +if (unlikely(lrbp->lun != rsp_field->lun)) {
> > +struct scsi_device *sdev;
> > +bool found = false;
> > +
> > +__shost_for_each_device(sdev, hba->host) {
> > +hpb = ufshpb_get_hpb_data(sdev);
> > +
> > +if (!hpb)
> > +continue;
> > +
> > +if (rsp_field->lun == hpb->lun) {
> > +found = true;
> > +break;
> > +}
> > +}
> > +
> > +if (!found)
> > +return;
> > +}
> > +
> > +if (!hpb)
> > +return;
> > +
> > +if ((ufshpb_get_state(hpb) != HPB_PRESENT) &&
> > +(ufshpb_get_state(hpb) != HPB_SUSPEND)) {
> > +dev_notice(>sdev_ufs_lu->sdev_dev,
> > +   "%s: ufshpb state is not PRESENT/SUSPEND\n",
> > +   __func__);
>  
> Please mute these prints before hpb is fully initilized, otherwise
> there can be tons of these prints during bootup. Say set a flag in
> ufshpb_hpb_lu_prepared() and check for that flag - just a rough idea.

OK, I will change it.

Thanks,
Daejun


Re: [PATCH v26 2/4] scsi: ufs: L2P map management for HPB read

2021-03-11 Thread Can Guo

On 2021-03-03 14:28, Daejun Park wrote:

This is a patch for managing L2P map in HPB module.

The HPB divides logical addresses into several regions. A region 
consists
of several sub-regions. The sub-region is a basic unit where L2P 
mapping is
managed. The driver loads L2P mapping data of each sub-region. The 
loaded
sub-region is called active-state. The HPB driver unloads L2P mapping 
data

as region unit. The unloaded region is called inactive-state.

Sub-region/region candidates to be loaded and unloaded are delivered 
from
the UFS device. The UFS device delivers the recommended active 
sub-region

and inactivate region to the driver using sensedata.
The HPB module performs L2P mapping management on the host through the
delivered information.

A pinned region is a pre-set regions on the UFS device that is always
activate-state.

The data structure for map data request and L2P map uses mempool API,
minimizing allocation overhead while avoiding static allocation.

The mininum size of the memory pool used in the HPB is implemented
as a module parameter, so that it can be configurable by the user.

To gurantee a minimum memory pool size of 4MB: 
ufshpb_host_map_kbytes=4096


The map_work manages active/inactive by 2 "to-do" lists.
Each hpb lun maintains 2 "to-do" lists:
  hpb->lh_inact_rgn - regions to be inactivated, and
  hpb->lh_act_srgn - subregions to be activated
Those lists are maintained on IO completion.

Reviewed-by: Bart Van Assche 
Reviewed-by: Can Guo 
Acked-by: Avri Altman 
Tested-by: Bean Huo 
Signed-off-by: Daejun Park 
---
 drivers/scsi/ufs/ufs.h|   36 ++
 drivers/scsi/ufs/ufshcd.c |4 +
 drivers/scsi/ufs/ufshpb.c | 1091 -
 drivers/scsi/ufs/ufshpb.h |   65 +++
 4 files changed, 1181 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 65563635e20e..957763db1006 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -472,6 +472,41 @@ struct utp_cmd_rsp {
u8 sense_data[UFS_SENSE_SIZE];
 };
...
+/*
+ * This function will parse recommended active subregion information 
in sense

+ * data field of response UPIU with SAM_STAT_GOOD state.
+ */
+void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
+{
+   struct ufshpb_lu *hpb = ufshpb_get_hpb_data(lrbp->cmd->device);
+   struct utp_hpb_rsp *rsp_field = >ucd_rsp_ptr->hr;
+   int data_seg_len;
+
+   if (unlikely(lrbp->lun != rsp_field->lun)) {
+   struct scsi_device *sdev;
+   bool found = false;
+
+   __shost_for_each_device(sdev, hba->host) {
+   hpb = ufshpb_get_hpb_data(sdev);
+
+   if (!hpb)
+   continue;
+
+   if (rsp_field->lun == hpb->lun) {
+   found = true;
+   break;
+   }
+   }
+
+   if (!found)
+   return;
+   }
+
+   if (!hpb)
+   return;
+
+   if ((ufshpb_get_state(hpb) != HPB_PRESENT) &&
+   (ufshpb_get_state(hpb) != HPB_SUSPEND)) {
+   dev_notice(>sdev_ufs_lu->sdev_dev,
+  "%s: ufshpb state is not PRESENT/SUSPEND\n",
+  __func__);


Please mute these prints before hpb is fully initilized, otherwise
there can be tons of these prints during bootup. Say set a flag in
ufshpb_hpb_lu_prepared() and check for that flag - just a rough idea.

Thanks,
Can Guo.


+   return;
+   }
+


Re: [PATCH v26 2/4] scsi: ufs: L2P map management for HPB read

2021-03-11 Thread Can Guo

On 2021-03-03 14:28, Daejun Park wrote:

This is a patch for managing L2P map in HPB module.

The HPB divides logical addresses into several regions. A region 
consists
of several sub-regions. The sub-region is a basic unit where L2P 
mapping is
managed. The driver loads L2P mapping data of each sub-region. The 
loaded
sub-region is called active-state. The HPB driver unloads L2P mapping 
data

as region unit. The unloaded region is called inactive-state.

Sub-region/region candidates to be loaded and unloaded are delivered 
from
the UFS device. The UFS device delivers the recommended active 
sub-region

and inactivate region to the driver using sensedata.
The HPB module performs L2P mapping management on the host through the
delivered information.

A pinned region is a pre-set regions on the UFS device that is always
activate-state.

The data structure for map data request and L2P map uses mempool API,
minimizing allocation overhead while avoiding static allocation.

The mininum size of the memory pool used in the HPB is implemented
as a module parameter, so that it can be configurable by the user.

To gurantee a minimum memory pool size of 4MB: 
ufshpb_host_map_kbytes=4096


The map_work manages active/inactive by 2 "to-do" lists.
Each hpb lun maintains 2 "to-do" lists:
  hpb->lh_inact_rgn - regions to be inactivated, and
  hpb->lh_act_srgn - subregions to be activated
Those lists are maintained on IO completion.

Reviewed-by: Bart Van Assche 
Reviewed-by: Can Guo 
Acked-by: Avri Altman 
Tested-by: Bean Huo 
Signed-off-by: Daejun Park 
---
 drivers/scsi/ufs/ufs.h|   36 ++
 drivers/scsi/ufs/ufshcd.c |4 +
 drivers/scsi/ufs/ufshpb.c | 1091 -
 drivers/scsi/ufs/ufshpb.h |   65 +++
 4 files changed, 1181 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 65563635e20e..957763db1006 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -472,6 +472,41 @@ struct utp_cmd_rsp {
u8 sense_data[UFS_SENSE_SIZE];
 };

+struct ufshpb_active_field {
+   __be16 active_rgn;
+   __be16 active_srgn;
+};
+#define HPB_ACT_FIELD_SIZE 4
+
+/**
+ * struct utp_hpb_rsp - Response UPIU structure
+ * @residual_transfer_count: Residual transfer count DW-3
+ * @reserved1: Reserved double words DW-4 to DW-7
+ * @sense_data_len: Sense data length DW-8 U16
+ * @desc_type: Descriptor type of sense data
+ * @additional_len: Additional length of sense data
+ * @hpb_op: HPB operation type
+ * @lun: LUN of response UPIU
+ * @active_rgn_cnt: Active region count
+ * @inactive_rgn_cnt: Inactive region count
+ * @hpb_active_field: Recommended to read HPB region and subregion
+ * @hpb_inactive_field: To be inactivated HPB region and subregion
+ */
+struct utp_hpb_rsp {
+   __be32 residual_transfer_count;
+   __be32 reserved1[4];
+   __be16 sense_data_len;
+   u8 desc_type;
+   u8 additional_len;
+   u8 hpb_op;
+   u8 lun;
+   u8 active_rgn_cnt;
+   u8 inactive_rgn_cnt;
+   struct ufshpb_active_field hpb_active_field[2];
+   __be16 hpb_inactive_field[2];
+};
+#define UTP_HPB_RSP_SIZE 40
+
 /**
  * struct utp_upiu_rsp - general upiu response structure
  * @header: UPIU header structure DW-0 to DW-2
@@ -482,6 +517,7 @@ struct utp_upiu_rsp {
struct utp_upiu_header header;
union {
struct utp_cmd_rsp sr;
+   struct utp_hpb_rsp hr;
struct utp_upiu_query qr;
};
 };
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 49b3d5d24fa6..5852ff44c3cc 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -5021,6 +5021,9 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba,
struct ufshcd_lrb *lrbp)
 */
pm_runtime_get_noresume(hba->dev);
}
+
+   if (scsi_status == SAM_STAT_GOOD)
+   ufshpb_rsp_upiu(hba, lrbp);
break;
case UPIU_TRANSACTION_REJECT_UPIU:
/* TODO: handle Reject UPIU Response */
@@ -9221,6 +9224,7 @@ EXPORT_SYMBOL(ufshcd_shutdown);
 void ufshcd_remove(struct ufs_hba *hba)
 {
ufs_bsg_remove(hba);
+   ufshpb_remove(hba);
ufs_sysfs_remove_nodes(hba->dev);
blk_cleanup_queue(hba->tmf_queue);
blk_mq_free_tag_set(>tmf_tag_set);
diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
index 1a72f6541510..8abadb0e010a 100644
--- a/drivers/scsi/ufs/ufshpb.c
+++ b/drivers/scsi/ufs/ufshpb.c
@@ -16,6 +16,16 @@
 #include "ufshpb.h"
 #include "../sd.h"

+/* memory management */
+static struct kmem_cache *ufshpb_mctx_cache;
+static mempool_t *ufshpb_mctx_pool;
+static mempool_t *ufshpb_page_pool;
+/* A cache size of 2MB can cache ppn in the 1GB range. */
+static unsigned int ufshpb_host_map_kbytes = 2048;
+static int tot_active_srgn_pages;
+
+static struct 

[PATCH v26 2/4] scsi: ufs: L2P map management for HPB read

2021-03-03 Thread Daejun Park
This is a patch for managing L2P map in HPB module.

The HPB divides logical addresses into several regions. A region consists
of several sub-regions. The sub-region is a basic unit where L2P mapping is
managed. The driver loads L2P mapping data of each sub-region. The loaded
sub-region is called active-state. The HPB driver unloads L2P mapping data
as region unit. The unloaded region is called inactive-state.

Sub-region/region candidates to be loaded and unloaded are delivered from
the UFS device. The UFS device delivers the recommended active sub-region
and inactivate region to the driver using sensedata.
The HPB module performs L2P mapping management on the host through the
delivered information.

A pinned region is a pre-set regions on the UFS device that is always
activate-state.

The data structure for map data request and L2P map uses mempool API,
minimizing allocation overhead while avoiding static allocation.

The mininum size of the memory pool used in the HPB is implemented
as a module parameter, so that it can be configurable by the user.

To gurantee a minimum memory pool size of 4MB: ufshpb_host_map_kbytes=4096

The map_work manages active/inactive by 2 "to-do" lists.
Each hpb lun maintains 2 "to-do" lists:
  hpb->lh_inact_rgn - regions to be inactivated, and
  hpb->lh_act_srgn - subregions to be activated
Those lists are maintained on IO completion.

Reviewed-by: Bart Van Assche 
Reviewed-by: Can Guo 
Acked-by: Avri Altman 
Tested-by: Bean Huo 
Signed-off-by: Daejun Park 
---
 drivers/scsi/ufs/ufs.h|   36 ++
 drivers/scsi/ufs/ufshcd.c |4 +
 drivers/scsi/ufs/ufshpb.c | 1091 -
 drivers/scsi/ufs/ufshpb.h |   65 +++
 4 files changed, 1181 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 65563635e20e..957763db1006 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -472,6 +472,41 @@ struct utp_cmd_rsp {
u8 sense_data[UFS_SENSE_SIZE];
 };
 
+struct ufshpb_active_field {
+   __be16 active_rgn;
+   __be16 active_srgn;
+};
+#define HPB_ACT_FIELD_SIZE 4
+
+/**
+ * struct utp_hpb_rsp - Response UPIU structure
+ * @residual_transfer_count: Residual transfer count DW-3
+ * @reserved1: Reserved double words DW-4 to DW-7
+ * @sense_data_len: Sense data length DW-8 U16
+ * @desc_type: Descriptor type of sense data
+ * @additional_len: Additional length of sense data
+ * @hpb_op: HPB operation type
+ * @lun: LUN of response UPIU
+ * @active_rgn_cnt: Active region count
+ * @inactive_rgn_cnt: Inactive region count
+ * @hpb_active_field: Recommended to read HPB region and subregion
+ * @hpb_inactive_field: To be inactivated HPB region and subregion
+ */
+struct utp_hpb_rsp {
+   __be32 residual_transfer_count;
+   __be32 reserved1[4];
+   __be16 sense_data_len;
+   u8 desc_type;
+   u8 additional_len;
+   u8 hpb_op;
+   u8 lun;
+   u8 active_rgn_cnt;
+   u8 inactive_rgn_cnt;
+   struct ufshpb_active_field hpb_active_field[2];
+   __be16 hpb_inactive_field[2];
+};
+#define UTP_HPB_RSP_SIZE 40
+
 /**
  * struct utp_upiu_rsp - general upiu response structure
  * @header: UPIU header structure DW-0 to DW-2
@@ -482,6 +517,7 @@ struct utp_upiu_rsp {
struct utp_upiu_header header;
union {
struct utp_cmd_rsp sr;
+   struct utp_hpb_rsp hr;
struct utp_upiu_query qr;
};
 };
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 49b3d5d24fa6..5852ff44c3cc 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -5021,6 +5021,9 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct 
ufshcd_lrb *lrbp)
 */
pm_runtime_get_noresume(hba->dev);
}
+
+   if (scsi_status == SAM_STAT_GOOD)
+   ufshpb_rsp_upiu(hba, lrbp);
break;
case UPIU_TRANSACTION_REJECT_UPIU:
/* TODO: handle Reject UPIU Response */
@@ -9221,6 +9224,7 @@ EXPORT_SYMBOL(ufshcd_shutdown);
 void ufshcd_remove(struct ufs_hba *hba)
 {
ufs_bsg_remove(hba);
+   ufshpb_remove(hba);
ufs_sysfs_remove_nodes(hba->dev);
blk_cleanup_queue(hba->tmf_queue);
blk_mq_free_tag_set(>tmf_tag_set);
diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
index 1a72f6541510..8abadb0e010a 100644
--- a/drivers/scsi/ufs/ufshpb.c
+++ b/drivers/scsi/ufs/ufshpb.c
@@ -16,6 +16,16 @@
 #include "ufshpb.h"
 #include "../sd.h"
 
+/* memory management */
+static struct kmem_cache *ufshpb_mctx_cache;
+static mempool_t *ufshpb_mctx_pool;
+static mempool_t *ufshpb_page_pool;
+/* A cache size of 2MB can cache ppn in the 1GB range. */
+static unsigned int ufshpb_host_map_kbytes = 2048;
+static int tot_active_srgn_pages;
+
+static struct workqueue_struct *ufshpb_wq;
+
 bool