lkml.org 
[lkml]   [2015]   [Jan]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.14 97/98] s390/3215: fix hanging console issue
    Date
    3.14-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Martin Schwidefsky <schwidefsky@de.ibm.com>

    commit 26d766c60f4ea08cd14f0f3435a6db3d6cc2ae96 upstream.

    The ccw_device_start in raw3215_start_io can fail. raw3215_try_io
    does not check if the request could be started and removes any
    pending timer. This can leave the system in a hanging state.
    Check for pending request after raw3215_start_io and start a
    timer if necessary.

    Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/s390/char/con3215.c | 32 +++++++++++++++++---------------
    1 file changed, 17 insertions(+), 15 deletions(-)

    --- a/drivers/s390/char/con3215.c
    +++ b/drivers/s390/char/con3215.c
    @@ -288,12 +288,16 @@ static void raw3215_timeout(unsigned lon
    unsigned long flags;

    spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
    - if (raw->flags & RAW3215_TIMER_RUNS) {
    - del_timer(&raw->timer);
    - raw->flags &= ~RAW3215_TIMER_RUNS;
    - if (!(raw->port.flags & ASYNC_SUSPENDED)) {
    - raw3215_mk_write_req(raw);
    - raw3215_start_io(raw);
    + raw->flags &= ~RAW3215_TIMER_RUNS;
    + if (!(raw->port.flags & ASYNC_SUSPENDED)) {
    + raw3215_mk_write_req(raw);
    + raw3215_start_io(raw);
    + if ((raw->queued_read || raw->queued_write) &&
    + !(raw->flags & RAW3215_WORKING) &&
    + !(raw->flags & RAW3215_TIMER_RUNS)) {
    + raw->timer.expires = RAW3215_TIMEOUT + jiffies;
    + add_timer(&raw->timer);
    + raw->flags |= RAW3215_TIMER_RUNS;
    }
    }
    spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
    @@ -317,17 +321,15 @@ static inline void raw3215_try_io(struct
    (raw->flags & RAW3215_FLUSHING)) {
    /* execute write requests bigger than minimum size */
    raw3215_start_io(raw);
    - if (raw->flags & RAW3215_TIMER_RUNS) {
    - del_timer(&raw->timer);
    - raw->flags &= ~RAW3215_TIMER_RUNS;
    - }
    - } else if (!(raw->flags & RAW3215_TIMER_RUNS)) {
    - /* delay small writes */
    - raw->timer.expires = RAW3215_TIMEOUT + jiffies;
    - add_timer(&raw->timer);
    - raw->flags |= RAW3215_TIMER_RUNS;
    }
    }
    + if ((raw->queued_read || raw->queued_write) &&
    + !(raw->flags & RAW3215_WORKING) &&
    + !(raw->flags & RAW3215_TIMER_RUNS)) {
    + raw->timer.expires = RAW3215_TIMEOUT + jiffies;
    + add_timer(&raw->timer);
    + raw->flags |= RAW3215_TIMER_RUNS;
    + }
    }

    /*



    \
     
     \ /
      Last update: 2015-01-25 20:21    [W:2.391 / U:0.160 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site