aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorJan Glauber <jang@linux.vnet.ibm.com>2008-12-25 07:38:47 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2008-12-25 07:38:59 -0500
commit50f769df1c4bea766c4eb927eae35728fb93e305 (patch)
treec86228e6965de0ea84bddc2104d7dfa339e2a187 /drivers/s390
parent22f9934767f49012ffbae753b28b8055bd28348f (diff)
[S390] qdio: improve inbound buffer acknowledgement
- Use automatic acknowledgement of incoming buffers in QEBSM mode - Move ACK for non-QEBSM mode always to the newest buffer to prevent a race with qdio_stop_polling - Remove the polling spinlock, the upper layer drivers return new buffers in the same code path and could not run in parallel - Don't flood the error log in case of no-target-buffer-empty - In handle_inbound we check if we would overwrite an ACK'ed buffer, if so advance the pointer to the oldest ACK'ed buffer so we don't overwrite an empty buffer in qdio_stop_polling Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/cio/qdio.h19
-rw-r--r--drivers/s390/cio/qdio_debug.c7
-rw-r--r--drivers/s390/cio/qdio_main.c181
-rw-r--r--drivers/s390/cio/qdio_perf.c2
-rw-r--r--drivers/s390/cio/qdio_perf.h1
-rw-r--r--drivers/s390/cio/qdio_setup.c1
-rw-r--r--drivers/s390/cio/qdio_thinint.c2
7 files changed, 139 insertions, 74 deletions
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 7b50882577d5..c60f2566d28c 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -112,12 +112,12 @@ static inline int do_sqbs(u64 token, unsigned char state, int queue,
112} 112}
113 113
114static inline int do_eqbs(u64 token, unsigned char *state, int queue, 114static inline int do_eqbs(u64 token, unsigned char *state, int queue,
115 int *start, int *count) 115 int *start, int *count, int ack)
116{ 116{
117 register unsigned long _ccq asm ("0") = *count; 117 register unsigned long _ccq asm ("0") = *count;
118 register unsigned long _token asm ("1") = token; 118 register unsigned long _token asm ("1") = token;
119 unsigned long _queuestart = ((unsigned long)queue << 32) | *start; 119 unsigned long _queuestart = ((unsigned long)queue << 32) | *start;
120 unsigned long _state = 0; 120 unsigned long _state = (unsigned long)ack << 63;
121 121
122 asm volatile( 122 asm volatile(
123 " .insn rrf,0xB99c0000,%1,%2,0,0" 123 " .insn rrf,0xB99c0000,%1,%2,0,0"
@@ -134,7 +134,7 @@ static inline int do_eqbs(u64 token, unsigned char *state, int queue,
134static inline int do_sqbs(u64 token, unsigned char state, int queue, 134static inline int do_sqbs(u64 token, unsigned char state, int queue,
135 int *start, int *count) { return 0; } 135 int *start, int *count) { return 0; }
136static inline int do_eqbs(u64 token, unsigned char *state, int queue, 136static inline int do_eqbs(u64 token, unsigned char *state, int queue,
137 int *start, int *count) { return 0; } 137 int *start, int *count, int ack) { return 0; }
138#endif /* CONFIG_64BIT */ 138#endif /* CONFIG_64BIT */
139 139
140struct qdio_irq; 140struct qdio_irq;
@@ -187,11 +187,11 @@ struct qdio_input_q {
187 /* input buffer acknowledgement flag */ 187 /* input buffer acknowledgement flag */
188 int polling; 188 int polling;
189 189
190 /* how much sbals are acknowledged with qebsm */
191 int ack_count;
192
190 /* last time of noticing incoming data */ 193 /* last time of noticing incoming data */
191 u64 timestamp; 194 u64 timestamp;
192
193 /* lock for clearing the acknowledgement */
194 spinlock_t lock;
195}; 195};
196 196
197struct qdio_output_q { 197struct qdio_output_q {
@@ -351,10 +351,13 @@ static inline unsigned long long get_usecs(void)
351 ((bufnr + 1) & QDIO_MAX_BUFFERS_MASK) 351 ((bufnr + 1) & QDIO_MAX_BUFFERS_MASK)
352#define add_buf(bufnr, inc) \ 352#define add_buf(bufnr, inc) \
353 ((bufnr + inc) & QDIO_MAX_BUFFERS_MASK) 353 ((bufnr + inc) & QDIO_MAX_BUFFERS_MASK)
354#define sub_buf(bufnr, dec) \
355 ((bufnr - dec) & QDIO_MAX_BUFFERS_MASK)
354 356
355/* prototypes for thin interrupt */ 357/* prototypes for thin interrupt */
356void qdio_sync_after_thinint(struct qdio_q *q); 358void qdio_sync_after_thinint(struct qdio_q *q);
357int get_buf_state(struct qdio_q *q, unsigned int bufnr, unsigned char *state); 359int get_buf_state(struct qdio_q *q, unsigned int bufnr, unsigned char *state,
360 int auto_ack);
358void qdio_check_outbound_after_thinint(struct qdio_q *q); 361void qdio_check_outbound_after_thinint(struct qdio_q *q);
359int qdio_inbound_q_moved(struct qdio_q *q); 362int qdio_inbound_q_moved(struct qdio_q *q);
360void qdio_kick_inbound_handler(struct qdio_q *q); 363void qdio_kick_inbound_handler(struct qdio_q *q);
@@ -388,6 +391,8 @@ int qdio_setup_irq(struct qdio_initialize *init_data);
388void qdio_print_subchannel_info(struct qdio_irq *irq_ptr, 391void qdio_print_subchannel_info(struct qdio_irq *irq_ptr,
389 struct ccw_device *cdev); 392 struct ccw_device *cdev);
390void qdio_release_memory(struct qdio_irq *irq_ptr); 393void qdio_release_memory(struct qdio_irq *irq_ptr);
394int qdio_setup_create_sysfs(struct ccw_device *cdev);
395void qdio_setup_destroy_sysfs(struct ccw_device *cdev);
391int qdio_setup_init(void); 396int qdio_setup_init(void);
392void qdio_setup_exit(void); 397void qdio_setup_exit(void);
393 398
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c
index 0add07c1b5d2..f8a3b6967f69 100644
--- a/drivers/s390/cio/qdio_debug.c
+++ b/drivers/s390/cio/qdio_debug.c
@@ -60,16 +60,18 @@ static int qstat_show(struct seq_file *m, void *v)
60 if (!q) 60 if (!q)
61 return 0; 61 return 0;
62 62
63 seq_printf(m, "device state indicator: %d\n", *q->irq_ptr->dsci); 63 seq_printf(m, "device state indicator: %d\n", *(u32 *)q->irq_ptr->dsci);
64 seq_printf(m, "nr_used: %d\n", atomic_read(&q->nr_buf_used)); 64 seq_printf(m, "nr_used: %d\n", atomic_read(&q->nr_buf_used));
65 seq_printf(m, "ftc: %d\n", q->first_to_check); 65 seq_printf(m, "ftc: %d\n", q->first_to_check);
66 seq_printf(m, "last_move_ftc: %d\n", q->last_move_ftc); 66 seq_printf(m, "last_move_ftc: %d\n", q->last_move_ftc);
67 seq_printf(m, "polling: %d\n", q->u.in.polling); 67 seq_printf(m, "polling: %d\n", q->u.in.polling);
68 seq_printf(m, "ack count: %d\n", q->u.in.ack_count);
68 seq_printf(m, "slsb buffer states:\n"); 69 seq_printf(m, "slsb buffer states:\n");
70 seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n");
69 71
70 qdio_siga_sync_q(q); 72 qdio_siga_sync_q(q);
71 for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) { 73 for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) {
72 get_buf_state(q, i, &state); 74 get_buf_state(q, i, &state, 0);
73 switch (state) { 75 switch (state) {
74 case SLSB_P_INPUT_NOT_INIT: 76 case SLSB_P_INPUT_NOT_INIT:
75 case SLSB_P_OUTPUT_NOT_INIT: 77 case SLSB_P_OUTPUT_NOT_INIT:
@@ -101,6 +103,7 @@ static int qstat_show(struct seq_file *m, void *v)
101 seq_printf(m, "\n"); 103 seq_printf(m, "\n");
102 } 104 }
103 seq_printf(m, "\n"); 105 seq_printf(m, "\n");
106 seq_printf(m, "|64 |72 |80 |88 |96 |104 |112 | 127|\n");
104 return 0; 107 return 0;
105} 108}
106 109
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index c810214d3d08..0b4c09cf6a47 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -112,12 +112,13 @@ static inline int qdio_check_ccq(struct qdio_q *q, unsigned int ccq)
112 * @state: state of the extracted buffers 112 * @state: state of the extracted buffers
113 * @start: buffer number to start at 113 * @start: buffer number to start at
114 * @count: count of buffers to examine 114 * @count: count of buffers to examine
115 * @auto_ack: automatically acknowledge buffers
115 * 116 *
116 * Returns the number of successfull extracted equal buffer states. 117 * Returns the number of successfull extracted equal buffer states.
117 * Stops processing if a state is different from the last buffers state. 118 * Stops processing if a state is different from the last buffers state.
118 */ 119 */
119static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state, 120static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state,
120 int start, int count) 121 int start, int count, int auto_ack)
121{ 122{
122 unsigned int ccq = 0; 123 unsigned int ccq = 0;
123 int tmp_count = count, tmp_start = start; 124 int tmp_count = count, tmp_start = start;
@@ -130,7 +131,8 @@ static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state,
130 if (!q->is_input_q) 131 if (!q->is_input_q)
131 nr += q->irq_ptr->nr_input_qs; 132 nr += q->irq_ptr->nr_input_qs;
132again: 133again:
133 ccq = do_eqbs(q->irq_ptr->sch_token, state, nr, &tmp_start, &tmp_count); 134 ccq = do_eqbs(q->irq_ptr->sch_token, state, nr, &tmp_start, &tmp_count,
135 auto_ack);
134 rc = qdio_check_ccq(q, ccq); 136 rc = qdio_check_ccq(q, ccq);
135 137
136 /* At least one buffer was processed, return and extract the remaining 138 /* At least one buffer was processed, return and extract the remaining
@@ -176,6 +178,9 @@ static int qdio_do_sqbs(struct qdio_q *q, unsigned char state, int start,
176 int nr = q->nr; 178 int nr = q->nr;
177 int rc; 179 int rc;
178 180
181 if (!count)
182 return 0;
183
179 BUG_ON(!q->irq_ptr->sch_token); 184 BUG_ON(!q->irq_ptr->sch_token);
180 qdio_perf_stat_inc(&perf_stats.debug_sqbs_all); 185 qdio_perf_stat_inc(&perf_stats.debug_sqbs_all);
181 186
@@ -203,7 +208,8 @@ again:
203 208
204/* returns number of examined buffers and their common state in *state */ 209/* returns number of examined buffers and their common state in *state */
205static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr, 210static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr,
206 unsigned char *state, unsigned int count) 211 unsigned char *state, unsigned int count,
212 int auto_ack)
207{ 213{
208 unsigned char __state = 0; 214 unsigned char __state = 0;
209 int i; 215 int i;
@@ -212,7 +218,7 @@ static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr,
212 BUG_ON(count > QDIO_MAX_BUFFERS_PER_Q); 218 BUG_ON(count > QDIO_MAX_BUFFERS_PER_Q);
213 219
214 if (is_qebsm(q)) 220 if (is_qebsm(q))
215 return qdio_do_eqbs(q, state, bufnr, count); 221 return qdio_do_eqbs(q, state, bufnr, count, auto_ack);
216 222
217 for (i = 0; i < count; i++) { 223 for (i = 0; i < count; i++) {
218 if (!__state) 224 if (!__state)
@@ -226,9 +232,9 @@ static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr,
226} 232}
227 233
228inline int get_buf_state(struct qdio_q *q, unsigned int bufnr, 234inline int get_buf_state(struct qdio_q *q, unsigned int bufnr,
229 unsigned char *state) 235 unsigned char *state, int auto_ack)
230{ 236{
231 return get_buf_states(q, bufnr, state, 1); 237 return get_buf_states(q, bufnr, state, 1, auto_ack);
232} 238}
233 239
234/* wrap-around safe setting of slsb states, returns number of changed buffers */ 240/* wrap-around safe setting of slsb states, returns number of changed buffers */
@@ -376,29 +382,91 @@ void qdio_sync_after_thinint(struct qdio_q *q)
376 382
377inline void qdio_stop_polling(struct qdio_q *q) 383inline void qdio_stop_polling(struct qdio_q *q)
378{ 384{
379 spin_lock_bh(&q->u.in.lock); 385 if (!q->u.in.polling)
380 if (!q->u.in.polling) {
381 spin_unlock_bh(&q->u.in.lock);
382 return; 386 return;
383 } 387
384 q->u.in.polling = 0; 388 q->u.in.polling = 0;
385 qdio_perf_stat_inc(&perf_stats.debug_stop_polling); 389 qdio_perf_stat_inc(&perf_stats.debug_stop_polling);
386 390
387 /* show the card that we are not polling anymore */ 391 /* show the card that we are not polling anymore */
388 set_buf_state(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT); 392 if (is_qebsm(q)) {
389 spin_unlock_bh(&q->u.in.lock); 393 set_buf_states(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT,
394 q->u.in.ack_count);
395 q->u.in.ack_count = 0;
396 } else
397 set_buf_state(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT);
390} 398}
391 399
392static void announce_buffer_error(struct qdio_q *q) 400static void announce_buffer_error(struct qdio_q *q, int count)
393{ 401{
402 q->qdio_error = QDIO_ERROR_SLSB_STATE;
403
404 /* special handling for no target buffer empty */
405 if ((!q->is_input_q &&
406 (q->sbal[q->first_to_check]->element[15].flags & 0xff) == 0x10)) {
407 qdio_perf_stat_inc(&perf_stats.outbound_target_full);
408 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "OUTFULL FTC:%3d",
409 q->first_to_check);
410 return;
411 }
412
394 DBF_ERROR("%4x BUF ERROR", SCH_NO(q)); 413 DBF_ERROR("%4x BUF ERROR", SCH_NO(q));
395 DBF_ERROR((q->is_input_q) ? "IN:%2d" : "OUT:%2d", q->nr); 414 DBF_ERROR((q->is_input_q) ? "IN:%2d" : "OUT:%2d", q->nr);
396 DBF_ERROR("FTC:%3d", q->first_to_check); 415 DBF_ERROR("FTC:%3d C:%3d", q->first_to_check, count);
397 DBF_ERROR("F14:%2x F15:%2x", 416 DBF_ERROR("F14:%2x F15:%2x",
398 q->sbal[q->first_to_check]->element[14].flags & 0xff, 417 q->sbal[q->first_to_check]->element[14].flags & 0xff,
399 q->sbal[q->first_to_check]->element[15].flags & 0xff); 418 q->sbal[q->first_to_check]->element[15].flags & 0xff);
419}
400 420
401 q->qdio_error = QDIO_ERROR_SLSB_STATE; 421static inline void inbound_primed(struct qdio_q *q, int count)
422{
423 int new;
424
425 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in prim: %3d", count);
426
427 /* for QEBSM the ACK was already set by EQBS */
428 if (is_qebsm(q)) {
429 if (!q->u.in.polling) {
430 q->u.in.polling = 1;
431 q->u.in.ack_count = count;
432 q->last_move_ftc = q->first_to_check;
433 return;
434 }
435
436 /* delete the previous ACK's */
437 set_buf_states(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT,
438 q->u.in.ack_count);
439 q->u.in.ack_count = count;
440 q->last_move_ftc = q->first_to_check;
441 return;
442 }
443
444 /*
445 * ACK the newest buffer. The ACK will be removed in qdio_stop_polling
446 * or by the next inbound run.
447 */
448 new = add_buf(q->first_to_check, count - 1);
449 if (q->u.in.polling) {
450 /* reset the previous ACK but first set the new one */
451 set_buf_state(q, new, SLSB_P_INPUT_ACK);
452 set_buf_state(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT);
453 }
454 else {
455 q->u.in.polling = 1;
456 set_buf_state(q, q->first_to_check, SLSB_P_INPUT_ACK);
457 }
458
459 q->last_move_ftc = new;
460 count--;
461 if (!count)
462 return;
463
464 /*
465 * Need to change all PRIMED buffers to NOT_INIT, otherwise
466 * we're loosing initiative in the thinint code.
467 */
468 set_buf_states(q, next_buf(q->first_to_check), SLSB_P_INPUT_NOT_INIT,
469 count);
402} 470}
403 471
404static int get_inbound_buffer_frontier(struct qdio_q *q) 472static int get_inbound_buffer_frontier(struct qdio_q *q)
@@ -407,13 +475,6 @@ static int get_inbound_buffer_frontier(struct qdio_q *q)
407 unsigned char state; 475 unsigned char state;
408 476
409 /* 477 /*
410 * If we still poll don't update last_move_ftc, keep the
411 * previously ACK buffer there.
412 */
413 if (!q->u.in.polling)
414 q->last_move_ftc = q->first_to_check;
415
416 /*
417 * Don't check 128 buffers, as otherwise qdio_inbound_q_moved 478 * Don't check 128 buffers, as otherwise qdio_inbound_q_moved
418 * would return 0. 479 * would return 0.
419 */ 480 */
@@ -433,34 +494,13 @@ check_next:
433 if (q->first_to_check == stop) 494 if (q->first_to_check == stop)
434 goto out; 495 goto out;
435 496
436 count = get_buf_states(q, q->first_to_check, &state, count); 497 count = get_buf_states(q, q->first_to_check, &state, count, 1);
437 if (!count) 498 if (!count)
438 goto out; 499 goto out;
439 500
440 switch (state) { 501 switch (state) {
441 case SLSB_P_INPUT_PRIMED: 502 case SLSB_P_INPUT_PRIMED:
442 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in prim: %3d", count); 503 inbound_primed(q, count);
443
444 /*
445 * Only ACK the first buffer. The ACK will be removed in
446 * qdio_stop_polling.
447 */
448 if (q->u.in.polling)
449 state = SLSB_P_INPUT_NOT_INIT;
450 else {
451 q->u.in.polling = 1;
452 state = SLSB_P_INPUT_ACK;
453 }
454 set_buf_state(q, q->first_to_check, state);
455
456 /*
457 * Need to change all PRIMED buffers to NOT_INIT, otherwise
458 * we're loosing initiative in the thinint code.
459 */
460 if (count > 1)
461 set_buf_states(q, next_buf(q->first_to_check),
462 SLSB_P_INPUT_NOT_INIT, count - 1);
463
464 /* 504 /*
465 * No siga-sync needed for non-qebsm here, as the inbound queue 505 * No siga-sync needed for non-qebsm here, as the inbound queue
466 * will be synced on the next siga-r, resp. 506 * will be synced on the next siga-r, resp.
@@ -470,7 +510,7 @@ check_next:
470 atomic_sub(count, &q->nr_buf_used); 510 atomic_sub(count, &q->nr_buf_used);
471 goto check_next; 511 goto check_next;
472 case SLSB_P_INPUT_ERROR: 512 case SLSB_P_INPUT_ERROR:
473 announce_buffer_error(q); 513 announce_buffer_error(q, count);
474 /* process the buffer, the upper layer will take care of it */ 514 /* process the buffer, the upper layer will take care of it */
475 q->first_to_check = add_buf(q->first_to_check, count); 515 q->first_to_check = add_buf(q->first_to_check, count);
476 atomic_sub(count, &q->nr_buf_used); 516 atomic_sub(count, &q->nr_buf_used);
@@ -516,7 +556,7 @@ static int qdio_inbound_q_done(struct qdio_q *q)
516 */ 556 */
517 qdio_siga_sync_q(q); 557 qdio_siga_sync_q(q);
518 558
519 get_buf_state(q, q->first_to_check, &state); 559 get_buf_state(q, q->first_to_check, &state, 0);
520 if (state == SLSB_P_INPUT_PRIMED) 560 if (state == SLSB_P_INPUT_PRIMED)
521 /* we got something to do */ 561 /* we got something to do */
522 return 0; 562 return 0;
@@ -619,7 +659,7 @@ check_next:
619 if (q->first_to_check == stop) 659 if (q->first_to_check == stop)
620 return q->first_to_check; 660 return q->first_to_check;
621 661
622 count = get_buf_states(q, q->first_to_check, &state, count); 662 count = get_buf_states(q, q->first_to_check, &state, count, 0);
623 if (!count) 663 if (!count)
624 return q->first_to_check; 664 return q->first_to_check;
625 665
@@ -638,7 +678,7 @@ check_next:
638 break; 678 break;
639 goto check_next; 679 goto check_next;
640 case SLSB_P_OUTPUT_ERROR: 680 case SLSB_P_OUTPUT_ERROR:
641 announce_buffer_error(q); 681 announce_buffer_error(q, count);
642 /* process the buffer, the upper layer will take care of it */ 682 /* process the buffer, the upper layer will take care of it */
643 q->first_to_check = add_buf(q->first_to_check, count); 683 q->first_to_check = add_buf(q->first_to_check, count);
644 atomic_sub(count, &q->nr_buf_used); 684 atomic_sub(count, &q->nr_buf_used);
@@ -1451,23 +1491,38 @@ static inline int buf_in_between(int bufnr, int start, int count)
1451static void handle_inbound(struct qdio_q *q, unsigned int callflags, 1491static void handle_inbound(struct qdio_q *q, unsigned int callflags,
1452 int bufnr, int count) 1492 int bufnr, int count)
1453{ 1493{
1454 unsigned long flags; 1494 int used, rc, diff;
1455 int used, rc;
1456 1495
1457 /* 1496 if (!q->u.in.polling)
1458 * do_QDIO could run in parallel with the queue tasklet so the 1497 goto set;
1459 * upper-layer programm could empty the ACK'ed buffer here. 1498
1460 * If that happens we must clear the polling flag, otherwise 1499 /* protect against stop polling setting an ACK for an emptied slsb */
1461 * qdio_stop_polling() could set the buffer to NOT_INIT after 1500 if (count == QDIO_MAX_BUFFERS_PER_Q) {
1462 * it was set to EMPTY which would kill us. 1501 /* overwriting everything, just delete polling status */
1463 */ 1502 q->u.in.polling = 0;
1464 spin_lock_irqsave(&q->u.in.lock, flags); 1503 q->u.in.ack_count = 0;
1465 if (q->u.in.polling) 1504 goto set;
1466 if (buf_in_between(q->last_move_ftc, bufnr, count)) 1505 } else if (buf_in_between(q->last_move_ftc, bufnr, count)) {
1506 if (is_qebsm(q)) {
1507 /* partial overwrite, just update last_move_ftc */
1508 diff = add_buf(bufnr, count);
1509 diff = sub_buf(diff, q->last_move_ftc);
1510 q->u.in.ack_count -= diff;
1511 if (q->u.in.ack_count <= 0) {
1512 q->u.in.polling = 0;
1513 q->u.in.ack_count = 0;
1514 /* TODO: must we set last_move_ftc to something meaningful? */
1515 goto set;
1516 }
1517 q->last_move_ftc = add_buf(q->last_move_ftc, diff);
1518 }
1519 else
1520 /* the only ACK will be deleted, so stop polling */
1467 q->u.in.polling = 0; 1521 q->u.in.polling = 0;
1522 }
1468 1523
1524set:
1469 count = set_buf_states(q, bufnr, SLSB_CU_INPUT_EMPTY, count); 1525 count = set_buf_states(q, bufnr, SLSB_CU_INPUT_EMPTY, count);
1470 spin_unlock_irqrestore(&q->u.in.lock, flags);
1471 1526
1472 used = atomic_add_return(count, &q->nr_buf_used) - count; 1527 used = atomic_add_return(count, &q->nr_buf_used) - count;
1473 BUG_ON(used + count > QDIO_MAX_BUFFERS_PER_Q); 1528 BUG_ON(used + count > QDIO_MAX_BUFFERS_PER_Q);
@@ -1535,7 +1590,7 @@ static void handle_outbound(struct qdio_q *q, unsigned int callflags,
1535 } 1590 }
1536 1591
1537 /* try to fast requeue buffers */ 1592 /* try to fast requeue buffers */
1538 get_buf_state(q, prev_buf(bufnr), &state); 1593 get_buf_state(q, prev_buf(bufnr), &state, 0);
1539 if (state != SLSB_CU_OUTPUT_PRIMED) 1594 if (state != SLSB_CU_OUTPUT_PRIMED)
1540 qdio_kick_outbound_q(q); 1595 qdio_kick_outbound_q(q);
1541 else { 1596 else {
diff --git a/drivers/s390/cio/qdio_perf.c b/drivers/s390/cio/qdio_perf.c
index bec01100f8e8..136d0f0b1e93 100644
--- a/drivers/s390/cio/qdio_perf.c
+++ b/drivers/s390/cio/qdio_perf.c
@@ -74,6 +74,8 @@ static int qdio_perf_proc_show(struct seq_file *m, void *v)
74 seq_printf(m, "\n"); 74 seq_printf(m, "\n");
75 seq_printf(m, "Number of fast requeues (outg. SBAL w/o SIGA)\t: %li\n", 75 seq_printf(m, "Number of fast requeues (outg. SBAL w/o SIGA)\t: %li\n",
76 (long)atomic_long_read(&perf_stats.fast_requeue)); 76 (long)atomic_long_read(&perf_stats.fast_requeue));
77 seq_printf(m, "Number of outbound target full condition\t: %li\n",
78 (long)atomic_long_read(&perf_stats.outbound_target_full));
77 seq_printf(m, "Number of outbound tasklet mod_timer calls\t: %li\n", 79 seq_printf(m, "Number of outbound tasklet mod_timer calls\t: %li\n",
78 (long)atomic_long_read(&perf_stats.debug_tl_out_timer)); 80 (long)atomic_long_read(&perf_stats.debug_tl_out_timer));
79 seq_printf(m, "Number of stop polling calls\t\t\t: %li\n", 81 seq_printf(m, "Number of stop polling calls\t\t\t: %li\n",
diff --git a/drivers/s390/cio/qdio_perf.h b/drivers/s390/cio/qdio_perf.h
index d16c1c67160f..7821ac4fa517 100644
--- a/drivers/s390/cio/qdio_perf.h
+++ b/drivers/s390/cio/qdio_perf.h
@@ -36,6 +36,7 @@ struct qdio_perf_stats {
36 atomic_long_t inbound_handler; 36 atomic_long_t inbound_handler;
37 atomic_long_t outbound_handler; 37 atomic_long_t outbound_handler;
38 atomic_long_t fast_requeue; 38 atomic_long_t fast_requeue;
39 atomic_long_t outbound_target_full;
39 40
40 /* for debugging */ 41 /* for debugging */
41 atomic_long_t debug_tl_out_timer; 42 atomic_long_t debug_tl_out_timer;
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index 7323799b2ce3..18d54fc21ce9 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -167,7 +167,6 @@ static void setup_queues(struct qdio_irq *irq_ptr,
167 setup_queues_misc(q, irq_ptr, qdio_init->input_handler, i); 167 setup_queues_misc(q, irq_ptr, qdio_init->input_handler, i);
168 168
169 q->is_input_q = 1; 169 q->is_input_q = 1;
170 spin_lock_init(&q->u.in.lock);
171 setup_storage_lists(q, irq_ptr, input_sbal_array, i); 170 setup_storage_lists(q, irq_ptr, input_sbal_array, i);
172 input_sbal_array += QDIO_MAX_BUFFERS_PER_Q; 171 input_sbal_array += QDIO_MAX_BUFFERS_PER_Q;
173 172
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index 47ee741d65b2..8e90e147b746 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -131,7 +131,7 @@ static inline int tiqdio_inbound_q_done(struct qdio_q *q)
131 return 1; 131 return 1;
132 132
133 qdio_siga_sync_q(q); 133 qdio_siga_sync_q(q);
134 get_buf_state(q, q->first_to_check, &state); 134 get_buf_state(q, q->first_to_check, &state, 0);
135 135
136 if (state == SLSB_P_INPUT_PRIMED) 136 if (state == SLSB_P_INPUT_PRIMED)
137 /* more work coming */ 137 /* more work coming */