Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Martin Schwidefsky: "Mostly cleanups and bug-fixes, with two exceptions. The first is lazy flushing of I/O-TLBs for PCI to improve performance, the second is software dirty bits in the pmd for the madvise-free implementation" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (24 commits) s390/locking: Reenable optimistic spinning s390/mm: implement dirty bits for large segment table entries KVM: s390/mm: Fix page table locking vs. split pmd lock s390/dasd: fix camel case s390/3215: fix hanging console issue s390/irq: improve displayed interrupt order in /proc/interrupts s390/seccomp: fix error return for filtered system calls s390/pci: introduce lazy IOTLB flushing for DMA unmap dasd: fix error recovery for alias devices during format dasd: fix list_del corruption during format dasd: fix unresponsive device during format dasd: use aliases for formatted devices during format s390/pci: fix kmsg component s390/kdump: Return NOTIFY_OK for all actions other than MEM_GOING_OFFLINE s390/watchdog: Fix module name in Kconfig help text s390/dasd: replace seq_printf by seq_puts s390/dasd: replace pr_warning by pr_warn s390/dasd: Move EXPORT_SYMBOL after function/variable s390/dasd: remove unnecessary null test before debugfs_remove s390/zfcp: use qdio buffer helpers ...
This commit is contained in:
@@ -292,14 +292,43 @@ int qeth_realloc_buffer_pool(struct qeth_card *card, int bufcnt)
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
static struct qeth_qdio_q *qeth_alloc_qdio_queue(void)
|
||||
{
|
||||
struct qeth_qdio_q *q = kzalloc(sizeof(*q), GFP_KERNEL);
|
||||
int i;
|
||||
|
||||
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];
|
||||
|
||||
QETH_DBF_HEX(SETUP, 2, &q, sizeof(void *));
|
||||
return q;
|
||||
}
|
||||
|
||||
static inline int qeth_cq_init(struct qeth_card *card)
|
||||
{
|
||||
int rc;
|
||||
|
||||
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,
|
||||
@@ -323,21 +352,12 @@ static inline int qeth_alloc_cq(struct qeth_card *card)
|
||||
struct qdio_outbuf_state *outbuf_states;
|
||||
|
||||
QETH_DBF_TEXT(SETUP, 2, "cqon");
|
||||
card->qdio.c_q = kzalloc(sizeof(struct qeth_qdio_q),
|
||||
GFP_KERNEL);
|
||||
card->qdio.c_q = qeth_alloc_qdio_queue();
|
||||
if (!card->qdio.c_q) {
|
||||
rc = -1;
|
||||
goto kmsg_out;
|
||||
}
|
||||
QETH_DBF_HEX(SETUP, 2, &card->qdio.c_q, sizeof(void *));
|
||||
|
||||
for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i) {
|
||||
card->qdio.c_q->bufs[i].buffer =
|
||||
&card->qdio.c_q->qdio_bufs[i];
|
||||
}
|
||||
|
||||
card->qdio.no_in_queues = 2;
|
||||
|
||||
card->qdio.out_bufstates =
|
||||
kzalloc(card->qdio.no_out_queues *
|
||||
QDIO_MAX_BUFFERS_PER_Q *
|
||||
@@ -361,7 +381,7 @@ static inline int qeth_alloc_cq(struct qeth_card *card)
|
||||
out:
|
||||
return rc;
|
||||
free_cq_out:
|
||||
kfree(card->qdio.c_q);
|
||||
qeth_free_qdio_queue(card->qdio.c_q);
|
||||
card->qdio.c_q = NULL;
|
||||
kmsg_out:
|
||||
dev_err(&card->gdev->dev, "Failed to create completion queue\n");
|
||||
@@ -372,7 +392,7 @@ static inline void qeth_free_cq(struct qeth_card *card)
|
||||
{
|
||||
if (card->qdio.c_q) {
|
||||
--card->qdio.no_in_queues;
|
||||
kfree(card->qdio.c_q);
|
||||
qeth_free_qdio_queue(card->qdio.c_q);
|
||||
card->qdio.c_q = NULL;
|
||||
}
|
||||
kfree(card->qdio.out_bufstates);
|
||||
@@ -1282,35 +1302,6 @@ static void qeth_free_buffer_pool(struct qeth_card *card)
|
||||
}
|
||||
}
|
||||
|
||||
static void qeth_free_qdio_buffers(struct qeth_card *card)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (atomic_xchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED) ==
|
||||
QETH_QDIO_UNINITIALIZED)
|
||||
return;
|
||||
|
||||
qeth_free_cq(card);
|
||||
cancel_delayed_work_sync(&card->buffer_reclaim_work);
|
||||
for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) {
|
||||
if (card->qdio.in_q->bufs[j].rx_skb)
|
||||
dev_kfree_skb_any(card->qdio.in_q->bufs[j].rx_skb);
|
||||
}
|
||||
kfree(card->qdio.in_q);
|
||||
card->qdio.in_q = NULL;
|
||||
/* inbound buffer pool */
|
||||
qeth_free_buffer_pool(card);
|
||||
/* free outbound qdio_qs */
|
||||
if (card->qdio.out_qs) {
|
||||
for (i = 0; i < card->qdio.no_out_queues; ++i) {
|
||||
qeth_clear_outq_buffers(card->qdio.out_qs[i], 1);
|
||||
kfree(card->qdio.out_qs[i]);
|
||||
}
|
||||
kfree(card->qdio.out_qs);
|
||||
card->qdio.out_qs = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void qeth_clean_channel(struct qeth_channel *channel)
|
||||
{
|
||||
int cnt;
|
||||
@@ -2392,7 +2383,7 @@ static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *q, int bidx)
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
newbuf->buffer = &q->qdio_bufs[bidx];
|
||||
newbuf->buffer = q->qdio_bufs[bidx];
|
||||
skb_queue_head_init(&newbuf->skb_list);
|
||||
lockdep_set_class(&newbuf->skb_list.lock, &qdio_out_skb_queue_key);
|
||||
newbuf->q = q;
|
||||
@@ -2411,6 +2402,28 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void qeth_free_qdio_out_buf(struct qeth_qdio_out_q *q)
|
||||
{
|
||||
if (!q)
|
||||
return;
|
||||
|
||||
qdio_free_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q);
|
||||
kfree(q);
|
||||
}
|
||||
|
||||
static struct qeth_qdio_out_q *qeth_alloc_qdio_out_buf(void)
|
||||
{
|
||||
struct qeth_qdio_out_q *q = kzalloc(sizeof(*q), GFP_KERNEL);
|
||||
|
||||
if (!q)
|
||||
return NULL;
|
||||
|
||||
if (qdio_alloc_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q)) {
|
||||
kfree(q);
|
||||
return NULL;
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
static int qeth_alloc_qdio_buffers(struct qeth_card *card)
|
||||
{
|
||||
@@ -2422,19 +2435,11 @@ static int qeth_alloc_qdio_buffers(struct qeth_card *card)
|
||||
QETH_QDIO_ALLOCATED) != QETH_QDIO_UNINITIALIZED)
|
||||
return 0;
|
||||
|
||||
card->qdio.in_q = kzalloc(sizeof(struct qeth_qdio_q),
|
||||
GFP_KERNEL);
|
||||
QETH_DBF_TEXT(SETUP, 2, "inq");
|
||||
card->qdio.in_q = qeth_alloc_qdio_queue();
|
||||
if (!card->qdio.in_q)
|
||||
goto out_nomem;
|
||||
QETH_DBF_TEXT(SETUP, 2, "inq");
|
||||
QETH_DBF_HEX(SETUP, 2, &card->qdio.in_q, sizeof(void *));
|
||||
memset(card->qdio.in_q, 0, sizeof(struct qeth_qdio_q));
|
||||
/* give inbound qeth_qdio_buffers their qdio_buffers */
|
||||
for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i) {
|
||||
card->qdio.in_q->bufs[i].buffer =
|
||||
&card->qdio.in_q->qdio_bufs[i];
|
||||
card->qdio.in_q->bufs[i].rx_skb = NULL;
|
||||
}
|
||||
|
||||
/* inbound buffer pool */
|
||||
if (qeth_alloc_buffer_pool(card))
|
||||
goto out_freeinq;
|
||||
@@ -2446,8 +2451,7 @@ static int qeth_alloc_qdio_buffers(struct qeth_card *card)
|
||||
if (!card->qdio.out_qs)
|
||||
goto out_freepool;
|
||||
for (i = 0; i < card->qdio.no_out_queues; ++i) {
|
||||
card->qdio.out_qs[i] = kzalloc(sizeof(struct qeth_qdio_out_q),
|
||||
GFP_KERNEL);
|
||||
card->qdio.out_qs[i] = qeth_alloc_qdio_out_buf();
|
||||
if (!card->qdio.out_qs[i])
|
||||
goto out_freeoutq;
|
||||
QETH_DBF_TEXT_(SETUP, 2, "outq %i", i);
|
||||
@@ -2476,7 +2480,7 @@ out_freeoutqbufs:
|
||||
}
|
||||
out_freeoutq:
|
||||
while (i > 0) {
|
||||
kfree(card->qdio.out_qs[--i]);
|
||||
qeth_free_qdio_out_buf(card->qdio.out_qs[--i]);
|
||||
qeth_clear_outq_buffers(card->qdio.out_qs[i], 1);
|
||||
}
|
||||
kfree(card->qdio.out_qs);
|
||||
@@ -2484,13 +2488,42 @@ out_freeoutq:
|
||||
out_freepool:
|
||||
qeth_free_buffer_pool(card);
|
||||
out_freeinq:
|
||||
kfree(card->qdio.in_q);
|
||||
qeth_free_qdio_queue(card->qdio.in_q);
|
||||
card->qdio.in_q = NULL;
|
||||
out_nomem:
|
||||
atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void qeth_free_qdio_buffers(struct qeth_card *card)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (atomic_xchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED) ==
|
||||
QETH_QDIO_UNINITIALIZED)
|
||||
return;
|
||||
|
||||
qeth_free_cq(card);
|
||||
cancel_delayed_work_sync(&card->buffer_reclaim_work);
|
||||
for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) {
|
||||
if (card->qdio.in_q->bufs[j].rx_skb)
|
||||
dev_kfree_skb_any(card->qdio.in_q->bufs[j].rx_skb);
|
||||
}
|
||||
qeth_free_qdio_queue(card->qdio.in_q);
|
||||
card->qdio.in_q = NULL;
|
||||
/* inbound buffer pool */
|
||||
qeth_free_buffer_pool(card);
|
||||
/* free outbound qdio_qs */
|
||||
if (card->qdio.out_qs) {
|
||||
for (i = 0; i < card->qdio.no_out_queues; ++i) {
|
||||
qeth_clear_outq_buffers(card->qdio.out_qs[i], 1);
|
||||
qeth_free_qdio_out_buf(card->qdio.out_qs[i]);
|
||||
}
|
||||
kfree(card->qdio.out_qs);
|
||||
card->qdio.out_qs = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void qeth_create_qib_param_field(struct qeth_card *card,
|
||||
char *param_field)
|
||||
{
|
||||
@@ -2788,8 +2821,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)
|
||||
@@ -2811,8 +2844,8 @@ int qeth_init_qdio_queues(struct qeth_card *card)
|
||||
|
||||
/* outbound queue */
|
||||
for (i = 0; i < card->qdio.no_out_queues; ++i) {
|
||||
memset(card->qdio.out_qs[i]->qdio_bufs, 0,
|
||||
QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer));
|
||||
qdio_reset_buffers(card->qdio.out_qs[i]->qdio_bufs,
|
||||
QDIO_MAX_BUFFERS_PER_Q);
|
||||
for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) {
|
||||
qeth_clear_output_buffer(card->qdio.out_qs[i],
|
||||
card->qdio.out_qs[i]->bufs[j],
|
||||
@@ -3569,7 +3602,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;
|
||||
|
||||
Reference in New Issue
Block a user