summaryrefslogtreecommitdiff
path: root/drivers/scsi/ufs
diff options
context:
space:
mode:
authorAvri Altman <avri.altman@wdc.com>2021-07-12 12:50:30 +0300
committerMartin K. Petersen <martin.petersen@oracle.com>2021-08-01 16:05:14 -0400
commit8becf4db1e01d6ae2bb9f9877537dffee89b8308 (patch)
tree14f311cada78f6c9ab7ac5fd3b96453aca9a5561 /drivers/scsi/ufs
parent3a2c1f6803298c0a8784444cf66645163dd8e61b (diff)
scsi: ufs: ufshpb: Transform set_dirty to iterate_rgn
Given a transfer length, set_dirty meticulously iterates over all the entries, across subregions and regions if needed. Currently its only use is to mark dirty blocks, but HCM may benefit from it as well to manage its read counters. Link: https://lore.kernel.org/r/20210712095039.8093-4-avri.altman@wdc.com Reviewed-by: Daejun Park <daejun7.park@samsung.com> Signed-off-by: Avri Altman <avri.altman@wdc.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/ufs')
-rw-r--r--drivers/scsi/ufs/ufshpb.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
index 9d46d02f6b97..8b4029b9da2e 100644
--- a/drivers/scsi/ufs/ufshpb.c
+++ b/drivers/scsi/ufs/ufshpb.c
@@ -145,13 +145,14 @@ static bool ufshpb_is_hpb_rsp_valid(struct ufs_hba *hba,
return true;
}
-static void ufshpb_set_ppn_dirty(struct ufshpb_lu *hpb, int rgn_idx,
- int srgn_idx, int srgn_offset, int cnt)
+static void ufshpb_iterate_rgn(struct ufshpb_lu *hpb, int rgn_idx, int srgn_idx,
+ int srgn_offset, int cnt, bool set_dirty)
{
struct ufshpb_region *rgn;
struct ufshpb_subregion *srgn;
int set_bit_len;
int bitmap_len;
+ unsigned long flags;
next_srgn:
rgn = hpb->rgn_tbl + rgn_idx;
@@ -167,11 +168,14 @@ next_srgn:
else
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)
bitmap_set(srgn->mctx->ppn_dirty, srgn_offset, set_bit_len);
+ spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
srgn_offset = 0;
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 (ufshpb_is_write_or_discard(cmd)) {
- spin_lock_irqsave(&hpb->rgn_state_lock, flags);
- ufshpb_set_ppn_dirty(hpb, rgn_idx, srgn_idx, srgn_offset,
- transfer_len);
- spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
+ ufshpb_iterate_rgn(hpb, rgn_idx, srgn_idx, srgn_offset,
+ transfer_len, true);
return 0;
}