]> rtime.felk.cvut.cz Git - zynq/linux.git/blobdiff - include/linux/netdevice.h
Apply preempt_rt patch-4.9-rt1.patch.xz
[zynq/linux.git] / include / linux / netdevice.h
index 91ee3643ccc8df3f8d244b6dd5f47526ea688274..7a1074bdd820e8a3b1e1f79111a99c9d967390f0 100644 (file)
@@ -396,7 +396,19 @@ typedef enum rx_handler_result rx_handler_result_t;
 typedef rx_handler_result_t rx_handler_func_t(struct sk_buff **pskb);
 
 void __napi_schedule(struct napi_struct *n);
+
+/*
+ * When PREEMPT_RT_FULL is defined, all device interrupt handlers
+ * run as threads, and they can also be preempted (without PREEMPT_RT
+ * interrupt threads can not be preempted). Which means that calling
+ * __napi_schedule_irqoff() from an interrupt handler can be preempted
+ * and can corrupt the napi->poll_list.
+ */
+#ifdef CONFIG_PREEMPT_RT_FULL
+#define __napi_schedule_irqoff(n) __napi_schedule(n)
+#else
 void __napi_schedule_irqoff(struct napi_struct *n);
+#endif
 
 static inline bool napi_disable_pending(struct napi_struct *n)
 {
@@ -1619,7 +1631,7 @@ enum netdev_priv_flags {
  *     @dcbnl_ops:     Data Center Bridging netlink ops
  *     @num_tc:        Number of traffic classes in the net device
  *     @tc_to_txq:     XXX: need comments on this one
- *     @prio_tc_map    XXX: need comments on this one
+ *     @prio_tc_map:   XXX: need comments on this one
  *
  *     @fcoe_ddp_xid:  Max exchange id for FCoE LRO by ddp
  *
@@ -2461,14 +2473,53 @@ void netdev_freemem(struct net_device *dev);
 void synchronize_net(void);
 int init_dummy_netdev(struct net_device *dev);
 
-DECLARE_PER_CPU(int, xmit_recursion);
 #define XMIT_RECURSION_LIMIT   10
+#ifdef CONFIG_PREEMPT_RT_FULL
+static inline int dev_recursion_level(void)
+{
+       return current->xmit_recursion;
+}
+
+static inline int xmit_rec_read(void)
+{
+       return current->xmit_recursion;
+}
+
+static inline void xmit_rec_inc(void)
+{
+       current->xmit_recursion++;
+}
+
+static inline void xmit_rec_dec(void)
+{
+       current->xmit_recursion--;
+}
+
+#else
+
+DECLARE_PER_CPU(int, xmit_recursion);
 
 static inline int dev_recursion_level(void)
 {
        return this_cpu_read(xmit_recursion);
 }
 
+static inline int xmit_rec_read(void)
+{
+       return __this_cpu_read(xmit_recursion);
+}
+
+static inline void xmit_rec_inc(void)
+{
+       __this_cpu_inc(xmit_recursion);
+}
+
+static inline void xmit_rec_dec(void)
+{
+       __this_cpu_dec(xmit_recursion);
+}
+#endif
+
 struct net_device *dev_get_by_index(struct net *net, int ifindex);
 struct net_device *__dev_get_by_index(struct net *net, int ifindex);
 struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex);
@@ -2846,6 +2897,7 @@ struct softnet_data {
        unsigned int            dropped;
        struct sk_buff_head     input_pkt_queue;
        struct napi_struct      backlog;
+       struct sk_buff_head     tofree_queue;
 
 };
 
@@ -3354,6 +3406,21 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb);
 bool is_skb_forwardable(const struct net_device *dev,
                        const struct sk_buff *skb);
 
+static __always_inline int ____dev_forward_skb(struct net_device *dev,
+                                              struct sk_buff *skb)
+{
+       if (skb_orphan_frags(skb, GFP_ATOMIC) ||
+           unlikely(!is_skb_forwardable(dev, skb))) {
+               atomic_long_inc(&dev->rx_dropped);
+               kfree_skb(skb);
+               return NET_RX_DROP;
+       }
+
+       skb_scrub_packet(skb, true);
+       skb->priority = 0;
+       return 0;
+}
+
 void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev);
 
 extern int             netdev_budget;