s390/qeth: use memory reserves in TX slow path
authorJulian Wiedmann <jwi@linux.ibm.com>
Wed, 18 Mar 2020 12:54:46 +0000 (13:54 +0100)
committerDavid S. Miller <davem@davemloft.net>
Wed, 18 Mar 2020 23:33:35 +0000 (16:33 -0700)
When falling back to an allocation from the HW header cache, check if
the skb is eligible for using memory reserves.
This only makes a difference if the cache is empty and needs to be
refilled.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/s390/net/qeth_core_main.c
drivers/s390/net/qeth_l2_main.c

index be3f629..767cef0 100644 (file)
@@ -3705,6 +3705,7 @@ static int qeth_add_hw_header(struct qeth_qdio_out_q *queue,
                              unsigned int hdr_len, unsigned int proto_len,
                              unsigned int *elements)
 {
+       gfp_t gfp = GFP_ATOMIC | (skb_pfmemalloc(skb) ? __GFP_MEMALLOC : 0);
        const unsigned int contiguous = proto_len ? proto_len : 1;
        const unsigned int max_elements = queue->max_elements;
        unsigned int __elements;
@@ -3760,10 +3761,11 @@ check_layout:
                *hdr = skb_push(skb, hdr_len);
                return hdr_len;
        }
-       /* fall back */
+
+       /* Fall back to cache element with known-good alignment: */
        if (hdr_len + proto_len > QETH_HDR_CACHE_OBJ_SIZE)
                return -E2BIG;
-       *hdr = kmem_cache_alloc(qeth_core_header_cache, GFP_ATOMIC);
+       *hdr = kmem_cache_alloc(qeth_core_header_cache, gfp);
        if (!*hdr)
                return -ENOMEM;
        /* Copy protocol headers behind HW header: */
index 4c8e931..8ba4ac2 100644 (file)
@@ -499,6 +499,7 @@ static void qeth_l2_rx_mode_work(struct work_struct *work)
 static int qeth_l2_xmit_osn(struct qeth_card *card, struct sk_buff *skb,
                            struct qeth_qdio_out_q *queue)
 {
+       gfp_t gfp = GFP_ATOMIC | (skb_pfmemalloc(skb) ? __GFP_MEMALLOC : 0);
        struct qeth_hdr *hdr = (struct qeth_hdr *)skb->data;
        addr_t end = (addr_t)(skb->data + sizeof(*hdr));
        addr_t start = (addr_t)skb->data;
@@ -511,7 +512,7 @@ static int qeth_l2_xmit_osn(struct qeth_card *card, struct sk_buff *skb,
 
        if (qeth_get_elements_for_range(start, end) > 1) {
                /* Misaligned HW header, move it to its own buffer element. */
-               hdr = kmem_cache_alloc(qeth_core_header_cache, GFP_ATOMIC);
+               hdr = kmem_cache_alloc(qeth_core_header_cache, gfp);
                if (!hdr)
                        return -ENOMEM;
                hd_len = sizeof(*hdr);