From 8a943f6077a90adebfc4305cb66fcf08376d045c Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Tue, 5 Sep 2017 14:22:48 +0200 Subject: [PATCH] s390/cmf: set_schib_wait add timeout When enabling channel measurement fails with a busy condition we wait for the next interrupt to arrive before we retry the operation. For devices which usually don't create interrupts we wait forever. Although the waiting is done interruptible that behavior is not expected and confused some users. Abort the operation after a 10s timeout. Signed-off-by: Sebastian Ott Reviewed-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/cmf.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c index 220491d27ef47..be0b010ff1360 100644 --- a/drivers/s390/cio/cmf.c +++ b/drivers/s390/cio/cmf.c @@ -227,6 +227,7 @@ static void cmf_set_schib_release(struct kref *kref) } #define CMF_PENDING 1 +#define SET_SCHIB_TIMEOUT (10 * HZ) static int set_schib_wait(struct ccw_device *cdev, u32 mme, int mbfc, unsigned long address) @@ -263,19 +264,19 @@ static int set_schib_wait(struct ccw_device *cdev, u32 mme, cdev->private->state = DEV_STATE_CMFCHANGE; set_data->ret = CMF_PENDING; cdev->private->cmb_wait = set_data; - spin_unlock_irq(cdev->ccwlock); - if (wait_event_interruptible(set_data->wait, - set_data->ret != CMF_PENDING)) { - spin_lock_irq(cdev->ccwlock); + + ret = wait_event_interruptible_timeout(set_data->wait, + set_data->ret != CMF_PENDING, + SET_SCHIB_TIMEOUT); + spin_lock_irq(cdev->ccwlock); + if (ret <= 0) { if (set_data->ret == CMF_PENDING) { - set_data->ret = -ERESTARTSYS; + set_data->ret = (ret == 0) ? -ETIME : ret; if (cdev->private->state == DEV_STATE_CMFCHANGE) cdev->private->state = DEV_STATE_ONLINE; } - spin_unlock_irq(cdev->ccwlock); } - spin_lock_irq(cdev->ccwlock); cdev->private->cmb_wait = NULL; ret = set_data->ret; out_put: -- 2.39.5