From 3060781f2664d34af641247aeac62696405a3fde Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Mon, 1 Apr 2019 10:08:08 +0200 Subject: s390/qdio: allow to scan all Output SBALs in one go Old code restricted the number of inspected SBALs to QDIO_MAX_BUFFERS_PER_Q - 1, as otherwise the first_to_check and first_to_kick cursors could overlap. Subsequent code would then assume that there was no progress on the queue, when in fact _all_ SBALs on the queue were ready-to-process. This limitation no longer applies, so allow the queue-scan code to inspect all SBALs on the queue. Note that qeth requires an additional patch ("s390/qeth: stop/wake TX queues based on their fill level"), to avoid potential queue stalls when all 128 SBALs are reported as ready-to-process. Signed-off-by: Julian Wiedmann Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/qdio_main.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers/s390/cio/qdio_main.c') diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index cfce255521ac..957c2a8dfc13 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -719,11 +719,7 @@ static int get_outbound_buffer_frontier(struct qdio_q *q, unsigned int start) multicast_outbound(q))) qdio_siga_sync_q(q); - /* - * Don't check 128 buffers, as otherwise qdio_inbound_q_moved - * would return 0. - */ - count = min(atomic_read(&q->nr_buf_used), QDIO_MAX_BUFFERS_MASK); + count = atomic_read(&q->nr_buf_used); if (!count) return 0; -- cgit v1.2.3 From 5a19d67027283c77f51b971485c3e579d94b5a2f Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Fri, 26 Apr 2019 09:30:11 +0200 Subject: s390/qdio: use get_buf_state() in debug_get_buf_state() For a 1-SBAL state inspection, use the corresponding helper. No functional change, just reducing the number of immediate callers to get_buf_states(). Signed-off-by: Julian Wiedmann Reviewed-by: Jens Remus Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/qdio_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/s390/cio/qdio_main.c') diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 957c2a8dfc13..be93172555ec 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -382,7 +382,7 @@ int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr, { if (need_siga_sync(q)) qdio_siga_sync_q(q); - return get_buf_states(q, bufnr, state, 1, 0, 0); + return get_buf_state(q, bufnr, state, 0); } static inline void qdio_stop_polling(struct qdio_q *q) -- cgit v1.2.3 From a698e1372800b7e5dde2e461c1d3948c2e06032a Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Fri, 26 Apr 2019 09:37:41 +0200 Subject: s390/qdio: optimize state inspection of HW-owned SBALs When get_buf_states() gets called with count > 1, it scans the corresponding number of SBAL states until it encounters a mismatch. But when these SBALs are in a HW-owned state, the callers don't actually care _how many_ such SBALs are on the queue. If we can't process the first SBAL, we can't process any of the following SBALs either. So when the first SBAL is HW-owned, skip the scan of the remaining SBALs and thus save some CPU time. Signed-off-by: Julian Wiedmann Reviewed-by: Jens Remus Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/qdio_main.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/s390/cio/qdio_main.c') diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index be93172555ec..7b7620de2acd 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -205,17 +205,22 @@ static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr, int auto_ack, int merge_pending) { unsigned char __state = 0; - int i; + int i = 1; if (is_qebsm(q)) return qdio_do_eqbs(q, state, bufnr, count, auto_ack); /* get initial state: */ __state = q->slsb.val[bufnr]; + + /* Bail out early if there is no work on the queue: */ + if (__state & SLSB_OWNER_CU) + goto out; + if (merge_pending && __state == SLSB_P_OUTPUT_PENDING) __state = SLSB_P_OUTPUT_EMPTY; - for (i = 1; i < count; i++) { + for (; i < count; i++) { bufnr = next_buf(bufnr); /* merge PENDING into EMPTY: */ @@ -228,6 +233,8 @@ static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr, if (q->slsb.val[bufnr] != __state) break; } + +out: *state = __state; return i; } -- cgit v1.2.3