git: kernel - Fix SMP tsleep_interlock() vs wakeup() race

Matthew Dillon dillon at crater.dragonflybsd.org
Wed Aug 23 09:34:46 PDT 2017


commit e676ebdaf2554fecf34b17eb0a0a71a248fdadbf
Author: Matthew Dillon <dillon at apollo.backplane.com>
Date:   Wed Aug 23 09:28:50 2017 -0700

    kernel - Fix SMP tsleep_interlock() vs wakeup() race
    
    * Problem triggered by kern_mutex.c, probably only triggered by mutexes.
      The mutex sets state non-atomically and calls wakeup() with no
      intervening atomic op.  wakeup() loads the cpumask to wakeup
      non-atomically.  This can cause the wakeup() code to miss an
      interaction with the cpumask set by another cpu.
    
      cpu A:
    	set state			<-- sets state
    	wakeup()			<-- loads cpu mask non-atomically
    
      cpu B:
    	tsleep_interlock()		<-- sets cpu mask atomically
    	if (checkstate failed)		<-- checks state
    		tsleep()
    
    * Fix the problem by add a lfence() in the wakeup() code prior to
      loading the cpumask.  Even though I'm fairly sure only the kern_mutex.c
      code can causing this problem, putting the lfence in wakeup() is the
      safest mechanic.

Summary of changes:
 sys/kern/kern_synch.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/e676ebdaf2554fecf34b17eb0a0a71a248fdadbf


-- 
DragonFly BSD source repository



More information about the Commits mailing list