On Fri, 27 May 2016 15:10:24 +0200 Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx> wrote: > * Luiz Capitulino | 2016-05-24 15:15:51 [-0400]: > > >Sebastian, > > > >It's not clear to me from our last discussion what's the > >best plan for this patch. I'm sending v2 with the changes > >you suggested. > > The patch at the bottom is what I intend to take into the next v4.6-RT. > local_lock_irqsave_on() was already part of the first v4.6 release. I > don't like the part where local_lock_irqsave_on() is a simple > local_irq_safe() on !RT but that is another story. Looks good to me. > > diff --git a/include/linux/locallock.h b/include/linux/locallock.h > index 493e801e0c9b..845c77f1a5ca 100644 > --- a/include/linux/locallock.h > +++ b/include/linux/locallock.h > @@ -66,6 +66,9 @@ static inline void __local_lock(struct local_irq_lock *lv) > #define local_lock(lvar) \ > do { __local_lock(&get_local_var(lvar)); } while (0) > > +#define local_lock_on(lvar, cpu) \ > + do { __local_lock(&per_cpu(lvar, cpu)); } while (0) > + > static inline int __local_trylock(struct local_irq_lock *lv) > { > if (lv->owner != current && spin_trylock_local(&lv->lock)) { > @@ -104,6 +107,9 @@ static inline void __local_unlock(struct local_irq_lock *lv) > put_local_var(lvar); \ > } while (0) > > +#define local_unlock_on(lvar, cpu) \ > + do { __local_unlock(&per_cpu(lvar, cpu)); } while (0) > + > static inline void __local_lock_irq(struct local_irq_lock *lv) > { > spin_lock_irqsave(&lv->lock, lv->flags); > diff --git a/mm/swap.c b/mm/swap.c > index 892747266c7e..35fab668a782 100644 > --- a/mm/swap.c > +++ b/mm/swap.c > @@ -596,9 +596,9 @@ void lru_add_drain_cpu(int cpu) > unsigned long flags; > > /* No harm done if a racing interrupt already did this */ > - local_lock_irqsave(rotate_lock, flags); > + local_lock_irqsave_on(rotate_lock, flags, cpu); > pagevec_move_tail(pvec); > - local_unlock_irqrestore(rotate_lock, flags); > + local_unlock_irqrestore_on(rotate_lock, flags, cpu); > } > > pvec = &per_cpu(lru_deactivate_file_pvecs, cpu); > @@ -666,12 +666,32 @@ void lru_add_drain(void) > local_unlock_cpu(swapvec_lock); > } > > + > +#ifdef CONFIG_PREEMPT_RT_BASE > +static inline void remote_lru_add_drain(int cpu, struct cpumask *has_work) > +{ > + local_lock_on(swapvec_lock, cpu); > + lru_add_drain_cpu(cpu); > + local_unlock_on(swapvec_lock, cpu); > +} > + > +#else > + > static void lru_add_drain_per_cpu(struct work_struct *dummy) > { > lru_add_drain(); > } > > static DEFINE_PER_CPU(struct work_struct, lru_add_drain_work); > +static inline void remote_lru_add_drain(int cpu, struct cpumask *has_work) > +{ > + struct work_struct *work = &per_cpu(lru_add_drain_work, cpu); > + > + INIT_WORK(work, lru_add_drain_per_cpu); > + schedule_work_on(cpu, work); > + cpumask_set_cpu(cpu, has_work); > +} > +#endif > > void lru_add_drain_all(void) > { > @@ -684,21 +704,18 @@ void lru_add_drain_all(void) > cpumask_clear(&has_work); > > for_each_online_cpu(cpu) { > - struct work_struct *work = &per_cpu(lru_add_drain_work, cpu); > - > if (pagevec_count(&per_cpu(lru_add_pvec, cpu)) || > pagevec_count(&per_cpu(lru_rotate_pvecs, cpu)) || > pagevec_count(&per_cpu(lru_deactivate_file_pvecs, cpu)) || > pagevec_count(&per_cpu(lru_deactivate_pvecs, cpu)) || > - need_activate_page_drain(cpu)) { > - INIT_WORK(work, lru_add_drain_per_cpu); > - schedule_work_on(cpu, work); > - cpumask_set_cpu(cpu, &has_work); > - } > + need_activate_page_drain(cpu)) > + remote_lru_add_drain(cpu, &has_work); > } > > +#ifndef CONFIG_PREEMPT_RT_BASE > for_each_cpu(cpu, &has_work) > flush_work(&per_cpu(lru_add_drain_work, cpu)); > +#endif > > put_online_cpus(); > mutex_unlock(&lock); -- To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html