> > 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 <bvanassche@xxxxxxx> > > Reviewed-by: Can Guo <cang@xxxxxxxxxxxxxx> > > Acked-by: Avri Altman <Avri.Altman@xxxxxxx> > > Tested-by: Bean Huo <beanhuo@xxxxxxxxxx> > > Signed-off-by: Daejun Park <daejun7.park@xxxxxxxxxxx> > > --- > > 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 = &lrbp->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(&hpb->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