Commit 0f75e149 authored by Julian Wiedmann's avatar Julian Wiedmann Committed by David S. Miller

s390/qeth: refactor buffer pool code

In preparation for a subsequent fix, split out helpers to allocate/free
individual pool entries.
Signed-off-by: default avatarJulian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f81649df
...@@ -65,7 +65,6 @@ static struct lock_class_key qdio_out_skb_queue_key; ...@@ -65,7 +65,6 @@ static struct lock_class_key qdio_out_skb_queue_key;
static void qeth_issue_next_read_cb(struct qeth_card *card, static void qeth_issue_next_read_cb(struct qeth_card *card,
struct qeth_cmd_buffer *iob, struct qeth_cmd_buffer *iob,
unsigned int data_length); unsigned int data_length);
static void qeth_free_buffer_pool(struct qeth_card *);
static int qeth_qdio_establish(struct qeth_card *); static int qeth_qdio_establish(struct qeth_card *);
static void qeth_free_qdio_queues(struct qeth_card *card); static void qeth_free_qdio_queues(struct qeth_card *card);
static void qeth_notify_skbs(struct qeth_qdio_out_q *queue, static void qeth_notify_skbs(struct qeth_qdio_out_q *queue,
...@@ -212,33 +211,66 @@ void qeth_clear_working_pool_list(struct qeth_card *card) ...@@ -212,33 +211,66 @@ void qeth_clear_working_pool_list(struct qeth_card *card)
} }
EXPORT_SYMBOL_GPL(qeth_clear_working_pool_list); EXPORT_SYMBOL_GPL(qeth_clear_working_pool_list);
static void qeth_free_pool_entry(struct qeth_buffer_pool_entry *entry)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(entry->elements); i++) {
if (entry->elements[i])
__free_page(entry->elements[i]);
}
kfree(entry);
}
static void qeth_free_buffer_pool(struct qeth_card *card)
{
struct qeth_buffer_pool_entry *entry, *tmp;
list_for_each_entry_safe(entry, tmp, &card->qdio.init_pool.entry_list,
init_list) {
list_del(&entry->init_list);
qeth_free_pool_entry(entry);
}
}
static struct qeth_buffer_pool_entry *qeth_alloc_pool_entry(unsigned int pages)
{
struct qeth_buffer_pool_entry *entry;
unsigned int i;
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (!entry)
return NULL;
for (i = 0; i < pages; i++) {
entry->elements[i] = alloc_page(GFP_KERNEL);
if (!entry->elements[i]) {
qeth_free_pool_entry(entry);
return NULL;
}
}
return entry;
}
static int qeth_alloc_buffer_pool(struct qeth_card *card) static int qeth_alloc_buffer_pool(struct qeth_card *card)
{ {
struct qeth_buffer_pool_entry *pool_entry; unsigned int buf_elements = QETH_MAX_BUFFER_ELEMENTS(card);
int i, j; unsigned int i;
QETH_CARD_TEXT(card, 5, "alocpool"); QETH_CARD_TEXT(card, 5, "alocpool");
for (i = 0; i < card->qdio.init_pool.buf_count; ++i) { for (i = 0; i < card->qdio.init_pool.buf_count; ++i) {
pool_entry = kzalloc(sizeof(*pool_entry), GFP_KERNEL); struct qeth_buffer_pool_entry *entry;
if (!pool_entry) {
qeth_free_buffer_pool(card);
return -ENOMEM;
}
for (j = 0; j < QETH_MAX_BUFFER_ELEMENTS(card); ++j) {
struct page *page = alloc_page(GFP_KERNEL);
if (!page) { entry = qeth_alloc_pool_entry(buf_elements);
while (j > 0) if (!entry) {
__free_page(pool_entry->elements[--j]);
kfree(pool_entry);
qeth_free_buffer_pool(card); qeth_free_buffer_pool(card);
return -ENOMEM; return -ENOMEM;
} }
pool_entry->elements[j] = page;
} list_add(&entry->init_list, &card->qdio.init_pool.entry_list);
list_add(&pool_entry->init_list,
&card->qdio.init_pool.entry_list);
} }
return 0; return 0;
} }
...@@ -1170,19 +1202,6 @@ void qeth_drain_output_queues(struct qeth_card *card) ...@@ -1170,19 +1202,6 @@ void qeth_drain_output_queues(struct qeth_card *card)
} }
EXPORT_SYMBOL_GPL(qeth_drain_output_queues); EXPORT_SYMBOL_GPL(qeth_drain_output_queues);
static void qeth_free_buffer_pool(struct qeth_card *card)
{
struct qeth_buffer_pool_entry *pool_entry, *tmp;
int i = 0;
list_for_each_entry_safe(pool_entry, tmp,
&card->qdio.init_pool.entry_list, init_list){
for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i)
__free_page(pool_entry->elements[i]);
list_del(&pool_entry->init_list);
kfree(pool_entry);
}
}
static int qeth_osa_set_output_queues(struct qeth_card *card, bool single) static int qeth_osa_set_output_queues(struct qeth_card *card, bool single)
{ {
unsigned int count = single ? 1 : card->dev->num_tx_queues; unsigned int count = single ? 1 : card->dev->num_tx_queues;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment