• Nicolas Pitre's avatar
    [PATCH] fix race with preempt_enable() · d6f02913
    Nicolas Pitre authored
    Currently a simple
    
    	void foo(void) { preempt_enable(); }
    
    produces the following code on ARM:
    
    foo:
    	bic	r3, sp, #8128
    	bic	r3, r3, #63
    	ldr	r2, [r3, #4]
    	ldr	r1, [r3, #0]
    	sub	r2, r2, #1
    	tst	r1, #4
    	str	r2, [r3, #4]
    	blne	preempt_schedule
    	mov	pc, lr
    
    The problem is that the TIF_NEED_RESCHED flag is loaded _before_ the
    preemption count is stored back, hence any interrupt coming within that
    3 instruction window causing TIF_NEED_RESCHED to be set won't be
    seen and scheduling won't happen as it should.
    
    Nothing currently prevents gcc from performing that reordering.  There
    is already a barrier() before the decrement of the preemption count, but
    another one is needed between this and the TIF_NEED_RESCHED flag test
    for proper code ordering.
    Signed-off-by: default avatarNicolas Pitre <nico@cam.org>
    Acked-by: default avatarNick Piggin <nickpiggin@yahoo.com.au>
    Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
    d6f02913
preempt.h 1.44 KB