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