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

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 <neale@sinenomine.net>
Reviewed-by: Ursula Braun <ursula.braun@de.ibm.com>
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by

Sebastian Ott and committed by
Martin Schwidefsky
6d284bde 4601ba6c

+17 -8
+2 -2
drivers/s390/net/qeth_core.h
··· 439 439 }; 440 440 441 441 struct qeth_qdio_q { 442 - struct qdio_buffer qdio_bufs[QDIO_MAX_BUFFERS_PER_Q]; 442 + struct qdio_buffer *qdio_bufs[QDIO_MAX_BUFFERS_PER_Q]; 443 443 struct qeth_qdio_buffer bufs[QDIO_MAX_BUFFERS_PER_Q]; 444 444 int next_buf_to_init; 445 - } __attribute__ ((aligned(256))); 445 + }; 446 446 447 447 struct qeth_qdio_out_buffer { 448 448 struct qdio_buffer *buffer;
+15 -6
drivers/s390/net/qeth_core_main.c
··· 294 294 295 295 static void qeth_free_qdio_queue(struct qeth_qdio_q *q) 296 296 { 297 + if (!q) 298 + return; 299 + 300 + qdio_free_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q); 297 301 kfree(q); 298 302 } 299 303 ··· 309 305 if (!q) 310 306 return NULL; 311 307 308 + if (qdio_alloc_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q)) { 309 + kfree(q); 310 + return NULL; 311 + } 312 + 312 313 for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i) 313 - q->bufs[i].buffer = &q->qdio_bufs[i]; 314 + q->bufs[i].buffer = q->qdio_bufs[i]; 314 315 315 316 QETH_DBF_HEX(SETUP, 2, &q, sizeof(void *)); 316 317 return q; ··· 327 318 328 319 if (card->options.cq == QETH_CQ_ENABLED) { 329 320 QETH_DBF_TEXT(SETUP, 2, "cqinit"); 330 - memset(card->qdio.c_q->qdio_bufs, 0, 331 - QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer)); 321 + qdio_reset_buffers(card->qdio.c_q->qdio_bufs, 322 + QDIO_MAX_BUFFERS_PER_Q); 332 323 card->qdio.c_q->next_buf_to_init = 127; 333 324 rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 334 325 card->qdio.no_in_queues - 1, 0, ··· 2800 2791 QETH_DBF_TEXT(SETUP, 2, "initqdqs"); 2801 2792 2802 2793 /* inbound queue */ 2803 - memset(card->qdio.in_q->qdio_bufs, 0, 2804 - QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer)); 2794 + qdio_reset_buffers(card->qdio.in_q->qdio_bufs, 2795 + QDIO_MAX_BUFFERS_PER_Q); 2805 2796 qeth_initialize_working_pool_list(card); 2806 2797 /*give only as many buffers to hardware as we have buffer pool entries*/ 2807 2798 for (i = 0; i < card->qdio.in_buf_pool.buf_count - 1; ++i) ··· 3542 3533 3543 3534 for (i = first_element; i < first_element + count; ++i) { 3544 3535 int bidx = i % QDIO_MAX_BUFFERS_PER_Q; 3545 - struct qdio_buffer *buffer = &cq->qdio_bufs[bidx]; 3536 + struct qdio_buffer *buffer = cq->qdio_bufs[bidx]; 3546 3537 int e; 3547 3538 3548 3539 e = 0;