From: SeongHan S. <lo...@gm...> - 2012-01-27 04:07:39
|
Hi My name is Sunghan Suh and I'm a software engineer for a software company in South Korea I'd like to express my gratitude for your contributions to UML, which is helping me tremendously I discovered a bug in your X86_64 configuration system a while back which involves lost wakeups for rw semaphores In what follows is an analysis of the problem and I'd be much obliged if you'd commit it to the mainline kernel The Kernel in question is 2.6.35.14 * Bug 1. two threads thread#0,#1 simultaneously attempt down_write(acquire) 2. thread#0 succeeds down_write, thread#1 fails down_write which causes it to sleep in rwsem_down_failed_common 3. thread#0 finishes its work and calls up_write(release) 4. thread#0 calls rwsem_wake in up_write which should wakeup thread#1, but it doesn't, so rwsem_wake isn't called therefore wakeup never happens * Source code and configurations In arch/x86/lib/rwsem_64.S there is a condition in which call_rwsem_wake calls rwsem_wake. If the count value isn't properly maintained, wakeup never happens because the condition statement fails In printing the count value, I discovered that the counter is set for 32bit systems while the condition check was for 64. - ./arch/x86/include/asm/rwsem.h (macro for counter) ----------------------------------------------------------------- #ifdef CONFIG_X86_64 #define RWSEM_ACTIVE_MASK 0xffffffffL #else #define RWSEM_ACTIVE_MASK 0x0000ffffL #endif ----------------------------------------------------------------- - ./arch/x86/lib/Makefile (condition check function selecting mechanism) ----------------------------------------------------------------- ifeq ($(CONFIG_X86_32),y) ... lib-y += semaphore_32.o string_32.o ... else ... lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem_64.o endif ----------------------------------------------------------------- - ./.config (neither CONFIG_X86_64 nor CONFIG_X86_32 are defined) ----------------------------------------------------------------- #CONFIG_X86_32 is not set ----------------------------------------------------------------- because neither CONFIG_X86_64 nor CONFIG_X86_32 are defined header file's macro is built for 32bit and the checking function is for 64. * Solution in arch/um/Kconfig.x86 add "X86_64" (the boldface part) config as in arch/x86/Kconfig ----------------------------------------------------------------- config 64BIT bool default SUBARCH = "x86_64" *config X86_64* * def_bool 64BIT* config X86_32 def_bool !64BIT ----------------------------------------------------------------- thank you for your time |