FROMLIST: scsi: ufs: Transform set_dirty to iterate_rgn
Given a transfer length, set_dirty meticulously runs over all the entries, across subregions and regions if needed. Currently its only use is to mark dirty blocks, but soon HCM may profit from it as well, when managing its read counters. Bug: 183467926 Bug: 170940265 Bug: 183454255 Link: https://lore.kernel.org/lkml/20210607061401.58884-4-avri.altman@wdc.com/ Signed-off-by: Avri Altman <avri.altman@wdc.com> Reviewed-by: Daejun Park <daejun7.park@samsung.com> Change-Id: I916f4bf80490e31e5ef797d67647a41a07cefa02
This commit is contained in:
@@ -145,13 +145,14 @@ static bool ufshpb_is_hpb_rsp_valid(struct ufs_hba *hba,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ufshpb_set_ppn_dirty(struct ufshpb_lu *hpb, int rgn_idx,
|
static void ufshpb_iterate_rgn(struct ufshpb_lu *hpb, int rgn_idx, int srgn_idx,
|
||||||
int srgn_idx, int srgn_offset, int cnt)
|
int srgn_offset, int cnt, bool set_dirty)
|
||||||
{
|
{
|
||||||
struct ufshpb_region *rgn;
|
struct ufshpb_region *rgn;
|
||||||
struct ufshpb_subregion *srgn;
|
struct ufshpb_subregion *srgn;
|
||||||
int set_bit_len;
|
int set_bit_len;
|
||||||
int bitmap_len;
|
int bitmap_len;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
next_srgn:
|
next_srgn:
|
||||||
rgn = hpb->rgn_tbl + rgn_idx;
|
rgn = hpb->rgn_tbl + rgn_idx;
|
||||||
@@ -167,11 +168,14 @@ next_srgn:
|
|||||||
else
|
else
|
||||||
set_bit_len = cnt;
|
set_bit_len = cnt;
|
||||||
|
|
||||||
set_bit(RGN_FLAG_DIRTY, &rgn->rgn_flags);
|
if (set_dirty)
|
||||||
|
set_bit(RGN_FLAG_DIRTY, &rgn->rgn_flags);
|
||||||
|
|
||||||
if (rgn->rgn_state != HPB_RGN_INACTIVE &&
|
spin_lock_irqsave(&hpb->rgn_state_lock, flags);
|
||||||
|
if (set_dirty && rgn->rgn_state != HPB_RGN_INACTIVE &&
|
||||||
srgn->srgn_state == HPB_SRGN_VALID)
|
srgn->srgn_state == HPB_SRGN_VALID)
|
||||||
bitmap_set(srgn->mctx->ppn_dirty, srgn_offset, set_bit_len);
|
bitmap_set(srgn->mctx->ppn_dirty, srgn_offset, set_bit_len);
|
||||||
|
spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
|
||||||
|
|
||||||
srgn_offset = 0;
|
srgn_offset = 0;
|
||||||
if (++srgn_idx == hpb->srgns_per_rgn) {
|
if (++srgn_idx == hpb->srgns_per_rgn) {
|
||||||
@@ -591,10 +595,8 @@ int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
|
|||||||
|
|
||||||
/* If command type is WRITE or DISCARD, set bitmap as drity */
|
/* If command type is WRITE or DISCARD, set bitmap as drity */
|
||||||
if (ufshpb_is_write_or_discard(cmd)) {
|
if (ufshpb_is_write_or_discard(cmd)) {
|
||||||
spin_lock_irqsave(&hpb->rgn_state_lock, flags);
|
ufshpb_iterate_rgn(hpb, rgn_idx, srgn_idx, srgn_offset,
|
||||||
ufshpb_set_ppn_dirty(hpb, rgn_idx, srgn_idx, srgn_offset,
|
transfer_len, true);
|
||||||
transfer_len);
|
|
||||||
spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user