|
Johannes Thumshirn |
2829fd |
From: Julian Wiedmann <jwi@linux.vnet.ibm.com>
|
|
Johannes Thumshirn |
2829fd |
Date: Mon, 5 Mar 2018 09:39:38 +0100
|
|
Johannes Thumshirn |
2829fd |
Subject: s390/qdio: don't retry EQBS after CCQ 96
|
|
Johannes Thumshirn |
2829fd |
Git-commit: dae55b6fef58530c13df074bcc182c096609339e
|
|
Johannes Thumshirn |
2829fd |
Patch-mainline: v4.17-rc1
|
|
Johannes Thumshirn |
2829fd |
References: bsc#1102088, LTC#169699
|
|
Johannes Thumshirn |
2829fd |
|
|
Johannes Thumshirn |
2829fd |
Immediate retry of EQBS after CCQ 96 means that we potentially misreport
|
|
Johannes Thumshirn |
2829fd |
the state of buffers inspected during the first EQBS call.
|
|
Johannes Thumshirn |
2829fd |
|
|
Johannes Thumshirn |
2829fd |
This occurs when
|
|
Johannes Thumshirn |
2829fd |
1. the first EQBS finds all inspected buffers still in the initial state
|
|
Johannes Thumshirn |
2829fd |
set by the driver (ie INPUT EMPTY or OUTPUT PRIMED),
|
|
Johannes Thumshirn |
2829fd |
2. the EQBS terminates early with CCQ 96, and
|
|
Johannes Thumshirn |
2829fd |
3. by the time that the second EQBS comes around, the state of those
|
|
Johannes Thumshirn |
2829fd |
previously inspected buffers has changed.
|
|
Johannes Thumshirn |
2829fd |
|
|
Johannes Thumshirn |
2829fd |
If the state reported by the second EQBS is 'driver-owned', all we know
|
|
Johannes Thumshirn |
2829fd |
is that the previous buffers are driver-owned now as well. But we can't
|
|
Johannes Thumshirn |
2829fd |
tell if they all have the same state. So for instance
|
|
Johannes Thumshirn |
2829fd |
- the second EQBS reports OUTPUT EMPTY, but any number of the previous
|
|
Johannes Thumshirn |
2829fd |
buffers could be OUTPUT ERROR by now,
|
|
Johannes Thumshirn |
2829fd |
- the second EQBS reports OUTPUT ERROR, but any number of the previous
|
|
Johannes Thumshirn |
2829fd |
buffers could be OUTPUT EMPTY by now.
|
|
Johannes Thumshirn |
2829fd |
|
|
Johannes Thumshirn |
2829fd |
Effectively, this can result in both over- and underreporting of errors.
|
|
Johannes Thumshirn |
2829fd |
|
|
Johannes Thumshirn |
2829fd |
If the state reported by the second EQBS is 'HW-owned', that doesn't
|
|
Johannes Thumshirn |
2829fd |
guarantee that the previous buffers have not been switched to
|
|
Johannes Thumshirn |
2829fd |
driver-owned in the mean time. So for instance
|
|
Johannes Thumshirn |
2829fd |
- the second EQBS reports INPUT EMPTY, but any number of the previous
|
|
Johannes Thumshirn |
2829fd |
buffers could be INPUT PRIMED (or INPUT ERROR) by now.
|
|
Johannes Thumshirn |
2829fd |
|
|
Johannes Thumshirn |
2829fd |
This would result in failure to process pending work on the queue. If
|
|
Johannes Thumshirn |
2829fd |
it's the final check before yielding initiative, this can cause
|
|
Johannes Thumshirn |
2829fd |
a (temporary) queue stall due to IRQ avoidance.
|
|
Johannes Thumshirn |
2829fd |
|
|
Johannes Thumshirn |
2829fd |
Fixes: 25f269f17316 ("[S390] qdio: EQBS retry after CCQ 96")
|
|
Johannes Thumshirn |
2829fd |
Cc: <stable@vger.kernel.org> #v3.2+
|
|
Johannes Thumshirn |
2829fd |
Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com>
|
|
Johannes Thumshirn |
2829fd |
Reviewed-by: Benjamin Block <bblock@linux.vnet.ibm.com>
|
|
Johannes Thumshirn |
2829fd |
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
|
|
Johannes Thumshirn |
2829fd |
Acked-by: Johannes Thumshirn <jthumshirn@suse.de>
|
|
Johannes Thumshirn |
2829fd |
---
|
|
Johannes Thumshirn |
2829fd |
drivers/s390/cio/qdio_main.c | 11 ++---------
|
|
Johannes Thumshirn |
2829fd |
1 file changed, 2 insertions(+), 9 deletions(-)
|
|
Johannes Thumshirn |
2829fd |
|
|
Johannes Thumshirn |
2829fd |
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
|
|
Johannes Thumshirn |
2829fd |
index 63c6e9cf958f..de647b7e17b1 100644
|
|
Johannes Thumshirn |
2829fd |
--- a/drivers/s390/cio/qdio_main.c
|
|
Johannes Thumshirn |
2829fd |
+++ b/drivers/s390/cio/qdio_main.c
|
|
Johannes Thumshirn |
2829fd |
@@ -128,7 +128,7 @@ static inline int qdio_check_ccq(struct qdio_q *q, unsigned int ccq)
|
|
Johannes Thumshirn |
2829fd |
static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state,
|
|
Johannes Thumshirn |
2829fd |
int start, int count, int auto_ack)
|
|
Johannes Thumshirn |
2829fd |
{
|
|
Johannes Thumshirn |
2829fd |
- int rc, tmp_count = count, tmp_start = start, nr = q->nr, retried = 0;
|
|
Johannes Thumshirn |
2829fd |
+ int rc, tmp_count = count, tmp_start = start, nr = q->nr;
|
|
Johannes Thumshirn |
2829fd |
unsigned int ccq = 0;
|
|
Johannes Thumshirn |
2829fd |
|
|
Johannes Thumshirn |
2829fd |
qperf_inc(q, eqbs);
|
|
Johannes Thumshirn |
2829fd |
@@ -151,14 +151,7 @@ static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state,
|
|
Johannes Thumshirn |
2829fd |
qperf_inc(q, eqbs_partial);
|
|
Johannes Thumshirn |
2829fd |
DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, "EQBS part:%02x",
|
|
Johannes Thumshirn |
2829fd |
tmp_count);
|
|
Johannes Thumshirn |
2829fd |
- /*
|
|
Johannes Thumshirn |
2829fd |
- * Retry once, if that fails bail out and process the
|
|
Johannes Thumshirn |
2829fd |
- * extracted buffers before trying again.
|
|
Johannes Thumshirn |
2829fd |
- */
|
|
Johannes Thumshirn |
2829fd |
- if (!retried++)
|
|
Johannes Thumshirn |
2829fd |
- goto again;
|
|
Johannes Thumshirn |
2829fd |
- else
|
|
Johannes Thumshirn |
2829fd |
- return count - tmp_count;
|
|
Johannes Thumshirn |
2829fd |
+ return count - tmp_count;
|
|
Johannes Thumshirn |
2829fd |
}
|
|
Johannes Thumshirn |
2829fd |
|
|
Johannes Thumshirn |
2829fd |
DBF_ERROR("%4x EQBS ERROR", SCH_NO(q));
|
|
Johannes Thumshirn |
2829fd |
|