The TX path usually maps the full content of a page into a buffer element. But there's specific skb layouts (ie. linearized TSO skbs) where the HW header (1) requires a separate buffer element, and (2) is page-contiguous with the packet data that's mapped into the next buffer element. Flag such buffer elements accordingly, so that HW can optimize its data access for them. Signed-off-by: Julian Wiedmann <jwi@xxxxxxxxxxxxx> --- drivers/s390/net/qeth_core_main.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 9c9a6edb5384..4d1d053eebb7 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -4110,8 +4110,16 @@ static unsigned int qeth_fill_buffer(struct qeth_qdio_out_buffer *buf, buffer->element[element].addr = virt_to_phys(hdr); buffer->element[element].length = hd_len; buffer->element[element].eflags = SBAL_EFLAGS_FIRST_FRAG; - /* remember to free cache-allocated HW header: */ - buf->is_header[element] = ((void *)hdr != skb->data); + + /* HW header is allocated from cache: */ + if ((void *)hdr != skb->data) + buf->is_header[element] = 1; + /* HW header was pushed and is contiguous with linear part: */ + else if (length > 0 && !PAGE_ALIGNED(data) && + (data == (char *)hdr + hd_len)) + buffer->element[element].eflags |= + SBAL_EFLAGS_CONTIGUOUS; + element++; } -- 2.17.1