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