Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ipv4: Introduce IN_DEV_NET_ROUTE_LOCALNET

performance profiles show a high cost in the IN_DEV_ROUTE_LOCALNET()
call done in ip_route_input_slow(), because of multiple dereferences,
even if cache lines are clean and available in cpu caches.

Since we already have the 'net' pointer, introduce
IN_DEV_NET_ROUTE_LOCALNET() macro avoiding two dereferences
(dev_net(in_dev->dev))

Also change the tests to use IN_DEV_NET_ROUTE_LOCALNET() only if saddr
or/and daddr are loopback addresse.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Eric Dumazet and committed by
David S. Miller
9eb43e76 40384999

+16 -6
+9 -2
include/linux/inetdevice.h
··· 104 104 #define IN_DEV_ANDCONF(in_dev, attr) \ 105 105 (IPV4_DEVCONF_ALL(dev_net(in_dev->dev), attr) && \ 106 106 IN_DEV_CONF_GET((in_dev), attr)) 107 - #define IN_DEV_ORCONF(in_dev, attr) \ 108 - (IPV4_DEVCONF_ALL(dev_net(in_dev->dev), attr) || \ 107 + 108 + #define IN_DEV_NET_ORCONF(in_dev, net, attr) \ 109 + (IPV4_DEVCONF_ALL(net, attr) || \ 109 110 IN_DEV_CONF_GET((in_dev), attr)) 111 + 112 + #define IN_DEV_ORCONF(in_dev, attr) \ 113 + IN_DEV_NET_ORCONF(in_dev, dev_net(in_dev->dev), attr) 114 + 110 115 #define IN_DEV_MAXCONF(in_dev, attr) \ 111 116 (max(IPV4_DEVCONF_ALL(dev_net(in_dev->dev), attr), \ 112 117 IN_DEV_CONF_GET((in_dev), attr))) ··· 138 133 IN_DEV_ORCONF((in_dev), \ 139 134 PROMOTE_SECONDARIES) 140 135 #define IN_DEV_ROUTE_LOCALNET(in_dev) IN_DEV_ORCONF(in_dev, ROUTE_LOCALNET) 136 + #define IN_DEV_NET_ROUTE_LOCALNET(in_dev, net) \ 137 + IN_DEV_NET_ORCONF(in_dev, net, ROUTE_LOCALNET) 141 138 142 139 #define IN_DEV_RX_REDIRECTS(in_dev) \ 143 140 ((IN_DEV_FORWARD(in_dev) && \
+7 -4
net/ipv4/route.c
··· 1587 1587 if (ipv4_is_zeronet(daddr)) 1588 1588 goto martian_destination; 1589 1589 1590 - if (likely(!IN_DEV_ROUTE_LOCALNET(in_dev))) { 1591 - if (ipv4_is_loopback(daddr)) 1590 + /* Following code try to avoid calling IN_DEV_NET_ROUTE_LOCALNET(), 1591 + * and call it once if daddr or/and saddr are loopback addresses 1592 + */ 1593 + if (ipv4_is_loopback(daddr)) { 1594 + if (!IN_DEV_NET_ROUTE_LOCALNET(in_dev, net)) 1592 1595 goto martian_destination; 1593 - 1594 - if (ipv4_is_loopback(saddr)) 1596 + } else if (ipv4_is_loopback(saddr)) { 1597 + if (!IN_DEV_NET_ROUTE_LOCALNET(in_dev, net)) 1595 1598 goto martian_source; 1596 1599 } 1597 1600