Skip to content
Snippets Groups Projects
Forked from Librem5 / linux
Loading
  • Grant Likely's avatar
    58b116bc
    drivercore: deferral race condition fix · 58b116bc
    Grant Likely authored
    
    When the kernel is built with CONFIG_PREEMPT it is possible to reach a state
    when all modules loaded but some driver still stuck in the deferred list
    and there is a need for external event to kick the deferred queue to probe
    these drivers.
    
    The issue has been observed on embedded systems with CONFIG_PREEMPT enabled,
    audio support built as modules and using nfsroot for root filesystem.
    
    The following log fragment shows such sequence when all audio modules
    were loaded but the sound card is not present since the machine driver has
    failed to probe due to missing dependency during it's probe.
    The board is am335x-evmsk (McASP<->tlv320aic3106 codec) with davinci-evm
    machine driver:
    
    ...
    [   12.615118] davinci-mcasp 4803c000.mcasp: davinci_mcasp_probe: ENTER
    [   12.719969] davinci_evm sound.3: davinci_evm_probe: ENTER
    [   12.725753] davinci_evm sound.3: davinci_evm_probe: snd_soc_register_card
    [   12.753846] davinci-mcasp 4803c000.mcasp: davinci_mcasp_probe: snd_soc_register_component
    [   12.922051] davinci-mcasp 4803c000.mcasp: davinci_mcasp_probe: snd_soc_register_component DONE
    [   12.950839] davinci_evm sound.3: ASoC: platform (null) not registered
    [   12.957898] davinci_evm sound.3: davinci_evm_probe: snd_soc_register_card DONE (-517)
    [   13.099026] davinci-mcasp 4803c000.mcasp: Kicking the deferred list
    [   13.177838] davinci-mcasp 4803c000.mcasp: really_probe: probe_count = 2
    [   13.194130] davinci_evm sound.3: snd_soc_register_card failed (-517)
    [   13.346755] davinci_mcasp_driver_init: LEAVE
    [   13.377446] platform sound.3: Driver davinci_evm requests probe deferral
    [   13.592527] platform sound.3: really_probe: probe_count = 0
    
    In the log the machine driver enters it's probe at 12.719969 (this point it
    has been removed from the deferred lists). McASP driver already executing
    it's probing (since 12.615118).
    The machine driver tries to construct the sound card (12.950839) but did
    not found one of the components so it fails. After this McASP driver
    registers all the ASoC components (the machine driver still in it's probe
    function after it failed to construct the card) and the deferred work is
    prepared at 13.099026 (note that this time the machine driver is not in the
    lists so it is not going to be handled when the work is executing).
    Lastly the machine driver exit from it's probe and the core places it to
    the deferred list but there will be no other driver going to load and the
    deferred queue is not going to be kicked again - till we have external event
    like connecting USB stick, etc.
    
    The proposed solution is to try the deferred queue once more when the last
    driver is asking for deferring and we had drivers loaded while this last
    driver was probing.
    
    This way we can avoid drivers stuck in the deferred queue.
    
    Signed-off-by: default avatarGrant Likely <grant.likely@linaro.org>
    Reviewed-by: default avatarPeter Ujfalusi <peter.ujfalusi@ti.com>
    Tested-by: default avatarPeter Ujfalusi <peter.ujfalusi@ti.com>
    Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    Cc: Mark Brown <broonie@kernel.org>
    Cc: Stable <stable@vger.kernel.org> # v3.4+
    58b116bc
    History
    drivercore: deferral race condition fix
    Grant Likely authored
    
    When the kernel is built with CONFIG_PREEMPT it is possible to reach a state
    when all modules loaded but some driver still stuck in the deferred list
    and there is a need for external event to kick the deferred queue to probe
    these drivers.
    
    The issue has been observed on embedded systems with CONFIG_PREEMPT enabled,
    audio support built as modules and using nfsroot for root filesystem.
    
    The following log fragment shows such sequence when all audio modules
    were loaded but the sound card is not present since the machine driver has
    failed to probe due to missing dependency during it's probe.
    The board is am335x-evmsk (McASP<->tlv320aic3106 codec) with davinci-evm
    machine driver:
    
    ...
    [   12.615118] davinci-mcasp 4803c000.mcasp: davinci_mcasp_probe: ENTER
    [   12.719969] davinci_evm sound.3: davinci_evm_probe: ENTER
    [   12.725753] davinci_evm sound.3: davinci_evm_probe: snd_soc_register_card
    [   12.753846] davinci-mcasp 4803c000.mcasp: davinci_mcasp_probe: snd_soc_register_component
    [   12.922051] davinci-mcasp 4803c000.mcasp: davinci_mcasp_probe: snd_soc_register_component DONE
    [   12.950839] davinci_evm sound.3: ASoC: platform (null) not registered
    [   12.957898] davinci_evm sound.3: davinci_evm_probe: snd_soc_register_card DONE (-517)
    [   13.099026] davinci-mcasp 4803c000.mcasp: Kicking the deferred list
    [   13.177838] davinci-mcasp 4803c000.mcasp: really_probe: probe_count = 2
    [   13.194130] davinci_evm sound.3: snd_soc_register_card failed (-517)
    [   13.346755] davinci_mcasp_driver_init: LEAVE
    [   13.377446] platform sound.3: Driver davinci_evm requests probe deferral
    [   13.592527] platform sound.3: really_probe: probe_count = 0
    
    In the log the machine driver enters it's probe at 12.719969 (this point it
    has been removed from the deferred lists). McASP driver already executing
    it's probing (since 12.615118).
    The machine driver tries to construct the sound card (12.950839) but did
    not found one of the components so it fails. After this McASP driver
    registers all the ASoC components (the machine driver still in it's probe
    function after it failed to construct the card) and the deferred work is
    prepared at 13.099026 (note that this time the machine driver is not in the
    lists so it is not going to be handled when the work is executing).
    Lastly the machine driver exit from it's probe and the core places it to
    the deferred list but there will be no other driver going to load and the
    deferred queue is not going to be kicked again - till we have external event
    like connecting USB stick, etc.
    
    The proposed solution is to try the deferred queue once more when the last
    driver is asking for deferring and we had drivers loaded while this last
    driver was probing.
    
    This way we can avoid drivers stuck in the deferred queue.
    
    Signed-off-by: default avatarGrant Likely <grant.likely@linaro.org>
    Reviewed-by: default avatarPeter Ujfalusi <peter.ujfalusi@ti.com>
    Tested-by: default avatarPeter Ujfalusi <peter.ujfalusi@ti.com>
    Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    Cc: Mark Brown <broonie@kernel.org>
    Cc: Stable <stable@vger.kernel.org> # v3.4+
dd.c 16.67 KiB
/*
 * drivers/base/dd.c - The core device/driver interactions.
 *
 * This file contains the (sometimes tricky) code that controls the
 * interactions between devices and drivers, which primarily includes
 * driver binding and unbinding.
 *
 * All of this code used to exist in drivers/base/bus.c, but was
 * relocated to here in the name of compartmentalization (since it wasn't
 * strictly code just for the 'struct bus_type'.
 *
 * Copyright (c) 2002-5 Patrick Mochel
 * Copyright (c) 2002-3 Open Source Development Labs
 * Copyright (c) 2007-2009 Greg Kroah-Hartman <gregkh@suse.de>
 * Copyright (c) 2007-2009 Novell Inc.
 *
 * This file is released under the GPLv2
 */

#include <linux/device.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/wait.h>
#include <linux/async.h>
#include <linux/pm_runtime.h>
#include <linux/pinctrl/devinfo.h>

#include "base.h"
#include "power/power.h"

/*
 * Deferred Probe infrastructure.
 *
 * Sometimes driver probe order matters, but the kernel doesn't always have
 * dependency information which means some drivers will get probed before a
 * resource it depends on is available.  For example, an SDHCI driver may
 * first need a GPIO line from an i2c GPIO controller before it can be
 * initialized.  If a required resource is not available yet, a driver can
 * request probing to be deferred by returning -EPROBE_DEFER from its probe hook
 *
 * Deferred probe maintains two lists of devices, a pending list and an active
 * list.  A driver returning -EPROBE_DEFER causes the device to be added to the
 * pending list.  A successful driver probe will trigger moving all devices
 * from the pending to the active list so that the workqueue will eventually
 * retry them.
 *
 * The deferred_probe_mutex must be held any time the deferred_probe_*_list
 * of the (struct device*)->p->deferred_probe pointers are manipulated
 */
static DEFINE_MUTEX(deferred_probe_mutex);
static LIST_HEAD(deferred_probe_pending_list);
static LIST_HEAD(deferred_probe_active_list);
static struct workqueue_struct *deferred_wq;
static atomic_t deferred_trigger_count = ATOMIC_INIT(0);

/**
 * deferred_probe_work_func() - Retry probing devices in the active list.
 */
static void deferred_probe_work_func(struct work_struct *work)
{
	struct device *dev;
	struct device_private *private;
	/*
	 * This block processes every device in the deferred 'active' list.
	 * Each device is removed from the active list and passed to
	 * bus_probe_device() to re-attempt the probe.  The loop continues
	 * until every device in the active list is removed and retried.
	 *
	 * Note: Once the device is removed from the list and the mutex is