And somehow I didn't notice that cpuhp_set_state() doesn't look right,

On 09/19, Peter Zijlstra wrote:
>  void cpu_hotplug_begin(void)
>  {
> -     cpu_hotplug.active_writer = current;
> +     lockdep_assert_held(&cpu_add_remove_lock);
>  
> -     for (;;) {
> -             mutex_lock(&cpu_hotplug.lock);
> -             if (likely(!cpu_hotplug.refcount))
> -                     break;
> -             __set_current_state(TASK_UNINTERRUPTIBLE);
> -             mutex_unlock(&cpu_hotplug.lock);
> -             schedule();
> -     }
> +     __cpuhp_writer = current;
> +
> +     /* After this everybody will observe _writer and take the slow path. */
> +     synchronize_sched();
> +
> +     /* Wait for no readers -- reader preference */
> +     cpuhp_wait_refcount();
> +
> +     /* Stop new readers. */
> +     cpuhp_set_state(1);

But this stops all readers, not only new. Even if cpuhp_wait_refcount()
was correct, a new reader can come right before cpuhp_set_state(1) and
then it can call another recursive get_online_cpus() right after.

Oleg.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to