};
enum gro_result {
-@@ -2249,6 +2252,26 @@ void netif_napi_add(struct net_device *d
+@@ -2101,6 +2104,7 @@ struct net_device {
+ struct lock_class_key addr_list_lock_key;
+ bool proto_down;
+ unsigned wol_enabled:1;
++ unsigned threaded:1;
+ };
+ #define to_net_dev(d) container_of(d, struct net_device, dev)
+
+@@ -2281,6 +2285,26 @@ void netif_napi_add(struct net_device *d
int (*poll)(struct napi_struct *, int), int weight);
/**
static int netif_rx_internal(struct sk_buff *skb);
static int call_netdevice_notifiers_info(unsigned long val,
-@@ -5910,6 +5911,11 @@ void __napi_schedule(struct napi_struct
+@@ -5940,6 +5941,11 @@ void __napi_schedule(struct napi_struct
{
unsigned long flags;
local_irq_save(flags);
____napi_schedule(this_cpu_ptr(&softnet_data), n);
local_irq_restore(flags);
-@@ -5957,6 +5963,11 @@ EXPORT_SYMBOL(napi_schedule_prep);
+@@ -5991,6 +5997,10 @@ EXPORT_SYMBOL(napi_schedule_prep);
*/
void __napi_schedule_irqoff(struct napi_struct *n)
{
+ queue_work(napi_workq, &n->work);
+ return;
+ }
-+
- ____napi_schedule(this_cpu_ptr(&softnet_data), n);
- }
- EXPORT_SYMBOL(__napi_schedule_irqoff);
-@@ -6218,6 +6229,84 @@ static void init_gro_hash(struct napi_st
+ if (!IS_ENABLED(CONFIG_PREEMPT_RT))
+ ____napi_schedule(this_cpu_ptr(&softnet_data), n);
+ else
+@@ -6255,9 +6265,89 @@ static void init_gro_hash(struct napi_st
napi->gro_bitmask = 0;
}
void netif_napi_add(struct net_device *dev, struct napi_struct *napi,
int (*poll)(struct napi_struct *, int), int weight)
{
-@@ -6237,6 +6326,7 @@ void netif_napi_add(struct net_device *d
++ if (dev->threaded)
++ set_bit(NAPI_STATE_THREADED, &napi->state);
+ INIT_LIST_HEAD(&napi->poll_list);
+ hrtimer_init(&napi->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_PINNED);
+ napi->timer.function = napi_watchdog;
+@@ -6274,6 +6364,7 @@ void netif_napi_add(struct net_device *d
#ifdef CONFIG_NETPOLL
napi->poll_owner = -1;
#endif
set_bit(NAPI_STATE_SCHED, &napi->state);
set_bit(NAPI_STATE_NPSVC, &napi->state);
list_add_rcu(&napi->dev_list, &dev->napi_list);
-@@ -6277,6 +6367,7 @@ static void flush_gro_hash(struct napi_s
+@@ -6314,6 +6405,7 @@ static void flush_gro_hash(struct napi_s
void netif_napi_del(struct napi_struct *napi)
{
might_sleep();
if (napi_hash_del(napi))
synchronize_net();
list_del_init(&napi->dev_list);
-@@ -6289,50 +6380,18 @@ EXPORT_SYMBOL(netif_napi_del);
+@@ -6326,50 +6418,18 @@ EXPORT_SYMBOL(netif_napi_del);
static int napi_poll(struct napi_struct *n, struct list_head *repoll)
{
have = netpoll_poll_lock(n);
- weight = n->weight;
-+ work = __napi_poll(n, &do_repoll);
-
+-
- /* This NAPI_STATE_SCHED test is for avoiding a race
- * with netpoll's poll_napi(). Only the entity which
- * obtains the lock and sees NAPI_STATE_SCHED set will
- }
-
- WARN_ON_ONCE(work > weight);
--
++ work = __napi_poll(n, &do_repoll);
+
- if (likely(work < weight))
- goto out_unlock;
-
/* Some drivers may have called napi_schedule
* prior to exhausting their budget.
-@@ -10270,6 +10329,10 @@ static int __init net_dev_init(void)
+@@ -10349,6 +10409,10 @@ static int __init net_dev_init(void)
sd->backlog.weight = weight_p;
}
/* The loopback device is special if any other network devices
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
-@@ -442,6 +442,52 @@ static ssize_t proto_down_store(struct d
+@@ -470,6 +470,52 @@ static ssize_t proto_down_store(struct d
}
NETDEVICE_SHOW_RW(proto_down, fmt_dec);
static ssize_t phys_port_id_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
-@@ -532,6 +578,7 @@ static struct attribute *net_class_attrs
+@@ -581,6 +627,7 @@ static struct attribute *net_class_attrs
&dev_attr_flags.attr,
&dev_attr_tx_queue_len.attr,
&dev_attr_gro_flush_timeout.attr,