Re: [PATCH v2 6/6] stop_machine: kill stop_cpus_lock and lg_double_lock/unlock()

2015-08-03 Thread Oleg Nesterov
On 07/30, Peter Zijlstra wrote: > > On Tue, Jul 21, 2015 at 09:22:47PM +0200, Oleg Nesterov wrote: > > > + err = -EDEADLK; > > + if (stop_work_pending(stopper1) != stop_work_pending(stopper2)) > > + goto unlock; > > You could DoS/false positive this by running stop_one_cpu() in a loop

Re: [PATCH v2 6/6] stop_machine: kill stop_cpus_lock and lg_double_lock/unlock()

2015-08-03 Thread Oleg Nesterov
On 07/31, Peter Zijlstra wrote: > > + for_each_cpu(cpu, cpumask) > + arch_spin_lock((arch_spinlock_t *)&per_cpu(cpu_stopper.lock, > cpu)); > + > for_each_cpu(cpu, cpumask) { > work = &per_cpu(cpu_stopper.stop_work, cpu); > work->fn = fn; >

Re: [PATCH v2 6/6] stop_machine: kill stop_cpus_lock and lg_double_lock/unlock()

2015-08-01 Thread Peter Zijlstra
On Sat, Aug 01, 2015 at 12:57:18PM +0200, Oleg Nesterov wrote: > > > + if (stop_work_pending(stopper1) != stop_work_pending(stopper2)) > > > + goto unlock; > > > > You could DoS/false positive this by running stop_one_cpu() in a loop, > > and thereby 'always' having work pending on one but

Re: [PATCH v2 6/6] stop_machine: kill stop_cpus_lock and lg_double_lock/unlock()

2015-08-01 Thread Oleg Nesterov
Hi Peter, Thanks for looking. I'll try to reply on Monday, just one note... On 07/30, Peter Zijlstra wrote: > > On Tue, Jul 21, 2015 at 09:22:47PM +0200, Oleg Nesterov wrote: > > > +static int cpu_stop_queue_two_works(int cpu1, struct cpu_stop_work *work1, > > + int

Re: [PATCH v2 6/6] stop_machine: kill stop_cpus_lock and lg_double_lock/unlock()

2015-07-31 Thread Peter Zijlstra
On Fri, Jul 31, 2015 at 01:12:46PM +0200, Peter Zijlstra wrote: > On Thu, Jul 30, 2015 at 11:55:27PM +0200, Peter Zijlstra wrote: > > > > Exclusion between stop_{one,two}_cpu{,s}() and stop_cpus() makes this > > trivially go away. > > > > Paul's RCU branch already kills try_stop_cpus() dead, so t

Re: [PATCH v2 6/6] stop_machine: kill stop_cpus_lock and lg_double_lock/unlock()

2015-07-31 Thread Peter Zijlstra
On Thu, Jul 30, 2015 at 11:55:27PM +0200, Peter Zijlstra wrote: > > Exclusion between stop_{one,two}_cpu{,s}() and stop_cpus() makes this > trivially go away. > > Paul's RCU branch already kills try_stop_cpus() dead, so that wart is > also gone. But we're still stuck with stop_machine_from_inacti

Re: [PATCH v2 6/6] stop_machine: kill stop_cpus_lock and lg_double_lock/unlock()

2015-07-30 Thread Peter Zijlstra
On Tue, Jul 21, 2015 at 09:22:47PM +0200, Oleg Nesterov wrote: > +static int cpu_stop_queue_two_works(int cpu1, struct cpu_stop_work *work1, > + int cpu2, struct cpu_stop_work *work2) > +{ > + struct cpu_stopper *stopper1 = per_cpu_ptr(&cpu_stopper, cpu1); > +

[PATCH v2 6/6] stop_machine: kill stop_cpus_lock and lg_double_lock/unlock()

2015-07-21 Thread Oleg Nesterov
stop_two_cpus() and stop_cpus() use stop_cpus_lock to avoid the deadlock, we need to ensure that the stopper functions can't be queued "backwards" from one another. Instead, we can change stop_two_cpus() to take 2 stopper->lock's and queue both works "atomically"; just we need to check that both -