aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulian Wiedmann <jwi@linux.vnet.ibm.com>2016-11-21 07:37:48 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-03-14 22:02:41 -0400
commit5cec5e32ba5637076aa8f06d61f89cecd877b78e (patch)
treecfe4be376c58100c90537f2b71277578e3c6fab9
parent519b6cead21ee66ad7825750ce8aefaf64dd6792 (diff)
s390/qdio: clear DSCI prior to scanning multiple input queues
commit 1e4a382fdc0ba8d1a85b758c0811de3a3631085e upstream. For devices with multiple input queues, tiqdio_call_inq_handlers() iterates over all input queues and clears the device's DSCI during each iteration. If the DSCI is re-armed during one of the later iterations, we therefore do not scan the previous queues again. The re-arming also raises a new adapter interrupt. But its handler does not trigger a rescan for the device, as the DSCI has already been erroneously cleared. This can result in queue stalls on devices with multiple input queues. Fix it by clearing the DSCI just once, prior to scanning the queues. As the code is moved in front of the loop, we also need to access the DSCI directly (ie irq->dsci) instead of going via each queue's parent pointer to the same irq. This is not a functional change, and a follow-up patch will clean up the other users. In practice, this bug only affects CQ-enabled HiperSockets devices, ie. devices with sysfs-attribute "hsuid" set. Setting a hsuid is needed for AF_IUCV socket applications that use HiperSockets communication. Fixes: 104ea556ee7f ("qdio: support asynchronous delivery of storage blocks") Reviewed-by: Ursula Braun <ubraun@linux.vnet.ibm.com> Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/s390/cio/qdio_thinint.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index 5d06253c2a7a..30e9fbbff051 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -147,11 +147,11 @@ static inline void tiqdio_call_inq_handlers(struct qdio_irq *irq)
147 struct qdio_q *q; 147 struct qdio_q *q;
148 int i; 148 int i;
149 149
150 for_each_input_queue(irq, q, i) { 150 if (!references_shared_dsci(irq) &&
151 if (!references_shared_dsci(irq) && 151 has_multiple_inq_on_dsci(irq))
152 has_multiple_inq_on_dsci(irq)) 152 xchg(irq->dsci, 0);
153 xchg(q->irq_ptr->dsci, 0);
154 153
154 for_each_input_queue(irq, q, i) {
155 if (q->u.in.queue_start_poll) { 155 if (q->u.in.queue_start_poll) {
156 /* skip if polling is enabled or already in work */ 156 /* skip if polling is enabled or already in work */
157 if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED, 157 if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,