Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 's390-qeth-next'

Julian Wiedmann says:

====================
s390/qeth: updates 2020-07-30

please apply the following patch series for qeth to netdev's net-next tree.

This primarily brings some modernization to the RX path, laying the
groundwork for smarter RX refill policies.
Some of the patches are tagged as fixes, but really target only rare /
theoretical issues. So given where we are in the release cycle and that we
touch the main RX path, taking them through net-next seems more appropriate.
====================

Reviewed-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

+48 -36
+1 -1
drivers/s390/net/qeth_core.h
··· 764 764 u8 buf_element; 765 765 int e_offset; 766 766 int qdio_err; 767 + u8 bufs_refill; 767 768 }; 768 769 769 770 struct carrier_info { ··· 834 833 struct napi_struct napi; 835 834 struct qeth_rx rx; 836 835 struct delayed_work buffer_reclaim_work; 837 - int reclaim_index; 838 836 struct work_struct close_dev_work; 839 837 }; 840 838
+43 -33
drivers/s390/net/qeth_core_main.c
··· 204 204 void qeth_clear_working_pool_list(struct qeth_card *card) 205 205 { 206 206 struct qeth_buffer_pool_entry *pool_entry, *tmp; 207 + struct qeth_qdio_q *queue = card->qdio.in_q; 208 + unsigned int i; 207 209 208 210 QETH_CARD_TEXT(card, 5, "clwrklst"); 209 211 list_for_each_entry_safe(pool_entry, tmp, 210 212 &card->qdio.in_buf_pool.entry_list, list){ 211 213 list_del(&pool_entry->list); 212 214 } 215 + 216 + for (i = 0; i < ARRAY_SIZE(queue->bufs); i++) 217 + queue->bufs[i].pool_entry = NULL; 213 218 } 214 219 EXPORT_SYMBOL_GPL(qeth_clear_working_pool_list); 215 220 ··· 2970 2965 static int qeth_init_input_buffer(struct qeth_card *card, 2971 2966 struct qeth_qdio_buffer *buf) 2972 2967 { 2973 - struct qeth_buffer_pool_entry *pool_entry; 2968 + struct qeth_buffer_pool_entry *pool_entry = buf->pool_entry; 2974 2969 int i; 2975 2970 2976 2971 if ((card->options.cq == QETH_CQ_ENABLED) && (!buf->rx_skb)) { ··· 2981 2976 return -ENOMEM; 2982 2977 } 2983 2978 2984 - pool_entry = qeth_find_free_buffer_pool_entry(card); 2985 - if (!pool_entry) 2986 - return -ENOBUFS; 2979 + if (!pool_entry) { 2980 + pool_entry = qeth_find_free_buffer_pool_entry(card); 2981 + if (!pool_entry) 2982 + return -ENOBUFS; 2983 + 2984 + buf->pool_entry = pool_entry; 2985 + } 2987 2986 2988 2987 /* 2989 2988 * since the buffer is accessed only from the input_tasklet ··· 2995 2986 * the QETH_IN_BUF_REQUEUE_THRESHOLD we should never run out off 2996 2987 * buffers 2997 2988 */ 2998 - 2999 - buf->pool_entry = pool_entry; 3000 2989 for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) { 3001 2990 buf->buffer->element[i].length = PAGE_SIZE; 3002 2991 buf->buffer->element[i].addr = ··· 3022 3015 3023 3016 static int qeth_init_qdio_queues(struct qeth_card *card) 3024 3017 { 3018 + unsigned int rx_bufs = card->qdio.in_buf_pool.buf_count; 3025 3019 unsigned int i; 3026 3020 int rc; 3027 3021 ··· 3034 3026 3035 3027 qeth_initialize_working_pool_list(card); 3036 3028 /*give only as many buffers to hardware as we have buffer pool entries*/ 3037 - for (i = 0; i < card->qdio.in_buf_pool.buf_count - 1; i++) { 3029 + for (i = 0; i < rx_bufs; i++) { 3038 3030 rc = qeth_init_input_buffer(card, &card->qdio.in_q->bufs[i]); 3039 3031 if (rc) 3040 3032 return rc; 3041 3033 } 3042 3034 3043 - card->qdio.in_q->next_buf_to_init = 3044 - card->qdio.in_buf_pool.buf_count - 1; 3045 - rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, 0, 3046 - card->qdio.in_buf_pool.buf_count - 1); 3035 + card->qdio.in_q->next_buf_to_init = QDIO_BUFNR(rx_bufs); 3036 + rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, 0, rx_bufs); 3047 3037 if (rc) { 3048 3038 QETH_CARD_TEXT_(card, 2, "1err%d", rc); 3049 3039 return rc; ··· 3491 3485 return 0; 3492 3486 } 3493 3487 3494 - static void qeth_queue_input_buffer(struct qeth_card *card, int index) 3488 + static unsigned int qeth_rx_refill_queue(struct qeth_card *card, 3489 + unsigned int count) 3495 3490 { 3496 3491 struct qeth_qdio_q *queue = card->qdio.in_q; 3497 3492 struct list_head *lh; 3498 - int count; 3499 3493 int i; 3500 3494 int rc; 3501 3495 int newcount = 0; 3502 3496 3503 - count = (index < queue->next_buf_to_init)? 3504 - card->qdio.in_buf_pool.buf_count - 3505 - (queue->next_buf_to_init - index) : 3506 - card->qdio.in_buf_pool.buf_count - 3507 - (queue->next_buf_to_init + QDIO_MAX_BUFFERS_PER_Q - index); 3508 3497 /* only requeue at a certain threshold to avoid SIGAs */ 3509 3498 if (count >= QETH_IN_BUF_REQUEUE_THRESHOLD(card)) { 3510 3499 for (i = queue->next_buf_to_init; ··· 3527 3526 i++; 3528 3527 if (i == card->qdio.in_buf_pool.buf_count) { 3529 3528 QETH_CARD_TEXT(card, 2, "qsarbw"); 3530 - card->reclaim_index = index; 3531 3529 schedule_delayed_work( 3532 3530 &card->buffer_reclaim_work, 3533 3531 QETH_RECLAIM_WORK_TIME); 3534 3532 } 3535 - return; 3533 + return 0; 3536 3534 } 3537 3535 3538 - /* 3539 - * according to old code it should be avoided to requeue all 3540 - * 128 buffers in order to benefit from PCI avoidance. 3541 - * this function keeps at least one buffer (the buffer at 3542 - * 'index') un-requeued -> this buffer is the first buffer that 3543 - * will be requeued the next time 3544 - */ 3545 3536 rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, 3546 3537 queue->next_buf_to_init, count); 3547 3538 if (rc) { ··· 3541 3548 } 3542 3549 queue->next_buf_to_init = QDIO_BUFNR(queue->next_buf_to_init + 3543 3550 count); 3551 + return count; 3544 3552 } 3553 + 3554 + return 0; 3545 3555 } 3546 3556 3547 3557 static void qeth_buffer_reclaim_work(struct work_struct *work) ··· 3552 3556 struct qeth_card *card = container_of(work, struct qeth_card, 3553 3557 buffer_reclaim_work.work); 3554 3558 3555 - QETH_CARD_TEXT_(card, 2, "brw:%x", card->reclaim_index); 3556 - qeth_queue_input_buffer(card, card->reclaim_index); 3559 + local_bh_disable(); 3560 + napi_schedule(&card->napi); 3561 + /* kick-start the NAPI softirq: */ 3562 + local_bh_enable(); 3557 3563 } 3558 3564 3559 3565 static void qeth_handle_send_error(struct qeth_card *card, ··· 5734 5736 5735 5737 static unsigned int qeth_rx_poll(struct qeth_card *card, int budget) 5736 5738 { 5739 + struct qeth_rx *ctx = &card->rx; 5737 5740 unsigned int work_done = 0; 5738 5741 5739 5742 while (budget > 0) { ··· 5770 5771 if (done) { 5771 5772 QETH_CARD_STAT_INC(card, rx_bufs); 5772 5773 qeth_put_buffer_pool_entry(card, buffer->pool_entry); 5773 - qeth_queue_input_buffer(card, card->rx.b_index); 5774 + buffer->pool_entry = NULL; 5774 5775 card->rx.b_count--; 5776 + ctx->bufs_refill++; 5777 + ctx->bufs_refill -= qeth_rx_refill_queue(card, 5778 + ctx->bufs_refill); 5775 5779 5776 5780 /* Step forward to next buffer: */ 5777 5781 card->rx.b_index = QDIO_BUFNR(card->rx.b_index + 1); ··· 5814 5812 if (card->options.cq == QETH_CQ_ENABLED) 5815 5813 qeth_cq_poll(card); 5816 5814 5817 - /* Exhausted the RX budget. Keep IRQ disabled, we get called again. */ 5818 - if (budget && work_done >= budget) 5819 - return work_done; 5815 + if (budget) { 5816 + struct qeth_rx *ctx = &card->rx; 5817 + 5818 + /* Process any substantial refill backlog: */ 5819 + ctx->bufs_refill -= qeth_rx_refill_queue(card, ctx->bufs_refill); 5820 + 5821 + /* Exhausted the RX budget. Keep IRQ disabled, we get called again. */ 5822 + if (work_done >= budget) 5823 + return work_done; 5824 + } 5820 5825 5821 5826 if (napi_complete_done(napi, work_done) && 5822 5827 qdio_start_irq(CARD_DDEV(card))) ··· 7010 7001 } 7011 7002 7012 7003 napi_disable(&card->napi); 7004 + cancel_delayed_work_sync(&card->buffer_reclaim_work); 7013 7005 qdio_stop_irq(CARD_DDEV(card)); 7014 7006 7015 7007 return 0;
+4 -1
drivers/s390/net/qeth_l2_main.c
··· 285 285 if (card->state == CARD_STATE_SOFTSETUP) { 286 286 qeth_clear_ipacmd_list(card); 287 287 qeth_drain_output_queues(card); 288 - cancel_delayed_work_sync(&card->buffer_reclaim_work); 289 288 card->state = CARD_STATE_DOWN; 290 289 } 291 290 ··· 1140 1141 int extrasize; 1141 1142 1142 1143 QETH_CARD_TEXT(card, 2, "brstchng"); 1144 + if (qports->num_entries == 0) { 1145 + QETH_CARD_TEXT(card, 2, "BPempty"); 1146 + return; 1147 + } 1143 1148 if (qports->entry_length != sizeof(struct qeth_sbp_port_entry)) { 1144 1149 QETH_CARD_TEXT_(card, 2, "BPsz%04x", qports->entry_length); 1145 1150 return;
-1
drivers/s390/net/qeth_l3_main.c
··· 1169 1169 qeth_l3_clear_ip_htable(card, 1); 1170 1170 qeth_clear_ipacmd_list(card); 1171 1171 qeth_drain_output_queues(card); 1172 - cancel_delayed_work_sync(&card->buffer_reclaim_work); 1173 1172 card->state = CARD_STATE_DOWN; 1174 1173 } 1175 1174