• Xiao Guangrong's avatar
    There is a race between generic_smp_call_function_*() and hotplug_cfd() in · 773438d6
    Xiao Guangrong authored
    many cases, see below examples:
    
    1: hotplug_cfd() can free cfd->cpumask, the system will crash if the
       cpu's cfd still in the call_function list:
    
    
          CPU A:                         CPU B
    
     smp_call_function_many()	    ......
       cpu_down()                      ......
      hotplug_cfd() ->                 ......
     free_cpumask_var(cfd->cpumask)  (receive function IPI interrupte)
                                    /* read cfd->cpumask */
                              generic_smp_call_function_interrupt() ->
                             cpumask_test_and_clear_cpu(cpu, data->cpumask)
    
                             	CRASH!!!
    
    2: It's not handle call_function list when cpu down, It's will lead to
       dead-wait if other path is waiting this cpu to execute function
    
        CPU A:                           CPU B
    
     smp_call_function_many(wait=0)
            ......			    CPU B down
       smp_call_function_many() -->  (cpu down before recevie function
        csd_lock(&data->csd);         IPI interrupte)
    
        DEAD-WAIT!!!!
    
      So, CPU A will dead-wait in csd_lock(), the same as
      smp_call_function_single()
    Signed-off-by: default avatarXiao Guangrong <xiaoguangrong@cn.fujitsu.com>
    Cc: Ingo Molnar <mingo@elte.hu>
    Cc: Jens Axboe <jens.axboe@oracle.com>
    Cc: Nick Piggin <nickpiggin@yahoo.com.au>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Rusty Russell <rusty@rustcorp.com.au>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    773438d6
smp.c 13 KB