Message ID | 1557416191-21935-2-git-send-email-frank.heimes@canonical.com |
---|---|
State | New |
Headers | show |
Series | [SRU,Bionic,1/1] s390/qdio: clear intparm during shutdown | expand |
On 5/9/19 8:36 AM, frank.heimes@canonical.com wrote: > From: Julian Wiedmann <jwi@linux.vnet.ibm.com> > > BugLink: https://bugs.launchpad.net/bugs/1828394 > > During shutdown, qdio returns its ccw device back to control by the > upper-layer driver. But there is a remote chance that by the time where the > IRQ handler gets switched back, the interrupt for the preceding > ccw_device_{clear,halt} hasn't been presented yet. > Upper-layer drivers would then need to handle this IRQ - and since the IO > is issued with an intparm, it could very well be confused with whatever > intparm mechanism the driver uses itself (eg intparm == request address). > > So when switching over the IRQ handler, also clear the intparm and have > upper-layer drivers deal with any such delayed interrupt as if it was > unsolicited. > > Suggested-by: Sebastian Ott <sebott@linux.vnet.ibm.com> > Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com> > Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> > (cherry picked from commit 89286320a236d245834075fa13adb0bdd827ecaa) > Signed-off-by: Frank Heimes <frank.heimes@canonical.com> > --- Nicely documented description of the problem. Acked-by: Connor Kuehl <connor.kuehl@canonical.com> > drivers/s390/cio/qdio_main.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c > index d76df58..8842be6 100644 > --- a/drivers/s390/cio/qdio_main.c > +++ b/drivers/s390/cio/qdio_main.c > @@ -1218,8 +1218,10 @@ int qdio_shutdown(struct ccw_device *cdev, int how) > qdio_shutdown_thinint(irq_ptr); > > /* restore interrupt handler */ > - if ((void *)cdev->handler == (void *)qdio_int_handler) > + if ((void *)cdev->handler == (void *)qdio_int_handler) { > cdev->handler = irq_ptr->orig_handler; > + cdev->private->intparm = 0; > + } > spin_unlock_irq(get_ccwdev_lock(cdev)); > > qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE); >
On 5/9/19 5:36 PM, frank.heimes@canonical.com wrote: > From: Julian Wiedmann <jwi@linux.vnet.ibm.com> > > BugLink: https://bugs.launchpad.net/bugs/1828394 > > During shutdown, qdio returns its ccw device back to control by the > upper-layer driver. But there is a remote chance that by the time where the > IRQ handler gets switched back, the interrupt for the preceding > ccw_device_{clear,halt} hasn't been presented yet. > Upper-layer drivers would then need to handle this IRQ - and since the IO > is issued with an intparm, it could very well be confused with whatever > intparm mechanism the driver uses itself (eg intparm == request address). > > So when switching over the IRQ handler, also clear the intparm and have > upper-layer drivers deal with any such delayed interrupt as if it was > unsolicited. > > Suggested-by: Sebastian Ott <sebott@linux.vnet.ibm.com> > Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com> > Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> > (cherry picked from commit 89286320a236d245834075fa13adb0bdd827ecaa) > Signed-off-by: Frank Heimes <frank.heimes@canonical.com> Clean cherry-pick, limited to platform specific driver. Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com> > --- > drivers/s390/cio/qdio_main.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c > index d76df58..8842be6 100644 > --- a/drivers/s390/cio/qdio_main.c > +++ b/drivers/s390/cio/qdio_main.c > @@ -1218,8 +1218,10 @@ int qdio_shutdown(struct ccw_device *cdev, int how) > qdio_shutdown_thinint(irq_ptr); > > /* restore interrupt handler */ > - if ((void *)cdev->handler == (void *)qdio_int_handler) > + if ((void *)cdev->handler == (void *)qdio_int_handler) { > cdev->handler = irq_ptr->orig_handler; > + cdev->private->intparm = 0; > + } > spin_unlock_irq(get_ccwdev_lock(cdev)); > > qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE); >
On 5/9/19 5:36 PM, frank.heimes@canonical.com wrote: > From: Julian Wiedmann <jwi@linux.vnet.ibm.com> > > BugLink: https://bugs.launchpad.net/bugs/1828394 > > During shutdown, qdio returns its ccw device back to control by the > upper-layer driver. But there is a remote chance that by the time where the > IRQ handler gets switched back, the interrupt for the preceding > ccw_device_{clear,halt} hasn't been presented yet. > Upper-layer drivers would then need to handle this IRQ - and since the IO > is issued with an intparm, it could very well be confused with whatever > intparm mechanism the driver uses itself (eg intparm == request address). > > So when switching over the IRQ handler, also clear the intparm and have > upper-layer drivers deal with any such delayed interrupt as if it was > unsolicited. > > Suggested-by: Sebastian Ott <sebott@linux.vnet.ibm.com> > Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com> > Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> > (cherry picked from commit 89286320a236d245834075fa13adb0bdd827ecaa) > Signed-off-by: Frank Heimes <frank.heimes@canonical.com> > --- > drivers/s390/cio/qdio_main.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c > index d76df58..8842be6 100644 > --- a/drivers/s390/cio/qdio_main.c > +++ b/drivers/s390/cio/qdio_main.c > @@ -1218,8 +1218,10 @@ int qdio_shutdown(struct ccw_device *cdev, int how) > qdio_shutdown_thinint(irq_ptr); > > /* restore interrupt handler */ > - if ((void *)cdev->handler == (void *)qdio_int_handler) > + if ((void *)cdev->handler == (void *)qdio_int_handler) { > cdev->handler = irq_ptr->orig_handler; > + cdev->private->intparm = 0; > + } > spin_unlock_irq(get_ccwdev_lock(cdev)); > > qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE); > Applied to bionic/master-next branch. Thanks, Kleber
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index d76df58..8842be6 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -1218,8 +1218,10 @@ int qdio_shutdown(struct ccw_device *cdev, int how) qdio_shutdown_thinint(irq_ptr); /* restore interrupt handler */ - if ((void *)cdev->handler == (void *)qdio_int_handler) + if ((void *)cdev->handler == (void *)qdio_int_handler) { cdev->handler = irq_ptr->orig_handler; + cdev->private->intparm = 0; + } spin_unlock_irq(get_ccwdev_lock(cdev)); qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);