Skip to content

Commit 0e0939c

Browse files
edumazetkuba-moo
authored andcommitted
net-procfs: use xarray iterator to implement /proc/net/dev
In commit 759ab1e ("net: store netdevs in an xarray") Jakub added net->dev_by_index to map ifindex to netdevices. We can get rid of the old hash table (net->dev_index_head), one patch at a time, if performance is acceptable. This patch removes unpleasant code to something more readable. As a bonus, /proc/net/dev gets netdevices sorted by their ifindex. Signed-off-by: Eric Dumazet <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 6fb5dfe commit 0e0939c

File tree

1 file changed

+7
-41
lines changed

1 file changed

+7
-41
lines changed

net/core/net-procfs.c

Lines changed: 7 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -6,66 +6,32 @@
66

77
#include "dev.h"
88

9-
#define BUCKET_SPACE (32 - NETDEV_HASHBITS - 1)
10-
11-
#define get_bucket(x) ((x) >> BUCKET_SPACE)
12-
#define get_offset(x) ((x) & ((1 << BUCKET_SPACE) - 1))
13-
#define set_bucket_offset(b, o) ((b) << BUCKET_SPACE | (o))
14-
15-
static inline struct net_device *dev_from_same_bucket(struct seq_file *seq, loff_t *pos)
9+
static void *dev_seq_from_index(struct seq_file *seq, loff_t *pos)
1610
{
17-
struct net *net = seq_file_net(seq);
11+
unsigned long ifindex = *pos;
1812
struct net_device *dev;
19-
struct hlist_head *h;
20-
unsigned int count = 0, offset = get_offset(*pos);
2113

22-
h = &net->dev_index_head[get_bucket(*pos)];
23-
hlist_for_each_entry_rcu(dev, h, index_hlist) {
24-
if (++count == offset)
25-
return dev;
14+
for_each_netdev_dump(seq_file_net(seq), dev, ifindex) {
15+
*pos = dev->ifindex;
16+
return dev;
2617
}
27-
28-
return NULL;
29-
}
30-
31-
static inline struct net_device *dev_from_bucket(struct seq_file *seq, loff_t *pos)
32-
{
33-
struct net_device *dev;
34-
unsigned int bucket;
35-
36-
do {
37-
dev = dev_from_same_bucket(seq, pos);
38-
if (dev)
39-
return dev;
40-
41-
bucket = get_bucket(*pos) + 1;
42-
*pos = set_bucket_offset(bucket, 1);
43-
} while (bucket < NETDEV_HASHENTRIES);
44-
4518
return NULL;
4619
}
4720

48-
/*
49-
* This is invoked by the /proc filesystem handler to display a device
50-
* in detail.
51-
*/
5221
static void *dev_seq_start(struct seq_file *seq, loff_t *pos)
5322
__acquires(RCU)
5423
{
5524
rcu_read_lock();
5625
if (!*pos)
5726
return SEQ_START_TOKEN;
5827

59-
if (get_bucket(*pos) >= NETDEV_HASHENTRIES)
60-
return NULL;
61-
62-
return dev_from_bucket(seq, pos);
28+
return dev_seq_from_index(seq, pos);
6329
}
6430

6531
static void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
6632
{
6733
++*pos;
68-
return dev_from_bucket(seq, pos);
34+
return dev_seq_from_index(seq, pos);
6935
}
7036

7137
static void dev_seq_stop(struct seq_file *seq, void *v)

0 commit comments

Comments
 (0)