Commit 8becf4db authored by Avri Altman's avatar Avri Altman Committed by Martin K. Petersen
Browse files

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: default avatarDaejun Park <daejun7.park@samsung.com>
Signed-off-by: default avatarAvri Altman <avri.altman@wdc.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 3a2c1f68
Loading
Loading
Loading
Loading
+10 −8
Original line number Original line Diff line number Diff line
@@ -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 @@ static void ufshpb_set_ppn_dirty(struct ufshpb_lu *hpb, int rgn_idx,
	else
	else
		set_bit_len = cnt;
		set_bit_len = cnt;


	if (set_dirty)
		set_bit(RGN_FLAG_DIRTY, &rgn->rgn_flags);
		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;
	}
	}