Re: [PATCH v4 3/9] mm/lru: replace pgdat lru_lock with lruvec lock

From: Matthew Wilcox
Date: Tue Nov 19 2019 - 10:57:11 EST


On Tue, Nov 19, 2019 at 08:23:17PM +0800, Alex Shi wrote:
> +static inline struct lruvec *lock_page_lruvec_irqsave(struct page *page,
> + struct pglist_data *pgdat, unsigned long *flags)
> +{
> + struct lruvec *lruvec = mem_cgroup_page_lruvec(page, pgdat);
> +
> + spin_lock_irqsave(&lruvec->lru_lock, *flags);
> +
> + return lruvec;
> +}

This should be a macro, not a function. You basically can't do this;
spin_lock_irqsave needs to write to a variable which can then be passed
to spin_unlock_irqrestore(). What you're doing here will dereference the
pointer in _this_ function, but won't propagate the modified value back to
the caller. I suppose you could do something like this ...

static inline struct lruvec *lock_page_lruvec_irqsave(struct page *page,
struct pglist_data *pgdat, unsigned long *flagsp)
{
unsigned long flags;
struct lruvec *lruvec = mem_cgroup_page_lruvec(page, pgdat);

spin_lock_irqsave(&lruvec->lru_lock, flags);
*flagsp = flags;

return lruvec;
}

Almost certainly easier to write a macro though.

You shouldn't need the two prior patches with this kind of change.