From: Sebastian Ott Date: Fri, 27 Jun 2014 15:07:47 +0000 (+0200) Subject: s390/qeth: extract qdio buffers from input buffer struct X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=6d284bde2beef9d4d067281b08f86554f41de799;p=GitHub%2FLineageOS%2FG12%2Fandroid_kernel_amlogic_linux-4.9.git s390/qeth: extract qdio buffers from input buffer struct Because of the embedded qdio_buffer array struct qeth_qdio_q is quite large resulting in an order 4 allocation. This is likely to fail at runtime and wastes a lot of memory since the actual size is just about 36K. Since there is no need for this buffer to be contiguous split it up using qdio buffer helpers. Reported-by: Neale Ferguson Reviewed-by: Ursula Braun Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index a2088af51cc5..4f9a3180f663 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -439,10 +439,10 @@ struct qeth_qdio_buffer { }; struct qeth_qdio_q { - struct qdio_buffer qdio_bufs[QDIO_MAX_BUFFERS_PER_Q]; + struct qdio_buffer *qdio_bufs[QDIO_MAX_BUFFERS_PER_Q]; struct qeth_qdio_buffer bufs[QDIO_MAX_BUFFERS_PER_Q]; int next_buf_to_init; -} __attribute__ ((aligned(256))); +}; struct qeth_qdio_out_buffer { struct qdio_buffer *buffer; diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index a0a6ad7a1739..acedba8539e4 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -294,6 +294,10 @@ EXPORT_SYMBOL_GPL(qeth_realloc_buffer_pool); static void qeth_free_qdio_queue(struct qeth_qdio_q *q) { + if (!q) + return; + + qdio_free_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q); kfree(q); } @@ -305,8 +309,13 @@ static struct qeth_qdio_q *qeth_alloc_qdio_queue(void) if (!q) return NULL; + if (qdio_alloc_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q)) { + kfree(q); + return NULL; + } + for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i) - q->bufs[i].buffer = &q->qdio_bufs[i]; + q->bufs[i].buffer = q->qdio_bufs[i]; QETH_DBF_HEX(SETUP, 2, &q, sizeof(void *)); return q; @@ -318,8 +327,8 @@ static inline int qeth_cq_init(struct qeth_card *card) if (card->options.cq == QETH_CQ_ENABLED) { QETH_DBF_TEXT(SETUP, 2, "cqinit"); - memset(card->qdio.c_q->qdio_bufs, 0, - QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer)); + qdio_reset_buffers(card->qdio.c_q->qdio_bufs, + QDIO_MAX_BUFFERS_PER_Q); card->qdio.c_q->next_buf_to_init = 127; rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, card->qdio.no_in_queues - 1, 0, @@ -2791,8 +2800,8 @@ int qeth_init_qdio_queues(struct qeth_card *card) QETH_DBF_TEXT(SETUP, 2, "initqdqs"); /* inbound queue */ - memset(card->qdio.in_q->qdio_bufs, 0, - QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer)); + qdio_reset_buffers(card->qdio.in_q->qdio_bufs, + QDIO_MAX_BUFFERS_PER_Q); qeth_initialize_working_pool_list(card); /*give only as many buffers to hardware as we have buffer pool entries*/ for (i = 0; i < card->qdio.in_buf_pool.buf_count - 1; ++i) @@ -3533,7 +3542,7 @@ static void qeth_qdio_cq_handler(struct qeth_card *card, for (i = first_element; i < first_element + count; ++i) { int bidx = i % QDIO_MAX_BUFFERS_PER_Q; - struct qdio_buffer *buffer = &cq->qdio_bufs[bidx]; + struct qdio_buffer *buffer = cq->qdio_bufs[bidx]; int e; e = 0;