aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorJulian Wiedmann <jwi@linux.ibm.com>2020-05-06 10:09:47 +0200
committerDavid S. Miller <davem@davemloft.net>2020-05-06 14:11:26 -0700
commit6ee091efa7b59829448d0f9287ea62c1f448a318 (patch)
tree15eb02e1f6366f99e3f3ac83dbd67a366c5aa328 /drivers/s390
parents390/qeth: indicate contiguous TX buffer elements (diff)
downloadlinux-dev-6ee091efa7b59829448d0f9287ea62c1f448a318.tar.xz
linux-dev-6ee091efa7b59829448d0f9287ea62c1f448a318.zip
s390/qeth: set TX IRQ marker on last buffer in a group
When qeth_flush_buffers() gets called for a group of TX buffers (currently up to 2 for OSA-style devices), the code iterates over each buffer for some final processing. During this processing, it sets the TX IRQ marker on the leading buffer rather than the last one. This can result in delayed TX completion of the trailing buffers. So pull the IRQ marker code out of the loop, and apply it to the final buffer. Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/net/qeth_core_main.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 4d1d053eebb7..164cc7f377fc 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -3617,11 +3617,11 @@ static int qeth_switch_to_nonpacking_if_needed(struct qeth_qdio_out_q *queue)
static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
int count)
{
+ struct qeth_qdio_out_buffer *buf = queue->bufs[index];
+ unsigned int qdio_flags = QDIO_FLAG_SYNC_OUTPUT;
struct qeth_card *card = queue->card;
- struct qeth_qdio_out_buffer *buf;
int rc;
int i;
- unsigned int qdio_flags;
for (i = index; i < index + count; ++i) {
unsigned int bidx = QDIO_BUFNR(i);
@@ -3638,9 +3638,10 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
if (IS_IQD(card)) {
skb_queue_walk(&buf->skb_list, skb)
skb_tx_timestamp(skb);
- continue;
}
+ }
+ if (!IS_IQD(card)) {
if (!queue->do_pack) {
if ((atomic_read(&queue->used_buffers) >=
(QETH_HIGH_WATERMARK_PACK -
@@ -3665,12 +3666,12 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
buf->buffer->element[0].sflags |= SBAL_SFLAGS0_PCI_REQ;
}
}
+
+ if (atomic_read(&queue->set_pci_flags_count))
+ qdio_flags |= QDIO_FLAG_PCI_OUT;
}
QETH_TXQ_STAT_INC(queue, doorbell);
- qdio_flags = QDIO_FLAG_SYNC_OUTPUT;
- if (atomic_read(&queue->set_pci_flags_count))
- qdio_flags |= QDIO_FLAG_PCI_OUT;
rc = do_QDIO(CARD_DDEV(queue->card), qdio_flags,
queue->queue_no, index, count);