diff options
author | Julian Wiedmann <jwi@linux.ibm.com> | 2019-04-26 03:37:41 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2019-05-08 09:01:23 -0400 |
commit | a698e1372800b7e5dde2e461c1d3948c2e06032a (patch) | |
tree | 2570ab3dd23f29f1f61a774ac7eb04e17b3aa528 | |
parent | 5a19d67027283c77f51b971485c3e579d94b5a2f (diff) |
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 <jwi@linux.ibm.com>
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | drivers/s390/cio/qdio_main.c | 11 |
1 files changed, 9 insertions, 2 deletions
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, | |||
205 | int auto_ack, int merge_pending) | 205 | int auto_ack, int merge_pending) |
206 | { | 206 | { |
207 | unsigned char __state = 0; | 207 | unsigned char __state = 0; |
208 | int i; | 208 | int i = 1; |
209 | 209 | ||
210 | if (is_qebsm(q)) | 210 | if (is_qebsm(q)) |
211 | return qdio_do_eqbs(q, state, bufnr, count, auto_ack); | 211 | return qdio_do_eqbs(q, state, bufnr, count, auto_ack); |
212 | 212 | ||
213 | /* get initial state: */ | 213 | /* get initial state: */ |
214 | __state = q->slsb.val[bufnr]; | 214 | __state = q->slsb.val[bufnr]; |
215 | |||
216 | /* Bail out early if there is no work on the queue: */ | ||
217 | if (__state & SLSB_OWNER_CU) | ||
218 | goto out; | ||
219 | |||
215 | if (merge_pending && __state == SLSB_P_OUTPUT_PENDING) | 220 | if (merge_pending && __state == SLSB_P_OUTPUT_PENDING) |
216 | __state = SLSB_P_OUTPUT_EMPTY; | 221 | __state = SLSB_P_OUTPUT_EMPTY; |
217 | 222 | ||
218 | for (i = 1; i < count; i++) { | 223 | for (; i < count; i++) { |
219 | bufnr = next_buf(bufnr); | 224 | bufnr = next_buf(bufnr); |
220 | 225 | ||
221 | /* merge PENDING into EMPTY: */ | 226 | /* merge PENDING into EMPTY: */ |
@@ -228,6 +233,8 @@ static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr, | |||
228 | if (q->slsb.val[bufnr] != __state) | 233 | if (q->slsb.val[bufnr] != __state) |
229 | break; | 234 | break; |
230 | } | 235 | } |
236 | |||
237 | out: | ||
231 | *state = __state; | 238 | *state = __state; |
232 | return i; | 239 | return i; |
233 | } | 240 | } |