diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2011-11-14 23:12:55 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-11-16 17:30:06 -0500 |
commit | 588f033075d8c7efe28695402114eab3f9da47c4 (patch) | |
tree | e057253b48041762ca0d747374521e5edf51c644 /net/core/dev.c | |
parent | 66846048f55c6c05a4c46c2daabb773173f8f28d (diff) |
net: use jump_label for netstamp_needed
netstamp_needed seems a good candidate to jump_label conversion.
This avoids 3 conditional branches per incoming packet in fast path.
No measurable difference, given that these conditional branches are
predicted on modern cpus. Only a small icache reduction, thanks to the
unlikely() stuff.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 32 |
1 files changed, 14 insertions, 18 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 6ba50a1e404c..51f89cd0a3f4 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -137,6 +137,7 @@ | |||
137 | #include <linux/if_pppox.h> | 137 | #include <linux/if_pppox.h> |
138 | #include <linux/ppp_defs.h> | 138 | #include <linux/ppp_defs.h> |
139 | #include <linux/net_tstamp.h> | 139 | #include <linux/net_tstamp.h> |
140 | #include <linux/jump_label.h> | ||
140 | 141 | ||
141 | #include "net-sysfs.h" | 142 | #include "net-sysfs.h" |
142 | 143 | ||
@@ -1449,34 +1450,32 @@ int call_netdevice_notifiers(unsigned long val, struct net_device *dev) | |||
1449 | } | 1450 | } |
1450 | EXPORT_SYMBOL(call_netdevice_notifiers); | 1451 | EXPORT_SYMBOL(call_netdevice_notifiers); |
1451 | 1452 | ||
1452 | /* When > 0 there are consumers of rx skb time stamps */ | 1453 | static struct jump_label_key netstamp_needed __read_mostly; |
1453 | static atomic_t netstamp_needed = ATOMIC_INIT(0); | ||
1454 | 1454 | ||
1455 | void net_enable_timestamp(void) | 1455 | void net_enable_timestamp(void) |
1456 | { | 1456 | { |
1457 | atomic_inc(&netstamp_needed); | 1457 | jump_label_inc(&netstamp_needed); |
1458 | } | 1458 | } |
1459 | EXPORT_SYMBOL(net_enable_timestamp); | 1459 | EXPORT_SYMBOL(net_enable_timestamp); |
1460 | 1460 | ||
1461 | void net_disable_timestamp(void) | 1461 | void net_disable_timestamp(void) |
1462 | { | 1462 | { |
1463 | atomic_dec(&netstamp_needed); | 1463 | jump_label_dec(&netstamp_needed); |
1464 | } | 1464 | } |
1465 | EXPORT_SYMBOL(net_disable_timestamp); | 1465 | EXPORT_SYMBOL(net_disable_timestamp); |
1466 | 1466 | ||
1467 | static inline void net_timestamp_set(struct sk_buff *skb) | 1467 | static inline void net_timestamp_set(struct sk_buff *skb) |
1468 | { | 1468 | { |
1469 | if (atomic_read(&netstamp_needed)) | 1469 | skb->tstamp.tv64 = 0; |
1470 | if (static_branch(&netstamp_needed)) | ||
1470 | __net_timestamp(skb); | 1471 | __net_timestamp(skb); |
1471 | else | ||
1472 | skb->tstamp.tv64 = 0; | ||
1473 | } | 1472 | } |
1474 | 1473 | ||
1475 | static inline void net_timestamp_check(struct sk_buff *skb) | 1474 | #define net_timestamp_check(COND, SKB) \ |
1476 | { | 1475 | if (static_branch(&netstamp_needed)) { \ |
1477 | if (!skb->tstamp.tv64 && atomic_read(&netstamp_needed)) | 1476 | if ((COND) && !(SKB)->tstamp.tv64) \ |
1478 | __net_timestamp(skb); | 1477 | __net_timestamp(SKB); \ |
1479 | } | 1478 | } \ |
1480 | 1479 | ||
1481 | static int net_hwtstamp_validate(struct ifreq *ifr) | 1480 | static int net_hwtstamp_validate(struct ifreq *ifr) |
1482 | { | 1481 | { |
@@ -2997,8 +2996,7 @@ int netif_rx(struct sk_buff *skb) | |||
2997 | if (netpoll_rx(skb)) | 2996 | if (netpoll_rx(skb)) |
2998 | return NET_RX_DROP; | 2997 | return NET_RX_DROP; |
2999 | 2998 | ||
3000 | if (netdev_tstamp_prequeue) | 2999 | net_timestamp_check(netdev_tstamp_prequeue, skb); |
3001 | net_timestamp_check(skb); | ||
3002 | 3000 | ||
3003 | trace_netif_rx(skb); | 3001 | trace_netif_rx(skb); |
3004 | #ifdef CONFIG_RPS | 3002 | #ifdef CONFIG_RPS |
@@ -3230,8 +3228,7 @@ static int __netif_receive_skb(struct sk_buff *skb) | |||
3230 | int ret = NET_RX_DROP; | 3228 | int ret = NET_RX_DROP; |
3231 | __be16 type; | 3229 | __be16 type; |
3232 | 3230 | ||
3233 | if (!netdev_tstamp_prequeue) | 3231 | net_timestamp_check(!netdev_tstamp_prequeue, skb); |
3234 | net_timestamp_check(skb); | ||
3235 | 3232 | ||
3236 | trace_netif_receive_skb(skb); | 3233 | trace_netif_receive_skb(skb); |
3237 | 3234 | ||
@@ -3362,8 +3359,7 @@ out: | |||
3362 | */ | 3359 | */ |
3363 | int netif_receive_skb(struct sk_buff *skb) | 3360 | int netif_receive_skb(struct sk_buff *skb) |
3364 | { | 3361 | { |
3365 | if (netdev_tstamp_prequeue) | 3362 | net_timestamp_check(netdev_tstamp_prequeue, skb); |
3366 | net_timestamp_check(skb); | ||
3367 | 3363 | ||
3368 | if (skb_defer_rx_timestamp(skb)) | 3364 | if (skb_defer_rx_timestamp(skb)) |
3369 | return NET_RX_SUCCESS; | 3365 | return NET_RX_SUCCESS; |