vlan: use xarray iterator to implement /proc/net/vlan/config
Adopt net->dev_by_index as I did in commit 0e0939c0ad
("net-procfs: use xarray iterator to implement /proc/net/dev")
Not only this removes quadratic behavior, it also makes sure
an existing vlan device is always visible in the dump,
regardless of concurrent net->dev_base_head changes.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://lore.kernel.org/r/20240211214404.1882191-2-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
bed90b06b6
commit
f383ced24d
|
@ -163,48 +163,34 @@ void vlan_proc_rem_dev(struct net_device *vlandev)
|
|||
* The following few functions build the content of /proc/net/vlan/config
|
||||
*/
|
||||
|
||||
/* start read of /proc/net/vlan/config */
|
||||
static void *vlan_seq_from_index(struct seq_file *seq, loff_t *pos)
|
||||
{
|
||||
unsigned long ifindex = *pos;
|
||||
struct net_device *dev;
|
||||
|
||||
for_each_netdev_dump(seq_file_net(seq), dev, ifindex) {
|
||||
if (!is_vlan_dev(dev))
|
||||
continue;
|
||||
*pos = dev->ifindex;
|
||||
return dev;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *vlan_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
__acquires(rcu)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct net *net = seq_file_net(seq);
|
||||
loff_t i = 1;
|
||||
|
||||
rcu_read_lock();
|
||||
if (*pos == 0)
|
||||
return SEQ_START_TOKEN;
|
||||
|
||||
for_each_netdev_rcu(net, dev) {
|
||||
if (!is_vlan_dev(dev))
|
||||
continue;
|
||||
|
||||
if (i++ == *pos)
|
||||
return dev;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return vlan_seq_from_index(seq, pos);
|
||||
}
|
||||
|
||||
static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct net *net = seq_file_net(seq);
|
||||
|
||||
++*pos;
|
||||
|
||||
dev = v;
|
||||
if (v == SEQ_START_TOKEN)
|
||||
dev = net_device_entry(&net->dev_base_head);
|
||||
|
||||
for_each_netdev_continue_rcu(net, dev) {
|
||||
if (!is_vlan_dev(dev))
|
||||
continue;
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return vlan_seq_from_index(seq, pos);
|
||||
}
|
||||
|
||||
static void vlan_seq_stop(struct seq_file *seq, void *v)
|
||||
|
|
Loading…
Reference in New Issue