History

rtnetlink: RTEXT_FILTER_SKIP_STATS support to avoid dumping inet/inet6 stats

Many commonly used functions like getifaddrs() invoke RTM_GETLINK to dump the interface information, and do not need the the AF_INET6 statististics that are always returned by default from rtnl_fill_ifinfo(). Computing the statistics can be an expensive operation that impacts scaling, so it is desirable to avoid this if the information is not needed. This patch adds a the RTEXT_FILTER_SKIP_STATS extended info flag that can be passed with netlink_request() to avoid statistics computation for the ifinfo path.

Sowmini Varadhan committed 11 years ago

Commit d5566fd1 parent ad1e7b95 files · +15 −7Browse files

Unified · Split

5 files
  1. include/net/rtnetlink.h +2 −1
  2. include/uapi/linux/rtnetlink.h +1 −0
  3. net/core/rtnetlink.c +1 −1
  4. net/ipv4/devinet.c +2 −1
  5. net/ipv6/addrconf.c +9 −4
include/net/rtnetlink.h+2−1
@@ -122,7 +122,8 @@ struct rtnl_af_ops { · 121 unmodified lines
122 int family;122 int family;
123 123
124 int (*fill_link_af)(struct sk_buff *skb,124 int (*fill_link_af)(struct sk_buff *skb,
125 const struct net_device *dev);125 const struct net_device *dev,
126 u32 ext_filter_mask);
126 size_t (*get_link_af_size)(const struct net_device *dev);127 size_t (*get_link_af_size)(const struct net_device *dev);
127 128
128 int (*validate_link_af)(const struct net_device *dev,129 int (*validate_link_af)(const struct net_device *dev,
include/uapi/linux/rtnetlink.h+1−0
@@ -667,6 +667,7 @@ struct tcamsg { · 666 unmodified lines
667#define RTEXT_FILTER_VF (1 << 0)667#define RTEXT_FILTER_VF (1 << 0)
668#define RTEXT_FILTER_BRVLAN (1 << 1)668#define RTEXT_FILTER_BRVLAN (1 << 1)
669#define RTEXT_FILTER_BRVLAN_COMPRESSED (1 << 2)669#define RTEXT_FILTER_BRVLAN_COMPRESSED (1 << 2)
670#define RTEXT_FILTER_SKIP_STATS (1 << 3)
670 671
671/* End of information exported to user level */672/* End of information exported to user level */
672 673
net/core/rtnetlink.c+1−1
@@ -1272,7 +1272,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, · 1271 unmodified lines
1272 if (!(af = nla_nest_start(skb, af_ops->family)))1272 if (!(af = nla_nest_start(skb, af_ops->family)))
1273 goto nla_put_failure;1273 goto nla_put_failure;
1274 1274
1275 err = af_ops->fill_link_af(skb, dev);1275 err = af_ops->fill_link_af(skb, dev, ext_filter_mask);
1276 1276
1277 /*1277 /*
1278 * Caller may return ENODATA to indicate that there1278 * Caller may return ENODATA to indicate that there
net/ipv4/devinet.c+2−1
@@ -1654,7 +1654,8 @@ static size_t inet_get_link_af_size(const struct net_device *dev) · 1653 unmodified lines
1654 return nla_total_size(IPV4_DEVCONF_MAX * 4); /* IFLA_INET_CONF */1654 return nla_total_size(IPV4_DEVCONF_MAX * 4); /* IFLA_INET_CONF */
1655}1655}
1656 1656
1657static int inet_fill_link_af(struct sk_buff *skb, const struct net_device *dev)1657static int inet_fill_link_af(struct sk_buff *skb, const struct net_device *dev,
1658 u32 ext_filter_mask)
1658{1659{
1659 struct in_device *in_dev = rcu_dereference_rtnl(dev->ip_ptr);1660 struct in_device *in_dev = rcu_dereference_rtnl(dev->ip_ptr);
1660 struct nlattr *nla;1661 struct nlattr *nla;
net/ipv6/addrconf.c+9−4
@@ -4729,7 +4729,8 @@ static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, · 4728 unmodified lines
4729 }4729 }
4730}4730}
4731 4731
4732static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev)4732static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev,
4733 u32 ext_filter_mask)
4733{4734{
4734 struct nlattr *nla;4735 struct nlattr *nla;
4735 struct ifla_cacheinfo ci;4736 struct ifla_cacheinfo ci;
@@ -4749,6 +4750,9 @@ static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev) · 13 unmodified lines
4749 4750
4750 /* XXX - MC not implemented */4751 /* XXX - MC not implemented */
4751 4752
4753 if (ext_filter_mask & RTEXT_FILTER_SKIP_STATS)
4754 return 0;
4755
4752 nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64));4756 nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64));
4753 if (!nla)4757 if (!nla)
4754 goto nla_put_failure;4758 goto nla_put_failure;
@@ -4784,14 +4788,15 @@ static size_t inet6_get_link_af_size(const struct net_device *dev) · 29 unmodified lines
4784 return inet6_ifla6_size();4788 return inet6_ifla6_size();
4785}4789}
4786 4790
4787static int inet6_fill_link_af(struct sk_buff *skb, const struct net_device *dev)4791static int inet6_fill_link_af(struct sk_buff *skb, const struct net_device *dev,
4792 u32 ext_filter_mask)
4788{4793{
4789 struct inet6_dev *idev = __in6_dev_get(dev);4794 struct inet6_dev *idev = __in6_dev_get(dev);
4790 4795
4791 if (!idev)4796 if (!idev)
4792 return -ENODATA;4797 return -ENODATA;
4793 4798
4794 if (inet6_fill_ifla6_attrs(skb, idev) < 0)4799 if (inet6_fill_ifla6_attrs(skb, idev, ext_filter_mask) < 0)
4795 return -EMSGSIZE;4800 return -EMSGSIZE;
4796 4801
4797 return 0;4802 return 0;
@@ -4946,7 +4951,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, · 148 unmodified lines
4946 if (!protoinfo)4951 if (!protoinfo)
4947 goto nla_put_failure;4952 goto nla_put_failure;
4948 4953
4949 if (inet6_fill_ifla6_attrs(skb, idev) < 0)4954 if (inet6_fill_ifla6_attrs(skb, idev, 0) < 0)
4950 goto nla_put_failure;4955 goto nla_put_failure;
4951 4956
4952 nla_nest_end(skb, protoinfo);4957 nla_nest_end(skb, protoinfo);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t