aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulian Wiedmann <jwi@linux.ibm.com>2019-04-26 03:37:41 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2019-05-08 09:01:23 -0400
commita698e1372800b7e5dde2e461c1d3948c2e06032a (patch)
tree2570ab3dd23f29f1f61a774ac7eb04e17b3aa528
parent5a19d67027283c77f51b971485c3e579d94b5a2f (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.c11
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
237out:
231 *state = __state; 238 *state = __state;
232 return i; 239 return i;
233} 240}