lkml.org 
[lkml]   [2015]   [Jan]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.12 141/176] pinctrl: Fix two deadlocks
    Date
    From: Jim Lin <jilin@nvidia.com>

    3.12-stable review patch. If anyone has any objections, please let me know.

    ===============

    commit db93facfb0ef542aa5d8079e47580b3e669a4d82 upstream.

    This patch is to fix two deadlock cases.
    Deadlock 1:
    CPU #1
    pinctrl_register-> pinctrl_get ->
    create_pinctrl
    (Holding lock pinctrl_maps_mutex)
    -> get_pinctrl_dev_from_devname
    (Trying to acquire lock pinctrldev_list_mutex)
    CPU #0
    pinctrl_unregister
    (Holding lock pinctrldev_list_mutex)
    -> pinctrl_put ->> pinctrl_free ->
    pinctrl_dt_free_maps -> pinctrl_unregister_map
    (Trying to acquire lock pinctrl_maps_mutex)

    Simply to say
    CPU#1 is holding lock A and trying to acquire lock B,
    CPU#0 is holding lock B and trying to acquire lock A.

    Deadlock 2:
    CPU #3
    pinctrl_register-> pinctrl_get ->
    create_pinctrl
    (Holding lock pinctrl_maps_mutex)
    -> get_pinctrl_dev_from_devname
    (Trying to acquire lock pinctrldev_list_mutex)
    CPU #2
    pinctrl_unregister
    (Holding lock pctldev->mutex)
    -> pinctrl_put ->> pinctrl_free ->
    pinctrl_dt_free_maps -> pinctrl_unregister_map
    (Trying to acquire lock pinctrl_maps_mutex)
    CPU #0
    tegra_gpio_request
    (Holding lock pinctrldev_list_mutex)
    -> pinctrl_get_device_gpio_range
    (Trying to acquire lock pctldev->mutex)

    Simply to say
    CPU#3 is holding lock A and trying to acquire lock D,
    CPU#2 is holding lock B and trying to acquire lock A,
    CPU#0 is holding lock D and trying to acquire lock B.

    Signed-off-by: Jim Lin <jilin@nvidia.com>
    Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
    Signed-off-by: Jiri Slaby <jslaby@suse.cz>
    ---
    drivers/pinctrl/core.c | 5 +++--
    1 file changed, 3 insertions(+), 2 deletions(-)

    diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
    index a1ffae4c3770..260a2551d612 100644
    --- a/drivers/pinctrl/core.c
    +++ b/drivers/pinctrl/core.c
    @@ -1796,14 +1796,15 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev)
    if (pctldev == NULL)
    return;

    - mutex_lock(&pinctrldev_list_mutex);
    mutex_lock(&pctldev->mutex);
    -
    pinctrl_remove_device_debugfs(pctldev);
    + mutex_unlock(&pctldev->mutex);

    if (!IS_ERR(pctldev->p))
    pinctrl_put(pctldev->p);

    + mutex_lock(&pinctrldev_list_mutex);
    + mutex_lock(&pctldev->mutex);
    /* TODO: check that no pinmuxes are still active? */
    list_del(&pctldev->node);
    /* Destroy descriptor tree */
    --
    2.2.2


    \
     
     \ /
      Last update: 2015-01-29 11:41    [W:3.485 / U:0.128 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site