diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2014-06-27 17:07:47 +0200 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-07-22 09:26:14 +0200 |
commit | 6d284bde2beef9d4d067281b08f86554f41de799 (patch) | |
tree | 435d84e5fa08b849fc31112884d54afad6e64de2 /drivers/s390 | |
parent | 4601ba6c92b000dcda37c9d74587e3b88374c00c (diff) | |
download | linux-6d284bde2beef9d4d067281b08f86554f41de799.tar.bz2 |
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>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/net/qeth_core.h | 4 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_main.c | 21 |
2 files changed, 17 insertions, 8 deletions
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; |