• Tejun Heo's avatar
    module, async: async_synchronize_full() on module init iff async is used · 774a1221
    Tejun Heo authored
    If the default iosched is built as module, the kernel may deadlock
    while trying to load the iosched module on device probe if the probing
    was running off async.  This is because async_synchronize_full() at
    the end of module init ends up waiting for the async job which
    initiated the module loading.
    
     async A				modprobe
    
     1. finds a device
     2. registers the block device
     3. request_module(default iosched)
    					4. modprobe in userland
    					5. load and init module
    					6. async_synchronize_full()
    
    Async A waits for modprobe to finish in request_module() and modprobe
    waits for async A to finish in async_synchronize_full().
    
    Because there's no easy to track dependency once control goes out to
    userland, implementing properly nested flushing is difficult.  For
    now, make module init perform async_synchronize_full() iff module init
    has queued async jobs as suggested by Linus.
    
    This avoids the described deadlock because iosched module doesn't use
    async and thus wouldn't invoke async_synchronize_full().  This is
    hacky and incomplete.  It will deadlock if async module loading nests;
    however, this works around the known problem case and seems to be the
    best of bad options.
    
    For more details, please refer to the following thread.
    
      http://thread.gmane.org/gmane.linux.kernel/1420814Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Reported-by: default avatarAlex Riesen <raa.lkml@gmail.com>
    Tested-by: default avatarMing Lei <ming.lei@canonical.com>
    Tested-by: default avatarAlex Riesen <raa.lkml@gmail.com>
    Cc: Arjan van de Ven <arjan@linux.intel.com>
    Cc: Jens Axboe <axboe@kernel.dk>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    774a1221
module.c 94.4 KB