Skip to content

Commit 97cdcf3

Browse files
Florian Westphaldavem330
authored andcommitted
net: place xmit recursion in softnet data
This fills a hole in softnet data, so no change in structure size. Also prepares for xmit_more placement in the same spot; skb->xmit_more will be removed in followup patch. Signed-off-by: Florian Westphal <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 74dcb4c commit 97cdcf3

File tree

3 files changed

+38
-18
lines changed

3 files changed

+38
-18
lines changed

include/linux/netdevice.h

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2659,14 +2659,6 @@ void netdev_freemem(struct net_device *dev);
26592659
void synchronize_net(void);
26602660
int init_dummy_netdev(struct net_device *dev);
26612661

2662-
DECLARE_PER_CPU(int, xmit_recursion);
2663-
#define XMIT_RECURSION_LIMIT 10
2664-
2665-
static inline int dev_recursion_level(void)
2666-
{
2667-
return this_cpu_read(xmit_recursion);
2668-
}
2669-
26702662
struct net_device *dev_get_by_index(struct net *net, int ifindex);
26712663
struct net_device *__dev_get_by_index(struct net *net, int ifindex);
26722664
struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex);
@@ -3015,6 +3007,11 @@ struct softnet_data {
30153007
#ifdef CONFIG_XFRM_OFFLOAD
30163008
struct sk_buff_head xfrm_backlog;
30173009
#endif
3010+
/* written and read only by owning cpu: */
3011+
struct {
3012+
u16 recursion;
3013+
u8 more;
3014+
} xmit;
30183015
#ifdef CONFIG_RPS
30193016
/* input_queue_head should be written by cpu owning this struct,
30203017
* and only read by other cpus. Worth using a cache line.
@@ -3050,6 +3047,28 @@ static inline void input_queue_tail_incr_save(struct softnet_data *sd,
30503047

30513048
DECLARE_PER_CPU_ALIGNED(struct softnet_data, softnet_data);
30523049

3050+
static inline int dev_recursion_level(void)
3051+
{
3052+
return __this_cpu_read(softnet_data.xmit.recursion);
3053+
}
3054+
3055+
#define XMIT_RECURSION_LIMIT 10
3056+
static inline bool dev_xmit_recursion(void)
3057+
{
3058+
return unlikely(__this_cpu_read(softnet_data.xmit.recursion) >
3059+
XMIT_RECURSION_LIMIT);
3060+
}
3061+
3062+
static inline void dev_xmit_recursion_inc(void)
3063+
{
3064+
__this_cpu_inc(softnet_data.xmit.recursion);
3065+
}
3066+
3067+
static inline void dev_xmit_recursion_dec(void)
3068+
{
3069+
__this_cpu_dec(softnet_data.xmit.recursion);
3070+
}
3071+
30533072
void __netif_schedule(struct Qdisc *q);
30543073
void netif_schedule_queue(struct netdev_queue *txq);
30553074

@@ -4409,6 +4428,11 @@ static inline netdev_tx_t __netdev_start_xmit(const struct net_device_ops *ops,
44094428
return ops->ndo_start_xmit(skb, dev);
44104429
}
44114430

4431+
static inline bool netdev_xmit_more(void)
4432+
{
4433+
return __this_cpu_read(softnet_data.xmit.more);
4434+
}
4435+
44124436
static inline netdev_tx_t netdev_start_xmit(struct sk_buff *skb, struct net_device *dev,
44134437
struct netdev_queue *txq, bool more)
44144438
{

net/core/dev.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3566,9 +3566,6 @@ static void skb_update_prio(struct sk_buff *skb)
35663566
#define skb_update_prio(skb)
35673567
#endif
35683568

3569-
DEFINE_PER_CPU(int, xmit_recursion);
3570-
EXPORT_SYMBOL(xmit_recursion);
3571-
35723569
/**
35733570
* dev_loopback_xmit - loop back @skb
35743571
* @net: network namespace this loopback is happening in
@@ -3857,8 +3854,7 @@ static int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev)
38573854
int cpu = smp_processor_id(); /* ok because BHs are off */
38583855

38593856
if (txq->xmit_lock_owner != cpu) {
3860-
if (unlikely(__this_cpu_read(xmit_recursion) >
3861-
XMIT_RECURSION_LIMIT))
3857+
if (dev_xmit_recursion())
38623858
goto recursion_alert;
38633859

38643860
skb = validate_xmit_skb(skb, dev, &again);
@@ -3868,9 +3864,9 @@ static int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev)
38683864
HARD_TX_LOCK(dev, txq, cpu);
38693865

38703866
if (!netif_xmit_stopped(txq)) {
3871-
__this_cpu_inc(xmit_recursion);
3867+
dev_xmit_recursion_inc();
38723868
skb = dev_hard_start_xmit(skb, dev, txq, &rc);
3873-
__this_cpu_dec(xmit_recursion);
3869+
dev_xmit_recursion_dec();
38743870
if (dev_xmit_complete(rc)) {
38753871
HARD_TX_UNLOCK(dev, txq);
38763872
goto out;

net/core/filter.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,17 +2016,17 @@ static inline int __bpf_tx_skb(struct net_device *dev, struct sk_buff *skb)
20162016
{
20172017
int ret;
20182018

2019-
if (unlikely(__this_cpu_read(xmit_recursion) > XMIT_RECURSION_LIMIT)) {
2019+
if (dev_xmit_recursion()) {
20202020
net_crit_ratelimited("bpf: recursion limit reached on datapath, buggy bpf program?\n");
20212021
kfree_skb(skb);
20222022
return -ENETDOWN;
20232023
}
20242024

20252025
skb->dev = dev;
20262026

2027-
__this_cpu_inc(xmit_recursion);
2027+
dev_xmit_recursion_inc();
20282028
ret = dev_queue_xmit(skb);
2029-
__this_cpu_dec(xmit_recursion);
2029+
dev_xmit_recursion_dec();
20302030

20312031
return ret;
20322032
}

0 commit comments

Comments
 (0)