lkml.org 
[lkml]   [2021]   [Jul]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.12 076/700] s390/cio: dont call css_wait_for_slow_path() inside a lock
    Date
    From: Vineeth Vijayan <vneethv@linux.ibm.com>

    commit c749d8c018daf5fba6dfac7b6c5c78b27efd7d65 upstream.

    Currently css_wait_for_slow_path() gets called inside the chp->lock.
    The path-verification-loop of slowpath inside this lock could lead to
    deadlock as reported by the lockdep validator.

    The ccw_device_get_chp_desc() during the instance of a device-set-online
    would try to acquire the same 'chp->lock' to read the chp->desc.
    The instance of this function can get called from multiple scenario,
    like probing or setting-device online manually. This could, in some
    corner-cases lead to the deadlock.

    lockdep validator reported this as,

    CPU0 CPU1
    ---- ----
    lock(&chp->lock);
    lock(kn->active#43);
    lock(&chp->lock);
    lock((wq_completion)cio);

    The chp->lock was introduced to serialize the access of struct
    channel_path. This lock is not needed for the css_wait_for_slow_path()
    function, so invoke the slow-path function outside this lock.

    Fixes: b730f3a93395 ("[S390] cio: add lock to struct channel_path")
    Cc: <stable@vger.kernel.org>
    Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
    Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com>
    Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/s390/cio/chp.c | 3 +++
    drivers/s390/cio/chsc.c | 2 --
    2 files changed, 3 insertions(+), 2 deletions(-)

    --- a/drivers/s390/cio/chp.c
    +++ b/drivers/s390/cio/chp.c
    @@ -255,6 +255,9 @@ static ssize_t chp_status_write(struct d
    if (!num_args)
    return count;

    + /* Wait until previous actions have settled. */
    + css_wait_for_slow_path();
    +
    if (!strncasecmp(cmd, "on", 2) || !strcmp(cmd, "1")) {
    mutex_lock(&cp->lock);
    error = s390_vary_chpid(cp->chpid, 1);
    --- a/drivers/s390/cio/chsc.c
    +++ b/drivers/s390/cio/chsc.c
    @@ -801,8 +801,6 @@ int chsc_chp_vary(struct chp_id chpid, i
    {
    struct channel_path *chp = chpid_to_chp(chpid);

    - /* Wait until previous actions have settled. */
    - css_wait_for_slow_path();
    /*
    * Redo PathVerification on the devices the chpid connects to
    */

    \
     
     \ /
      Last update: 2021-07-12 09:29    [W:2.275 / U:0.256 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site