Commit f3e59ff3 authored by Peter Oberparleiter's avatar Peter Oberparleiter Committed by Vasily Gorbik

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: default avatarSven Schnelle <svens@linux.ibm.com>
Reviewed-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarPeter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent 03785a69
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment