This patch was used to test patch ("net: Support flow sorted skb lists
for IPv4.") It is just a hack that disables GRO and does skb list
receive instead. Not for merging!

Signed-off-by: Steffen Klassert <steffen.klass...@secunet.com>
---
 include/linux/netdevice.h |  5 ++++-
 net/core/dev.c            | 23 ++++++++++++++---------
 net/ipv4/ip_input.c       |  1 +
 3 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index e2b3bd750c98..6518ceeda05d 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -333,7 +333,10 @@ struct napi_struct {
        int                     poll_owner;
 #endif
        struct net_device       *dev;
-       struct gro_list         gro_hash[GRO_HASH_BUCKETS];
+       union {
+               struct list_head        rx_list;
+               struct gro_list         gro_hash[GRO_HASH_BUCKETS];
+       };
        struct sk_buff          *skb;
        struct hrtimer          timer;
        struct list_head        dev_list;
diff --git a/net/core/dev.c b/net/core/dev.c
index 147da35d7380..68e00727c657 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5470,6 +5470,10 @@ static enum gro_result dev_gro_receive(struct 
napi_struct *napi, struct sk_buff
        int same_flow;
        int grow;
 
+       list_add_tail(&skb->list, &napi->rx_list);
+       ret = GRO_CONSUMED;
+       goto out;
+
        if (netif_elide_gro(skb->dev))
                goto normal;
 
@@ -5559,7 +5563,7 @@ static enum gro_result dev_gro_receive(struct napi_struct 
*napi, struct sk_buff
        } else if (test_bit(hash, &napi->gro_bitmask)) {
                __clear_bit(hash, &napi->gro_bitmask);
        }
-
+out:
        return ret;
 
 normal:
@@ -5958,7 +5962,7 @@ bool napi_complete_done(struct napi_struct *n, int 
work_done)
                                 NAPIF_STATE_IN_BUSY_POLL)))
                return false;
 
-       if (n->gro_bitmask) {
+       if (!list_empty(&n->rx_list)) {
                unsigned long timeout = 0;
 
                if (work_done)
@@ -5967,8 +5971,10 @@ bool napi_complete_done(struct napi_struct *n, int 
work_done)
                if (timeout)
                        hrtimer_start(&n->timer, ns_to_ktime(timeout),
                                      HRTIMER_MODE_REL_PINNED);
-               else
-                       napi_gro_flush(n, false);
+               else {
+                       netif_receive_skb_list(&n->rx_list);
+                       INIT_LIST_HEAD(&n->rx_list);
+               }
        }
        if (unlikely(!list_empty(&n->poll_list))) {
                /* If n->poll_list is not empty, we need to mask irqs */
@@ -6189,6 +6195,7 @@ void netif_napi_add(struct net_device *dev, struct 
napi_struct *napi,
                    int (*poll)(struct napi_struct *, int), int weight)
 {
        INIT_LIST_HEAD(&napi->poll_list);
+       INIT_LIST_HEAD(&napi->rx_list);
        hrtimer_init(&napi->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_PINNED);
        napi->timer.function = napi_watchdog;
        init_gro_hash(napi);
@@ -6289,11 +6296,9 @@ static int napi_poll(struct napi_struct *n, struct 
list_head *repoll)
                goto out_unlock;
        }
 
-       if (n->gro_bitmask) {
-               /* flush too old packets
-                * If HZ < 1000, flush all packets.
-                */
-               napi_gro_flush(n, HZ >= 1000);
+       if (!list_empty(&n->rx_list)) {
+               netif_receive_skb_list(&n->rx_list);
+               INIT_LIST_HEAD(&n->rx_list);
        }
 
        /* Some drivers may have called napi_schedule
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index bf710bf95fea..847965f83a2f 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -729,6 +729,7 @@ void ip_list_rcv(struct list_head *head, struct packet_type 
*pt,
                }
                list_add_tail(&skb->list, &sublist);
        }
+
        /* dispatch final sublist */
        ip_sublist_rcv(&sublist, curr_dev, curr_net);
 }
-- 
2.17.1

Reply via email to