Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
rcu: rcu_read_lock_bh_held(): disabling irqs also disables bh
generic-ipi: Fix deadlock in __smp_call_function_single

+15 -4
+1 -1
include/linux/rcupdate.h
··· 454 454 * Makes rcu_dereference_check() do the dirty work. 455 455 */ 456 456 #define rcu_dereference_bh(p) \ 457 - rcu_dereference_check(p, rcu_read_lock_bh_held()) 457 + rcu_dereference_check(p, rcu_read_lock_bh_held() || irqs_disabled()) 458 458 459 459 /** 460 460 * rcu_dereference_sched - fetch RCU-protected pointer, checking for RCU-sched
+14 -3
kernel/smp.c
··· 365 365 EXPORT_SYMBOL_GPL(smp_call_function_any); 366 366 367 367 /** 368 - * __smp_call_function_single(): Run a function on another CPU 368 + * __smp_call_function_single(): Run a function on a specific CPU 369 369 * @cpu: The CPU to run on. 370 370 * @data: Pre-allocated and setup data structure 371 + * @wait: If true, wait until function has completed on specified CPU. 371 372 * 372 373 * Like smp_call_function_single(), but allow caller to pass in a 373 374 * pre-allocated data structure. Useful for embedding @data inside ··· 377 376 void __smp_call_function_single(int cpu, struct call_single_data *data, 378 377 int wait) 379 378 { 380 - csd_lock(data); 379 + unsigned int this_cpu; 380 + unsigned long flags; 381 381 382 + this_cpu = get_cpu(); 382 383 /* 383 384 * Can deadlock when called with interrupts disabled. 384 385 * We allow cpu's that are not yet online though, as no one else can ··· 390 387 WARN_ON_ONCE(cpu_online(smp_processor_id()) && wait && irqs_disabled() 391 388 && !oops_in_progress); 392 389 393 - generic_exec_single(cpu, data, wait); 390 + if (cpu == this_cpu) { 391 + local_irq_save(flags); 392 + data->func(data->info); 393 + local_irq_restore(flags); 394 + } else { 395 + csd_lock(data); 396 + generic_exec_single(cpu, data, wait); 397 + } 398 + put_cpu(); 394 399 } 395 400 396 401 /**