Skip to content

Commit f3ad491

Browse files
committed
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>
2 parents 5829614 + 0feb396 commit f3ad491

File tree

1 file changed

+23
-38
lines changed

1 file changed

+23
-38
lines changed

net/core/rtnetlink.c

Lines changed: 23 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5961,19 +5961,17 @@ static int rtnl_stats_get(struct sk_buff *skb, struct nlmsghdr *nlh,
59615961
static int rtnl_stats_dump(struct sk_buff *skb, struct netlink_callback *cb)
59625962
{
59635963
struct netlink_ext_ack *extack = cb->extack;
5964-
int h, s_h, err, s_idx, s_idxattr, s_prividx;
59655964
struct rtnl_stats_dump_filters filters;
59665965
struct net *net = sock_net(skb->sk);
59675966
unsigned int flags = NLM_F_MULTI;
59685967
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;
59705973
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;
59775975

59785976
cb->seq = net->dev_base_seq;
59795977

@@ -5992,39 +5990,26 @@ static int rtnl_stats_dump(struct sk_buff *skb, struct netlink_callback *cb)
59925990
if (err)
59935991
return err;
59945992

5995-
for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
5996-
idx = 0;
5997-
head = &net->dev_index_head[h];
5998-
hlist_for_each_entry(dev, head, index_hlist) {
5999-
if (idx < s_idx)
6000-
goto cont;
6001-
err = rtnl_fill_statsinfo(skb, dev, RTM_NEWSTATS,
6002-
NETLINK_CB(cb->skb).portid,
6003-
cb->nlh->nlmsg_seq, 0,
6004-
flags, &filters,
6005-
&s_idxattr, &s_prividx,
6006-
extack);
6007-
/* If we ran out of room on the first message,
6008-
* we're in trouble
6009-
*/
6010-
WARN_ON((err == -EMSGSIZE) && (skb->len == 0));
5993+
for_each_netdev_dump(net, dev, ctx->ifindex) {
5994+
err = rtnl_fill_statsinfo(skb, dev, RTM_NEWSTATS,
5995+
NETLINK_CB(cb->skb).portid,
5996+
cb->nlh->nlmsg_seq, 0,
5997+
flags, &filters,
5998+
&ctx->idxattr, &ctx->prividx,
5999+
extack);
6000+
/* If we ran out of room on the first message,
6001+
* we're in trouble.
6002+
*/
6003+
WARN_ON((err == -EMSGSIZE) && (skb->len == 0));
60116004

6012-
if (err < 0)
6013-
goto out;
6014-
s_prividx = 0;
6015-
s_idxattr = 0;
6016-
nl_dump_check_consistent(cb, nlmsg_hdr(skb));
6017-
cont:
6018-
idx++;
6019-
}
6005+
if (err < 0)
6006+
break;
6007+
ctx->prividx = 0;
6008+
ctx->idxattr = 0;
6009+
nl_dump_check_consistent(cb, nlmsg_hdr(skb));
60206010
}
6021-
out:
6022-
cb->args[3] = s_prividx;
6023-
cb->args[2] = s_idxattr;
6024-
cb->args[1] = idx;
6025-
cb->args[0] = h;
60266011

6027-
return skb->len;
6012+
return err;
60286013
}
60296014

60306015
void rtnl_offload_xstats_notify(struct net_device *dev)

0 commit comments

Comments
 (0)