summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvri Altman <avri.altman@wdc.com>2021-07-12 12:50:32 +0300
committerMartin K. Petersen <martin.petersen@oracle.com>2021-08-01 16:05:14 -0400
commit6c59cb501b86f8cddc486d6846732375f7baef24 (patch)
tree332f62a18a3d15255ecdf073d13c5f52ac0a4078
parentc76a188856413f0a40585a7bc6801c755a4c0c8d (diff)
scsi: ufs: ufshpb: Make eviction depend on region's reads
In host mode, eviction is considered an extreme measure. Verify that the entering region has enough reads, and the exiting region has fewer reads. Link: https://lore.kernel.org/r/20210712095039.8093-6-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>
-rw-r--r--drivers/scsi/ufs/ufshpb.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
index a330c4922965..912bc6e5f3f8 100644
--- a/drivers/scsi/ufs/ufshpb.c
+++ b/drivers/scsi/ufs/ufshpb.c
@@ -17,6 +17,7 @@
#include "../sd.h"
#define ACTIVATION_THRESHOLD 8 /* 8 IOs */
+#define EVICTION_THRESHOLD (ACTIVATION_THRESHOLD << 5) /* 256 IOs */
/* memory management */
static struct kmem_cache *ufshpb_mctx_cache;
@@ -1056,6 +1057,13 @@ static struct ufshpb_region *ufshpb_victim_lru_info(struct ufshpb_lu *hpb)
if (ufshpb_check_srgns_issue_state(hpb, rgn))
continue;
+ /*
+ * in host control mode, verify that the exiting region
+ * has fewer reads
+ */
+ if (hpb->is_hcm && rgn->reads > (EVICTION_THRESHOLD >> 1))
+ continue;
+
victim_rgn = rgn;
break;
}
@@ -1223,7 +1231,7 @@ unlock_out:
static int ufshpb_add_region(struct ufshpb_lu *hpb, struct ufshpb_region *rgn)
{
- struct ufshpb_region *victim_rgn;
+ struct ufshpb_region *victim_rgn = NULL;
struct victim_select_info *lru_info = &hpb->lru_info;
unsigned long flags;
int ret = 0;
@@ -1250,7 +1258,15 @@ static int ufshpb_add_region(struct ufshpb_lu *hpb, struct ufshpb_region *rgn)
* It is okay to evict the least recently used region,
* because the device could detect this region
* by not issuing HPB_READ
+ *
+ * in host control mode, verify that the entering
+ * region has enough reads
*/
+ if (hpb->is_hcm && rgn->reads < EVICTION_THRESHOLD) {
+ ret = -EACCES;
+ goto out;
+ }
+
victim_rgn = ufshpb_victim_lru_info(hpb);
if (!victim_rgn) {
dev_warn(&hpb->sdev_ufs_lu->sdev_dev,