* Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx> wrote: > From: Ingo Molnar <mingo@xxxxxxxxxx> > > The various struct pagevec per CPU variables are protected by disabling > either preemption or interrupts across the critical sections. Inside > these sections spinlocks have to be acquired. > diff --git a/mm/swap.c b/mm/swap.c > index bf9a79fed62d7..4f965292044ca 100644 > --- a/mm/swap.c > +++ b/mm/swap.c > @@ -35,6 +35,7 @@ > #include <linux/uio.h> > #include <linux/hugetlb.h> > #include <linux/page_idle.h> > +#include <linux/locallock.h> > > #include "internal.h" > > @@ -44,14 +45,29 @@ > /* How many pages do we try to swap or page in/out together? */ > int page_cluster; > > -static DEFINE_PER_CPU(struct pagevec, lru_add_pvec); > -static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs); > -static DEFINE_PER_CPU(struct pagevec, lru_deactivate_file_pvecs); > -static DEFINE_PER_CPU(struct pagevec, lru_deactivate_pvecs); > -static DEFINE_PER_CPU(struct pagevec, lru_lazyfree_pvecs); > +/* Protecting lru_rotate_pvecs */ > +struct lru_rotate_pvecs { > + struct local_lock lock; > + struct pagevec pvec; > +}; > +static DEFINE_PER_CPU(struct lru_rotate_pvecs, lru_rotate_pvecs) = { > + .lock = INIT_LOCAL_LOCK(lock), > +}; > + > +/* Protecting the following struct pagevec */ > +struct lru_pvecs { > + struct local_lock lock; > + struct pagevec lru_add_pvec; > + struct pagevec lru_deactivate_file_pvecs; > + struct pagevec lru_deactivate_pvecs; > + struct pagevec lru_lazyfree_pvecs; Ack on coalescing these into the 'struct lru_pvecs' helper structure, but a minor namespace organization nit: I'd drop the _pvec/_pvecs postfix from the field names, i.e. make it something like this: /* Protecting the following struct pagevec */ struct lru_pvecs { struct local_lock lock; struct pagevec lru_add; struct pagevec lru_deactivate_file; struct pagevec lru_deactivate; struct pagevec lru_lazyfree; With that change, usage is a straightforward: pvec->lru_deactivate instead of the double-pvec name: pvec->lru_deactivate_pvec > + local_lock_irqsave(&lru_rotate_pvecs.lock, flags); Also: > + pvec = this_cpu_ptr(&lru_rotate_pvecs.pvec); s/lru_rotate_pvecs /lru_rotate_pvec it's a single pagevec, using plural is confusing when reading the code. I'd also suggest adding a comment explaining why the lru_rotate_pvec local lock is split away from lru_add/deactivate/deactivate/lazyfree pagevec local lock. Thanks, Ingo