In host mode, eviction is considered an extreme measure.
verify that the entering region has enough reads, and the exiting
region has much less reads.

Signed-off-by: Avri Altman <avri.alt...@wdc.com>
---
 drivers/scsi/ufs/ufshpb.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
index 3ab66421dc00..aefb6dc160ee 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;
@@ -1057,6 +1058,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 less reads
+                */
+               if (hpb->is_hcm && rgn->reads > (EVICTION_THRESHOLD >> 1))
+                       continue;
+
                victim_rgn = rgn;
                break;
        }
@@ -1229,7 +1237,7 @@ static int ufshpb_issue_map_req(struct ufshpb_lu *hpb,
 
 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;
@@ -1256,7 +1264,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,
-- 
2.25.1

Reply via email to