Re: [PATCH v6 6/9] mm: multigenerational lru: aging

From: Yu Zhao
Date: Tue Jan 11 2022 - 20:01:40 EST


On Mon, Jan 10, 2022 at 05:57:39PM +0100, Michal Hocko wrote:
> On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> [...]
> > +static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_mm_walk *walk)
> > +{
> > + static const struct mm_walk_ops mm_walk_ops = {
> > + .test_walk = should_skip_vma,
> > + .p4d_entry = walk_pud_range,
> > + };
> > +
> > + int err;
> > +#ifdef CONFIG_MEMCG
> > + struct mem_cgroup *memcg = lruvec_memcg(lruvec);
> > +#endif
> > +
> > + walk->next_addr = FIRST_USER_ADDRESS;
> > +
> > + do {
> > + unsigned long start = walk->next_addr;
> > + unsigned long end = mm->highest_vm_end;
> > +
> > + err = -EBUSY;
> > +
> > + rcu_read_lock();
> > +#ifdef CONFIG_MEMCG
> > + if (memcg && atomic_read(&memcg->moving_account))
> > + goto contended;
> > +#endif
>
> Why do you need to check for moving_account?

This check, if succeeds, blocks memcg migration.

Our goal is to move pages between different generations of the same
lruvec (the first arg). Meanwhile, pages can also be migrated between
different memcgs (different lruvecs).

The active/inactive lru uses isolation to block memcg migration.

Generations account pages similarly to the active/inactive lru, i.e.,
each generation has nr_pages counter. However, unlike the active/
inactive lru, a page can be moved to a different generation without
getting isolated or even without being under the lru lock, as long as
the delta is eventually accounted for (which does require the lru lock
when it happens).

The generation counter in page->flags (folio->flags to be precise)
stores 0 when a page is isolated, to synchronize with isolation.