On 09/24, Peter Zijlstra wrote:
>
> +void __get_online_cpus(void)
>  {
> -     if (cpu_hotplug.active_writer == current)
> +     /* Support reader-in-writer recursion */
> +     if (__cpuhp_writer == current)
>               return;
> -     mutex_lock(&cpu_hotplug.lock);
>  
> -     if (WARN_ON(!cpu_hotplug.refcount))
> -             cpu_hotplug.refcount++; /* try to fix things up */
> +     atomic_inc(&cpuhp_waitcount);
>  
> -     if (!--cpu_hotplug.refcount && unlikely(cpu_hotplug.active_writer))
> -             wake_up_process(cpu_hotplug.active_writer);
> -     mutex_unlock(&cpu_hotplug.lock);
> +     /*
> +      * We either call schedule() in the wait, or we'll fall through
> +      * and reschedule on the preempt_enable() in get_online_cpus().
> +      */
> +     preempt_enable_no_resched();
> +     wait_event(cpuhp_readers, !__cpuhp_writer);
> +     preempt_disable();
> +
> +     if (atomic_dec_and_test(&cpuhp_waitcount))
> +             wake_up_all(&cpuhp_writer);

Yes, this should fix the races with the exiting writer, but still this
doesn't look right afaics.

In particular let me repeat,

>  void cpu_hotplug_begin(void)
>  {
> -     cpu_hotplug.active_writer = current;
> +     unsigned int count = 0;
> +     int cpu;
> +
> +     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();

synchronize_sched() is slow. The new readers will likely notice
__cpuhp_writer != NULL much earlier and they will be blocked in
__get_online_cpus() while the writer sleeps before it actually
enters the critical section.

Or I completely misunderstood this all?

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