diff options
author | Eric Dumazet <dada1@cosmosbay.com> | 2009-05-18 22:19:19 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-05-18 22:19:19 -0700 |
commit | 93f154b594fe47e4a7e5358b309add449a046cd3 (patch) | |
tree | 479d9f2db25922a2312547c97e73d5a11b68bb1c /include/linux/if.h | |
parent | 496a60cdcd5d0d884dddf6c3b4ea912923a70f13 (diff) | |
download | linux-3.10-93f154b594fe47e4a7e5358b309add449a046cd3.tar.gz linux-3.10-93f154b594fe47e4a7e5358b309add449a046cd3.tar.bz2 linux-3.10-93f154b594fe47e4a7e5358b309add449a046cd3.zip |
net: release dst entry in dev_hard_start_xmit()
One point of contention in high network loads is the dst_release() performed
when a transmited skb is freed. This is because NIC tx completion calls
dev_kree_skb() long after original call to dev_queue_xmit(skb).
CPU cache is cold and the atomic op in dst_release() stalls. On SMP, this is
quite visible if one CPU is 100% handling softirqs for a network device,
since dst_clone() is done by other cpus, involving cache line ping pongs.
It seems right place to release dst is in dev_hard_start_xmit(), for most
devices but ones that are virtual, and some exceptions.
David Miller suggested to define a new device flag, set in alloc_netdev_mq()
(so that most devices set it at init time), and carefuly unset in devices
which dont want a NULL skb->dst in their ndo_start_xmit().
List of devices that must clear this flag is :
- loopback device, because it calls netif_rx() and quoting Patrick :
"ip_route_input() doesn't accept loopback addresses, so loopback packets
already need to have a dst_entry attached."
- appletalk/ipddp.c : needs skb->dst in its xmit function
- And all devices that call again dev_queue_xmit() from their xmit function
(as some classifiers need skb->dst) : bonding, vlan, macvlan, eql, ifb, hdlc_fr
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/if.h')
-rw-r--r-- | include/linux/if.h | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/include/linux/if.h b/include/linux/if.h index 1108f3e099e..b9a6229f3be 100644 --- a/include/linux/if.h +++ b/include/linux/if.h @@ -67,6 +67,9 @@ #define IFF_ISATAP 0x80 /* ISATAP interface (RFC4214) */ #define IFF_MASTER_ARPMON 0x100 /* bonding master, ARP mon in use */ #define IFF_WAN_HDLC 0x200 /* WAN HDLC device */ +#define IFF_XMIT_DST_RELEASE 0x400 /* dev_hard_start_xmit() is allowed to + * release skb->dst + */ #define IF_GET_IFACE 0x0001 /* for querying only */ #define IF_GET_PROTO 0x0002 |