aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Oberparleiter2022-09-28 15:34:33 +0200
committerVasily Gorbik2022-10-10 10:15:10 +0200
commitf3e59ff348c077a6afd4edb23d7e69e9cba62fdc (patch)
tree0e066cba6a6c804ee71bba2a2bedac68e8afaf37
parent03785a69ae47a17fe57fee31058fef7cd3042977 (diff)
s390/vmur: remove unnecessary BUG statement
An existing BUG statement in vmur's interrupt handler triggers if: 1. An online vmur device is removed (e.g. due to driver unload, manual unbind or channel-report words indicating hypervisor-side device removal) 2. Device deactivation fails due to firmware/hypervisor error, leaving subchannel enabled for interrupts + drvdata=NULL 3. Interrupt occurs This situation is highly unlikely and not a clear indication of a general system error that would warrant stopping the full Linux system. Also it can be prevented completely by clearing the interrupt handler when unsetting a vmur device's drvdata. Replace the BUG statement in vmur's interrupt handler by clearing the interrupt handler callback during device removal. Also move the initial setting of the interrupt handler callback under lock for consistency reasons. Reviewed-by: Sven Schnelle <svens@linux.ibm.com> Reviewed-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
-rw-r--r--drivers/s390/char/vmur.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c
index 68f49e2e964c..471f07ca5066 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -293,7 +293,6 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm,
return;
}
urd = dev_get_drvdata(&cdev->dev);
- BUG_ON(!urd);
/* On special conditions irb is an error pointer */
if (IS_ERR(irb))
urd->io_request_rc = PTR_ERR(irb);
@@ -809,7 +808,6 @@ static int ur_probe(struct ccw_device *cdev)
rc = -ENOMEM;
goto fail_urdev_put;
}
- cdev->handler = ur_int_handler;
/* validate virtual unit record device */
urd->class = get_urd_class(urd);
@@ -823,6 +821,7 @@ static int ur_probe(struct ccw_device *cdev)
}
spin_lock_irq(get_ccwdev_lock(cdev));
dev_set_drvdata(&cdev->dev, urd);
+ cdev->handler = ur_int_handler;
spin_unlock_irq(get_ccwdev_lock(cdev));
mutex_unlock(&vmur_mutex);
@@ -963,6 +962,7 @@ static void ur_remove(struct ccw_device *cdev)
spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
urdev_put(dev_get_drvdata(&cdev->dev));
dev_set_drvdata(&cdev->dev, NULL);
+ cdev->handler = NULL;
spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
mutex_unlock(&vmur_mutex);