diff options
Diffstat (limited to 'drivers/s390/cio/qdio_main.c')
-rw-r--r-- | drivers/s390/cio/qdio_main.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 62b654af9237..232ef047ba34 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c | |||
@@ -392,6 +392,20 @@ static inline void qdio_stop_polling(struct qdio_q *q) | |||
392 | set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT); | 392 | set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT); |
393 | } | 393 | } |
394 | 394 | ||
395 | static inline void account_sbals(struct qdio_q *q, int count) | ||
396 | { | ||
397 | int pos = 0; | ||
398 | |||
399 | q->q_stats.nr_sbal_total += count; | ||
400 | if (count == QDIO_MAX_BUFFERS_MASK) { | ||
401 | q->q_stats.nr_sbals[7]++; | ||
402 | return; | ||
403 | } | ||
404 | while (count >>= 1) | ||
405 | pos++; | ||
406 | q->q_stats.nr_sbals[pos]++; | ||
407 | } | ||
408 | |||
395 | static void announce_buffer_error(struct qdio_q *q, int count) | 409 | static void announce_buffer_error(struct qdio_q *q, int count) |
396 | { | 410 | { |
397 | q->qdio_error |= QDIO_ERROR_SLSB_STATE; | 411 | q->qdio_error |= QDIO_ERROR_SLSB_STATE; |
@@ -487,16 +501,22 @@ static int get_inbound_buffer_frontier(struct qdio_q *q) | |||
487 | q->first_to_check = add_buf(q->first_to_check, count); | 501 | q->first_to_check = add_buf(q->first_to_check, count); |
488 | if (atomic_sub(count, &q->nr_buf_used) == 0) | 502 | if (atomic_sub(count, &q->nr_buf_used) == 0) |
489 | qperf_inc(q, inbound_queue_full); | 503 | qperf_inc(q, inbound_queue_full); |
504 | if (q->irq_ptr->perf_stat_enabled) | ||
505 | account_sbals(q, count); | ||
490 | break; | 506 | break; |
491 | case SLSB_P_INPUT_ERROR: | 507 | case SLSB_P_INPUT_ERROR: |
492 | announce_buffer_error(q, count); | 508 | announce_buffer_error(q, count); |
493 | /* process the buffer, the upper layer will take care of it */ | 509 | /* process the buffer, the upper layer will take care of it */ |
494 | q->first_to_check = add_buf(q->first_to_check, count); | 510 | q->first_to_check = add_buf(q->first_to_check, count); |
495 | atomic_sub(count, &q->nr_buf_used); | 511 | atomic_sub(count, &q->nr_buf_used); |
512 | if (q->irq_ptr->perf_stat_enabled) | ||
513 | account_sbals_error(q, count); | ||
496 | break; | 514 | break; |
497 | case SLSB_CU_INPUT_EMPTY: | 515 | case SLSB_CU_INPUT_EMPTY: |
498 | case SLSB_P_INPUT_NOT_INIT: | 516 | case SLSB_P_INPUT_NOT_INIT: |
499 | case SLSB_P_INPUT_ACK: | 517 | case SLSB_P_INPUT_ACK: |
518 | if (q->irq_ptr->perf_stat_enabled) | ||
519 | q->q_stats.nr_sbal_nop++; | ||
500 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in nop"); | 520 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in nop"); |
501 | break; | 521 | break; |
502 | default: | 522 | default: |
@@ -514,7 +534,7 @@ static int qdio_inbound_q_moved(struct qdio_q *q) | |||
514 | 534 | ||
515 | if ((bufnr != q->last_move) || q->qdio_error) { | 535 | if ((bufnr != q->last_move) || q->qdio_error) { |
516 | q->last_move = bufnr; | 536 | q->last_move = bufnr; |
517 | if (!is_thinint_irq(q->irq_ptr) && !MACHINE_IS_VM) | 537 | if (!is_thinint_irq(q->irq_ptr) && MACHINE_IS_LPAR) |
518 | q->u.in.timestamp = get_usecs(); | 538 | q->u.in.timestamp = get_usecs(); |
519 | return 1; | 539 | return 1; |
520 | } else | 540 | } else |
@@ -643,15 +663,21 @@ static int get_outbound_buffer_frontier(struct qdio_q *q) | |||
643 | 663 | ||
644 | atomic_sub(count, &q->nr_buf_used); | 664 | atomic_sub(count, &q->nr_buf_used); |
645 | q->first_to_check = add_buf(q->first_to_check, count); | 665 | q->first_to_check = add_buf(q->first_to_check, count); |
666 | if (q->irq_ptr->perf_stat_enabled) | ||
667 | account_sbals(q, count); | ||
646 | break; | 668 | break; |
647 | case SLSB_P_OUTPUT_ERROR: | 669 | case SLSB_P_OUTPUT_ERROR: |
648 | announce_buffer_error(q, count); | 670 | announce_buffer_error(q, count); |
649 | /* process the buffer, the upper layer will take care of it */ | 671 | /* process the buffer, the upper layer will take care of it */ |
650 | q->first_to_check = add_buf(q->first_to_check, count); | 672 | q->first_to_check = add_buf(q->first_to_check, count); |
651 | atomic_sub(count, &q->nr_buf_used); | 673 | atomic_sub(count, &q->nr_buf_used); |
674 | if (q->irq_ptr->perf_stat_enabled) | ||
675 | account_sbals_error(q, count); | ||
652 | break; | 676 | break; |
653 | case SLSB_CU_OUTPUT_PRIMED: | 677 | case SLSB_CU_OUTPUT_PRIMED: |
654 | /* the adapter has not fetched the output yet */ | 678 | /* the adapter has not fetched the output yet */ |
679 | if (q->irq_ptr->perf_stat_enabled) | ||
680 | q->q_stats.nr_sbal_nop++; | ||
655 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out primed:%1d", q->nr); | 681 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out primed:%1d", q->nr); |
656 | break; | 682 | break; |
657 | case SLSB_P_OUTPUT_NOT_INIT: | 683 | case SLSB_P_OUTPUT_NOT_INIT: |