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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'rtnetlink-rtnl_stats_dump-changes'

Eric Dumazet says:

====================
rtnetlink: rtnl_stats_dump() changes

Getting rid of RTNL in rtnl_stats_dump() looks challenging.

In the meantime, we can:

1) Avoid RTNL acquisition for the final NLMSG_DONE marker.

2) Use for_each_netdev_dump() instead of the net->dev_index_head[]
hash table.
====================

Link: https://lore.kernel.org/r/20240502113748.1622637-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+23 -38
+23 -38
net/core/rtnetlink.c
··· 5961 5961 static int rtnl_stats_dump(struct sk_buff *skb, struct netlink_callback *cb) 5962 5962 { 5963 5963 struct netlink_ext_ack *extack = cb->extack; 5964 - int h, s_h, err, s_idx, s_idxattr, s_prividx; 5965 5964 struct rtnl_stats_dump_filters filters; 5966 5965 struct net *net = sock_net(skb->sk); 5967 5966 unsigned int flags = NLM_F_MULTI; 5968 5967 struct if_stats_msg *ifsm; 5969 - struct hlist_head *head; 5968 + struct { 5969 + unsigned long ifindex; 5970 + int idxattr; 5971 + int prividx; 5972 + } *ctx = (void *)cb->ctx; 5970 5973 struct net_device *dev; 5971 - int idx = 0; 5972 - 5973 - s_h = cb->args[0]; 5974 - s_idx = cb->args[1]; 5975 - s_idxattr = cb->args[2]; 5976 - s_prividx = cb->args[3]; 5974 + int err; 5977 5975 5978 5976 cb->seq = net->dev_base_seq; 5979 5977 ··· 5990 5992 if (err) 5991 5993 return err; 5992 5994 5993 - for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { 5994 - idx = 0; 5995 - head = &net->dev_index_head[h]; 5996 - hlist_for_each_entry(dev, head, index_hlist) { 5997 - if (idx < s_idx) 5998 - goto cont; 5999 - err = rtnl_fill_statsinfo(skb, dev, RTM_NEWSTATS, 6000 - NETLINK_CB(cb->skb).portid, 6001 - cb->nlh->nlmsg_seq, 0, 6002 - flags, &filters, 6003 - &s_idxattr, &s_prividx, 6004 - extack); 6005 - /* If we ran out of room on the first message, 6006 - * we're in trouble 6007 - */ 6008 - WARN_ON((err == -EMSGSIZE) && (skb->len == 0)); 5995 + for_each_netdev_dump(net, dev, ctx->ifindex) { 5996 + err = rtnl_fill_statsinfo(skb, dev, RTM_NEWSTATS, 5997 + NETLINK_CB(cb->skb).portid, 5998 + cb->nlh->nlmsg_seq, 0, 5999 + flags, &filters, 6000 + &ctx->idxattr, &ctx->prividx, 6001 + extack); 6002 + /* If we ran out of room on the first message, 6003 + * we're in trouble. 6004 + */ 6005 + WARN_ON((err == -EMSGSIZE) && (skb->len == 0)); 6009 6006 6010 - if (err < 0) 6011 - goto out; 6012 - s_prividx = 0; 6013 - s_idxattr = 0; 6014 - nl_dump_check_consistent(cb, nlmsg_hdr(skb)); 6015 - cont: 6016 - idx++; 6017 - } 6007 + if (err < 0) 6008 + break; 6009 + ctx->prividx = 0; 6010 + ctx->idxattr = 0; 6011 + nl_dump_check_consistent(cb, nlmsg_hdr(skb)); 6018 6012 } 6019 - out: 6020 - cb->args[3] = s_prividx; 6021 - cb->args[2] = s_idxattr; 6022 - cb->args[1] = idx; 6023 - cb->args[0] = h; 6024 6013 6025 - return skb->len; 6014 + return err; 6026 6015 } 6027 6016 6028 6017 void rtnl_offload_xstats_notify(struct net_device *dev)