• Igor Pylypiv's avatar
    Revert "module, async: async_synchronize_full() on module init iff async is used" · 67d6212a
    Igor Pylypiv authored
    This reverts commit 774a1221.
    
    We need to finish all async code before the module init sequence is
    done.  In the reverted commit the PF_USED_ASYNC flag was added to mark a
    thread that called async_schedule().  Then the PF_USED_ASYNC flag was
    used to determine whether or not async_synchronize_full() needs to be
    invoked.  This works when modprobe thread is calling async_schedule(),
    but it does not work if module dispatches init code to a worker thread
    which then calls async_schedule().
    
    For example, PCI driver probing is invoked from a worker thread based on
    a node where device is attached:
    
    	if (cpu < nr_cpu_ids)
    		error = work_on_cpu(cpu, local_pci_probe, &ddi);
    	else
    		error = local_pci_probe(&ddi);
    
    We end up in a situation where a worker thread gets the PF_USED_ASYNC
    flag set instead of the modprobe thread.  As a result,
    async_synchronize_full() is not invoked and modprobe completes without
    waiting for the async code to finish.
    
    The issue was discovered while loading the pm80xx driver:
    (scsi_mod.scan=async)
    
    modprobe pm80xx                      worker
    ...
      do_init_module()
      ...
        pci_call_probe()
          work_on_cpu(local_pci_probe)
                                         local_pci_probe()
                                           pm8001_pci_probe()
                                             scsi_scan_host()
                                               async_schedule()
                                               worker->flags |= PF_USED_ASYNC;
                                         ...
          < return from worker >
      ...
      if (current->flags & PF_USED_ASYNC) <--- false
      	async_synchronize_full();
    
    Commit 21c3c5d2 ("block: don't request module during elevator init")
    fixed the deadlock issue which the reverted commit 774a1221
    ("module, async: async_synchronize_full() on module init iff async is
    used") tried to fix.
    
    Since commit 0fdff3ec ("async, kmod: warn on synchronous
    request_module() from async workers") synchronous module loading from
    async is not allowed.
    
    Given that the original deadlock issue is fixed and it is no longer
    allowed to call synchronous request_module() from async we can remove
    PF_USED_ASYNC flag to make module init consistently invoke
    async_synchronize_full() unless async module probe is requested.
    Signed-off-by: default avatarIgor Pylypiv <ipylypiv@google.com>
    Reviewed-by: default avatarChangyuan Lyu <changyuanl@google.com>
    Reviewed-by: default avatarLuis Chamberlain <mcgrof@kernel.org>
    Acked-by: default avatarTejun Heo <tj@kernel.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    67d6212a
module.c 121 KB