Re: [PATCH v4 3/3] mm: mglru: promote mapped executable folios after first usage

From: Barry Song

Date: Tue Jul 21 2026 - 04:35:05 EST


On Mon, Jul 20, 2026 at 7:12 PM Baolin Wang
<baolin.wang@xxxxxxxxxxxxxxxxx> wrote:
>
> Classical LRU protects mapped executable file folios through commit
> 8cab4754d24a0 ("vmscan: make mapped executable pages the first class
> citizen") and commit c909e99364c8 ("vmscan: activate executable pages
> after first usage"), giving executable code a better chance to stay in
> memory, avoiding IO thrashing and improving workload performance.
>
> However, MGLRU's protection of mapped executable file folios is less
> reliable. Although shrink_folio_list() checks references, the access flag
> of mapped executable file folios may have already been checked and
> cleared by lru_gen_look_around() or walk_mm(). Additionally,
> folio_update_gen() or lru_gen_set_refs() only sets the 'PG_referenced'
> flag for mapped executable file folios, which causes shrink_folio_list()
> to ignore the first usage of these mapped executable file folios and
> reclaim them easily.
>
> Follow the classical LRU's logic, promoting mapped executable file folios
> after their first usage in folio_update_gen() and lru_gen_set_refs(),
> giving executable code a better chance to stay in memory.
>
> On my 32-core Arm machine, with the memcg limit set to 2G, running
> 'make -j32' to build kernel showed some improvement in sys time.
>
> base patched
> 9248.543s 7861.579s
>
> Signed-off-by: Baolin Wang <baolin.wang@xxxxxxxxxxxxxxxxx>
> Acked-by: Johannes Weiner <hannes@xxxxxxxxxxx>
> Reviewed-by: Axel Rasmussen <axelrasmussen@xxxxxxxxxx>
> ---
> mm/vmscan.c | 43 +++++++++++++++++++++++++++----------------
> 1 file changed, 27 insertions(+), 16 deletions(-)
>
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index 8f0c31a4848e..b1ec65fb8947 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -841,10 +841,16 @@ enum folio_references {
> * with PG_active set. In contrast, the aging (page table walk) path uses
> * folio_update_gen().
> */
> -static bool lru_gen_set_refs(struct folio *folio)
> +static bool lru_gen_set_refs(struct folio *folio, const vma_flags_t *vma_flags)
> {
> /* see the comment on LRU_REFS_FLAGS */
> if (!folio_test_referenced(folio) && !folio_test_workingset(folio)) {
> + /* Activate file-backed executable folios after first usage. */
> + if (is_exec_file_folio(folio, vma_flags)) {
> + set_mask_bits(&folio->flags.f, LRU_REFS_FLAGS, BIT(PG_workingset));
> + return true;
> + }
> +

Hi Baolin,

Do you see any performance difference if you change the code to
something like the following?

-static bool lru_gen_set_refs(struct folio *folio)
+static bool lru_gen_set_refs(struct folio *folio, const vma_flags_t *vma_flags)
{
+ /* Activate file-backed executable folios after first usage. */
+ if (is_exec_file_folio(folio, vma_flags)) {
+ set_mask_bits(&folio->flags.f, LRU_REFS_FLAGS,
BIT(PG_workingset));
+ return true;
+ }
+

Best Regards
Barry