@@ -261,6 +261,8 @@ static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio,
lru_gen_update_size(lruvec, folio, -1, gen);
/* for folio_rotate_reclaimable() */
+ folio->hit_shield = 1;
+ /* This for initialize hit_shield by 1 when folio add to gen */
if (reclaiming)
list_add_tail(&folio->lru, &lrugen->folios[gen][type][zone]);
else
@@ -189,6 +189,12 @@ struct page {
void *virtual; /* Kernel virtual address (NULL if
not kmapped, ie. highmem) */
#endif /* WANT_PAGE_VIRTUAL */
+ unsigned char hit_shield; /*
+ * The hit_shield variable I added to the page
+ * This variable is responsible for counting
+ * the number of times this
+ * page's generation has been updated.
+ */
#ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS
int _last_cpupid;
@@ -343,6 +349,10 @@ struct folio {
#if defined(WANT_PAGE_VIRTUAL)
void *virtual;
#endif
+ unsigned char hit_shield; /*
+ * Variable added to the folio that
+ * exists to offset the page structure.
+ */
#ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS
int _last_cpupid;
#endif
@@ -404,6 +414,8 @@ FOLIO_MATCH(memcg_data, memcg_data);
#if defined(WANT_PAGE_VIRTUAL)
FOLIO_MATCH(virtual, virtual);
#endif
+FOLIO_MATCH(hit_shield, hit_shield);
+/* A match macro for hit_shield */
#ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS
FOLIO_MATCH(_last_cpupid, _last_cpupid);
#endif
@@ -3132,7 +3132,14 @@ static int folio_update_gen(struct folio *folio, int gen)
new_flags = old_flags & ~(LRU_GEN_MASK | LRU_REFS_MASK | LRU_REFS_FLAGS);
new_flags |= (gen + 1UL) << LRU_GEN_PGOFF;
} while (!try_cmpxchg(&folio->flags, &old_flags, new_flags));
-
+ /*
+ * This part is core of hit_shield : Has this folio been updated frequently?
+ * I chose 5 as the number of times to grant shield because of MAX_NR_GENS is 4,
+ * so if this folio has been updated for more than a generation's length,
+ * it has additional survivability equal to the generation's length.
+ */
+ if (folio->hit_shield)
+ folio->hit_shield = (folio->hit_shield + 1) % 5;
return ((old_flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1;
}
@@ -4307,6 +4314,16 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, struct scan_c
return true;
}
+ /* this when hit_shield is enabled (if 0)
+ * init hit_shield again, and protect this folio like second chance algorithm
+ */
+ if (!folio->hit_shield) {
+ folio->hit_shield = 1;
+ gen = folio_inc_gen(lruvec, folio, true);
+ list_move(&folio->lru, &lrugen->folios[gen][type][zone]);
+ return true;
+ }
+
return false;
}