mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-28 20:37:27 +00:00
net: Introduce for_each_netdev_rcu() iterator
Adds RCU management to the list of netdevices. Convert some for_each_netdev() users to RCU version, if it can avoid read_lock-ing dev_base_lock Ie: read_lock(&dev_base_loack); for_each_netdev(net, dev) some_action(); read_unlock(&dev_base_lock); becomes : rcu_read_lock(); for_each_netdev_rcu(net, dev) some_action(); rcu_read_unlock(); Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d0075634cf
commit
c6d14c8456
@ -1081,6 +1081,8 @@ extern rwlock_t dev_base_lock; /* Device list lock */
|
|||||||
|
|
||||||
#define for_each_netdev(net, d) \
|
#define for_each_netdev(net, d) \
|
||||||
list_for_each_entry(d, &(net)->dev_base_head, dev_list)
|
list_for_each_entry(d, &(net)->dev_base_head, dev_list)
|
||||||
|
#define for_each_netdev_rcu(net, d) \
|
||||||
|
list_for_each_entry_rcu(d, &(net)->dev_base_head, dev_list)
|
||||||
#define for_each_netdev_safe(net, d, n) \
|
#define for_each_netdev_safe(net, d, n) \
|
||||||
list_for_each_entry_safe(d, n, &(net)->dev_base_head, dev_list)
|
list_for_each_entry_safe(d, n, &(net)->dev_base_head, dev_list)
|
||||||
#define for_each_netdev_continue(net, d) \
|
#define for_each_netdev_continue(net, d) \
|
||||||
|
@ -175,7 +175,7 @@ static struct list_head ptype_all __read_mostly; /* Taps */
|
|||||||
* The @dev_base_head list is protected by @dev_base_lock and the rtnl
|
* The @dev_base_head list is protected by @dev_base_lock and the rtnl
|
||||||
* semaphore.
|
* semaphore.
|
||||||
*
|
*
|
||||||
* Pure readers hold dev_base_lock for reading.
|
* Pure readers hold dev_base_lock for reading, or rcu_read_lock()
|
||||||
*
|
*
|
||||||
* Writers must hold the rtnl semaphore while they loop through the
|
* Writers must hold the rtnl semaphore while they loop through the
|
||||||
* dev_base_head list, and hold dev_base_lock for writing when they do the
|
* dev_base_head list, and hold dev_base_lock for writing when they do the
|
||||||
@ -212,7 +212,7 @@ static int list_netdevice(struct net_device *dev)
|
|||||||
ASSERT_RTNL();
|
ASSERT_RTNL();
|
||||||
|
|
||||||
write_lock_bh(&dev_base_lock);
|
write_lock_bh(&dev_base_lock);
|
||||||
list_add_tail(&dev->dev_list, &net->dev_base_head);
|
list_add_tail_rcu(&dev->dev_list, &net->dev_base_head);
|
||||||
hlist_add_head_rcu(&dev->name_hlist, dev_name_hash(net, dev->name));
|
hlist_add_head_rcu(&dev->name_hlist, dev_name_hash(net, dev->name));
|
||||||
hlist_add_head_rcu(&dev->index_hlist,
|
hlist_add_head_rcu(&dev->index_hlist,
|
||||||
dev_index_hash(net, dev->ifindex));
|
dev_index_hash(net, dev->ifindex));
|
||||||
@ -229,7 +229,7 @@ static void unlist_netdevice(struct net_device *dev)
|
|||||||
|
|
||||||
/* Unlink dev from the device chain */
|
/* Unlink dev from the device chain */
|
||||||
write_lock_bh(&dev_base_lock);
|
write_lock_bh(&dev_base_lock);
|
||||||
list_del(&dev->dev_list);
|
list_del_rcu(&dev->dev_list);
|
||||||
hlist_del_rcu(&dev->name_hlist);
|
hlist_del_rcu(&dev->name_hlist);
|
||||||
hlist_del_rcu(&dev->index_hlist);
|
hlist_del_rcu(&dev->index_hlist);
|
||||||
write_unlock_bh(&dev_base_lock);
|
write_unlock_bh(&dev_base_lock);
|
||||||
@ -799,15 +799,15 @@ struct net_device *dev_get_by_flags(struct net *net, unsigned short if_flags,
|
|||||||
struct net_device *dev, *ret;
|
struct net_device *dev, *ret;
|
||||||
|
|
||||||
ret = NULL;
|
ret = NULL;
|
||||||
read_lock(&dev_base_lock);
|
rcu_read_lock();
|
||||||
for_each_netdev(net, dev) {
|
for_each_netdev_rcu(net, dev) {
|
||||||
if (((dev->flags ^ if_flags) & mask) == 0) {
|
if (((dev->flags ^ if_flags) & mask) == 0) {
|
||||||
dev_hold(dev);
|
dev_hold(dev);
|
||||||
ret = dev;
|
ret = dev;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
read_unlock(&dev_base_lock);
|
rcu_read_unlock();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dev_get_by_flags);
|
EXPORT_SYMBOL(dev_get_by_flags);
|
||||||
@ -3077,18 +3077,18 @@ static int dev_ifconf(struct net *net, char __user *arg)
|
|||||||
* in detail.
|
* in detail.
|
||||||
*/
|
*/
|
||||||
void *dev_seq_start(struct seq_file *seq, loff_t *pos)
|
void *dev_seq_start(struct seq_file *seq, loff_t *pos)
|
||||||
__acquires(dev_base_lock)
|
__acquires(RCU)
|
||||||
{
|
{
|
||||||
struct net *net = seq_file_net(seq);
|
struct net *net = seq_file_net(seq);
|
||||||
loff_t off;
|
loff_t off;
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
|
|
||||||
read_lock(&dev_base_lock);
|
rcu_read_lock();
|
||||||
if (!*pos)
|
if (!*pos)
|
||||||
return SEQ_START_TOKEN;
|
return SEQ_START_TOKEN;
|
||||||
|
|
||||||
off = 1;
|
off = 1;
|
||||||
for_each_netdev(net, dev)
|
for_each_netdev_rcu(net, dev)
|
||||||
if (off++ == *pos)
|
if (off++ == *pos)
|
||||||
return dev;
|
return dev;
|
||||||
|
|
||||||
@ -3097,16 +3097,18 @@ void *dev_seq_start(struct seq_file *seq, loff_t *pos)
|
|||||||
|
|
||||||
void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||||
{
|
{
|
||||||
struct net *net = seq_file_net(seq);
|
struct net_device *dev = (v == SEQ_START_TOKEN) ?
|
||||||
|
first_net_device(seq_file_net(seq)) :
|
||||||
|
next_net_device((struct net_device *)v);
|
||||||
|
|
||||||
++*pos;
|
++*pos;
|
||||||
return v == SEQ_START_TOKEN ?
|
return rcu_dereference(dev);
|
||||||
first_net_device(net) : next_net_device((struct net_device *)v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dev_seq_stop(struct seq_file *seq, void *v)
|
void dev_seq_stop(struct seq_file *seq, void *v)
|
||||||
__releases(dev_base_lock)
|
__releases(RCU)
|
||||||
{
|
{
|
||||||
read_unlock(&dev_base_lock);
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
|
static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
|
||||||
|
@ -749,9 +749,9 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
|||||||
|
|
||||||
if (!(saddr->sdn_flags & SDF_WILD)) {
|
if (!(saddr->sdn_flags & SDF_WILD)) {
|
||||||
if (le16_to_cpu(saddr->sdn_nodeaddrl)) {
|
if (le16_to_cpu(saddr->sdn_nodeaddrl)) {
|
||||||
read_lock(&dev_base_lock);
|
rcu_read_lock();
|
||||||
ldev = NULL;
|
ldev = NULL;
|
||||||
for_each_netdev(&init_net, dev) {
|
for_each_netdev_rcu(&init_net, dev) {
|
||||||
if (!dev->dn_ptr)
|
if (!dev->dn_ptr)
|
||||||
continue;
|
continue;
|
||||||
if (dn_dev_islocal(dev, dn_saddr2dn(saddr))) {
|
if (dn_dev_islocal(dev, dn_saddr2dn(saddr))) {
|
||||||
@ -759,7 +759,7 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
read_unlock(&dev_base_lock);
|
rcu_read_unlock();
|
||||||
if (ldev == NULL)
|
if (ldev == NULL)
|
||||||
return -EADDRNOTAVAIL;
|
return -EADDRNOTAVAIL;
|
||||||
}
|
}
|
||||||
|
@ -607,8 +607,8 @@ static void dn_fib_del_ifaddr(struct dn_ifaddr *ifa)
|
|||||||
ASSERT_RTNL();
|
ASSERT_RTNL();
|
||||||
|
|
||||||
/* Scan device list */
|
/* Scan device list */
|
||||||
read_lock(&dev_base_lock);
|
rcu_read_lock();
|
||||||
for_each_netdev(&init_net, dev) {
|
for_each_netdev_rcu(&init_net, dev) {
|
||||||
dn_db = dev->dn_ptr;
|
dn_db = dev->dn_ptr;
|
||||||
if (dn_db == NULL)
|
if (dn_db == NULL)
|
||||||
continue;
|
continue;
|
||||||
@ -619,7 +619,7 @@ static void dn_fib_del_ifaddr(struct dn_ifaddr *ifa)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
read_unlock(&dev_base_lock);
|
rcu_read_unlock();
|
||||||
|
|
||||||
if (found_it == 0) {
|
if (found_it == 0) {
|
||||||
fib_magic(RTM_DELROUTE, RTN_LOCAL, ifa->ifa_local, 16, ifa);
|
fib_magic(RTM_DELROUTE, RTN_LOCAL, ifa->ifa_local, 16, ifa);
|
||||||
|
@ -908,8 +908,8 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old
|
|||||||
dev_put(dev_out);
|
dev_put(dev_out);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
read_lock(&dev_base_lock);
|
rcu_read_lock();
|
||||||
for_each_netdev(&init_net, dev) {
|
for_each_netdev_rcu(&init_net, dev) {
|
||||||
if (!dev->dn_ptr)
|
if (!dev->dn_ptr)
|
||||||
continue;
|
continue;
|
||||||
if (!dn_dev_islocal(dev, oldflp->fld_src))
|
if (!dn_dev_islocal(dev, oldflp->fld_src))
|
||||||
@ -922,7 +922,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old
|
|||||||
dev_out = dev;
|
dev_out = dev;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
read_unlock(&dev_base_lock);
|
rcu_read_unlock();
|
||||||
if (dev_out == NULL)
|
if (dev_out == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
dev_hold(dev_out);
|
dev_hold(dev_out);
|
||||||
|
@ -876,19 +876,16 @@ __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
|
|||||||
if (!addr)
|
if (!addr)
|
||||||
addr = ifa->ifa_local;
|
addr = ifa->ifa_local;
|
||||||
} endfor_ifa(in_dev);
|
} endfor_ifa(in_dev);
|
||||||
no_in_dev:
|
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
|
no_in_dev:
|
||||||
if (addr)
|
if (addr)
|
||||||
goto out;
|
goto out_unlock;
|
||||||
|
|
||||||
/* Not loopback addresses on loopback should be preferred
|
/* Not loopback addresses on loopback should be preferred
|
||||||
in this case. It is importnat that lo is the first interface
|
in this case. It is importnat that lo is the first interface
|
||||||
in dev_base list.
|
in dev_base list.
|
||||||
*/
|
*/
|
||||||
read_lock(&dev_base_lock);
|
for_each_netdev_rcu(net, dev) {
|
||||||
rcu_read_lock();
|
|
||||||
for_each_netdev(net, dev) {
|
|
||||||
if ((in_dev = __in_dev_get_rcu(dev)) == NULL)
|
if ((in_dev = __in_dev_get_rcu(dev)) == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -896,12 +893,11 @@ no_in_dev:
|
|||||||
if (ifa->ifa_scope != RT_SCOPE_LINK &&
|
if (ifa->ifa_scope != RT_SCOPE_LINK &&
|
||||||
ifa->ifa_scope <= scope) {
|
ifa->ifa_scope <= scope) {
|
||||||
addr = ifa->ifa_local;
|
addr = ifa->ifa_local;
|
||||||
goto out_unlock_both;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
} endfor_ifa(in_dev);
|
} endfor_ifa(in_dev);
|
||||||
}
|
}
|
||||||
out_unlock_both:
|
out_unlock:
|
||||||
read_unlock(&dev_base_lock);
|
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
out:
|
out:
|
||||||
return addr;
|
return addr;
|
||||||
@ -962,9 +958,8 @@ __be32 inet_confirm_addr(struct in_device *in_dev,
|
|||||||
return confirm_addr_indev(in_dev, dst, local, scope);
|
return confirm_addr_indev(in_dev, dst, local, scope);
|
||||||
|
|
||||||
net = dev_net(in_dev->dev);
|
net = dev_net(in_dev->dev);
|
||||||
read_lock(&dev_base_lock);
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
for_each_netdev(net, dev) {
|
for_each_netdev_rcu(net, dev) {
|
||||||
if ((in_dev = __in_dev_get_rcu(dev))) {
|
if ((in_dev = __in_dev_get_rcu(dev))) {
|
||||||
addr = confirm_addr_indev(in_dev, dst, local, scope);
|
addr = confirm_addr_indev(in_dev, dst, local, scope);
|
||||||
if (addr)
|
if (addr)
|
||||||
@ -972,7 +967,6 @@ __be32 inet_confirm_addr(struct in_device *in_dev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
read_unlock(&dev_base_lock);
|
|
||||||
|
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
@ -1240,18 +1234,18 @@ static void devinet_copy_dflt_conf(struct net *net, int i)
|
|||||||
{
|
{
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
|
|
||||||
read_lock(&dev_base_lock);
|
rcu_read_lock();
|
||||||
for_each_netdev(net, dev) {
|
for_each_netdev_rcu(net, dev) {
|
||||||
struct in_device *in_dev;
|
struct in_device *in_dev;
|
||||||
rcu_read_lock();
|
|
||||||
in_dev = __in_dev_get_rcu(dev);
|
in_dev = __in_dev_get_rcu(dev);
|
||||||
if (in_dev && !test_bit(i, in_dev->cnf.state))
|
if (in_dev && !test_bit(i, in_dev->cnf.state))
|
||||||
in_dev->cnf.data[i] = net->ipv4.devconf_dflt->data[i];
|
in_dev->cnf.data[i] = net->ipv4.devconf_dflt->data[i];
|
||||||
rcu_read_unlock();
|
|
||||||
}
|
}
|
||||||
read_unlock(&dev_base_lock);
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* called with RTNL locked */
|
||||||
static void inet_forward_change(struct net *net)
|
static void inet_forward_change(struct net *net)
|
||||||
{
|
{
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
@ -1260,7 +1254,6 @@ static void inet_forward_change(struct net *net)
|
|||||||
IPV4_DEVCONF_ALL(net, ACCEPT_REDIRECTS) = !on;
|
IPV4_DEVCONF_ALL(net, ACCEPT_REDIRECTS) = !on;
|
||||||
IPV4_DEVCONF_DFLT(net, FORWARDING) = on;
|
IPV4_DEVCONF_DFLT(net, FORWARDING) = on;
|
||||||
|
|
||||||
read_lock(&dev_base_lock);
|
|
||||||
for_each_netdev(net, dev) {
|
for_each_netdev(net, dev) {
|
||||||
struct in_device *in_dev;
|
struct in_device *in_dev;
|
||||||
if (on)
|
if (on)
|
||||||
@ -1271,7 +1264,6 @@ static void inet_forward_change(struct net *net)
|
|||||||
IN_DEV_CONF_SET(in_dev, FORWARDING, on);
|
IN_DEV_CONF_SET(in_dev, FORWARDING, on);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
read_unlock(&dev_base_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int devinet_conf_proc(ctl_table *ctl, int write,
|
static int devinet_conf_proc(ctl_table *ctl, int write,
|
||||||
|
@ -481,9 +481,8 @@ static void addrconf_forward_change(struct net *net, __s32 newf)
|
|||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
struct inet6_dev *idev;
|
struct inet6_dev *idev;
|
||||||
|
|
||||||
read_lock(&dev_base_lock);
|
rcu_read_lock();
|
||||||
for_each_netdev(net, dev) {
|
for_each_netdev_rcu(net, dev) {
|
||||||
rcu_read_lock();
|
|
||||||
idev = __in6_dev_get(dev);
|
idev = __in6_dev_get(dev);
|
||||||
if (idev) {
|
if (idev) {
|
||||||
int changed = (!idev->cnf.forwarding) ^ (!newf);
|
int changed = (!idev->cnf.forwarding) ^ (!newf);
|
||||||
@ -491,9 +490,8 @@ static void addrconf_forward_change(struct net *net, __s32 newf)
|
|||||||
if (changed)
|
if (changed)
|
||||||
dev_forward_change(idev);
|
dev_forward_change(idev);
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
|
||||||
}
|
}
|
||||||
read_unlock(&dev_base_lock);
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
|
static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
|
||||||
@ -1137,10 +1135,9 @@ int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
|
|||||||
hiscore->rule = -1;
|
hiscore->rule = -1;
|
||||||
hiscore->ifa = NULL;
|
hiscore->ifa = NULL;
|
||||||
|
|
||||||
read_lock(&dev_base_lock);
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
|
|
||||||
for_each_netdev(net, dev) {
|
for_each_netdev_rcu(net, dev) {
|
||||||
struct inet6_dev *idev;
|
struct inet6_dev *idev;
|
||||||
|
|
||||||
/* Candidate Source Address (section 4)
|
/* Candidate Source Address (section 4)
|
||||||
@ -1235,7 +1232,6 @@ try_nextdev:
|
|||||||
read_unlock_bh(&idev->lock);
|
read_unlock_bh(&idev->lock);
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
read_unlock(&dev_base_lock);
|
|
||||||
|
|
||||||
if (!hiscore->ifa)
|
if (!hiscore->ifa)
|
||||||
return -EADDRNOTAVAIL;
|
return -EADDRNOTAVAIL;
|
||||||
@ -4052,9 +4048,8 @@ static void addrconf_disable_change(struct net *net, __s32 newf)
|
|||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
struct inet6_dev *idev;
|
struct inet6_dev *idev;
|
||||||
|
|
||||||
read_lock(&dev_base_lock);
|
rcu_read_lock();
|
||||||
for_each_netdev(net, dev) {
|
for_each_netdev_rcu(net, dev) {
|
||||||
rcu_read_lock();
|
|
||||||
idev = __in6_dev_get(dev);
|
idev = __in6_dev_get(dev);
|
||||||
if (idev) {
|
if (idev) {
|
||||||
int changed = (!idev->cnf.disable_ipv6) ^ (!newf);
|
int changed = (!idev->cnf.disable_ipv6) ^ (!newf);
|
||||||
@ -4062,9 +4057,8 @@ static void addrconf_disable_change(struct net *net, __s32 newf)
|
|||||||
if (changed)
|
if (changed)
|
||||||
dev_disable_change(idev);
|
dev_disable_change(idev);
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
|
||||||
}
|
}
|
||||||
read_unlock(&dev_base_lock);
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old)
|
static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old)
|
||||||
|
@ -404,13 +404,13 @@ int ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
|
|||||||
|
|
||||||
if (dev)
|
if (dev)
|
||||||
return ipv6_chk_acast_dev(dev, addr);
|
return ipv6_chk_acast_dev(dev, addr);
|
||||||
read_lock(&dev_base_lock);
|
rcu_read_lock();
|
||||||
for_each_netdev(net, dev)
|
for_each_netdev_rcu(net, dev)
|
||||||
if (ipv6_chk_acast_dev(dev, addr)) {
|
if (ipv6_chk_acast_dev(dev, addr)) {
|
||||||
found = 1;
|
found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
read_unlock(&dev_base_lock);
|
rcu_read_unlock();
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -597,15 +597,15 @@ struct net_device *nr_dev_first(void)
|
|||||||
{
|
{
|
||||||
struct net_device *dev, *first = NULL;
|
struct net_device *dev, *first = NULL;
|
||||||
|
|
||||||
read_lock(&dev_base_lock);
|
rcu_read_lock();
|
||||||
for_each_netdev(&init_net, dev) {
|
for_each_netdev_rcu(&init_net, dev) {
|
||||||
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM)
|
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM)
|
||||||
if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
|
if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
|
||||||
first = dev;
|
first = dev;
|
||||||
}
|
}
|
||||||
if (first)
|
if (first)
|
||||||
dev_hold(first);
|
dev_hold(first);
|
||||||
read_unlock(&dev_base_lock);
|
rcu_read_unlock();
|
||||||
|
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
@ -617,16 +617,17 @@ struct net_device *nr_dev_get(ax25_address *addr)
|
|||||||
{
|
{
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
|
|
||||||
read_lock(&dev_base_lock);
|
rcu_read_lock();
|
||||||
for_each_netdev(&init_net, dev) {
|
for_each_netdev_rcu(&init_net, dev) {
|
||||||
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM && ax25cmp(addr, (ax25_address *)dev->dev_addr) == 0) {
|
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM &&
|
||||||
|
ax25cmp(addr, (ax25_address *)dev->dev_addr) == 0) {
|
||||||
dev_hold(dev);
|
dev_hold(dev);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dev = NULL;
|
dev = NULL;
|
||||||
out:
|
out:
|
||||||
read_unlock(&dev_base_lock);
|
rcu_read_unlock();
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,13 +600,13 @@ struct net_device *rose_dev_first(void)
|
|||||||
{
|
{
|
||||||
struct net_device *dev, *first = NULL;
|
struct net_device *dev, *first = NULL;
|
||||||
|
|
||||||
read_lock(&dev_base_lock);
|
rcu_read_lock();
|
||||||
for_each_netdev(&init_net, dev) {
|
for_each_netdev_rcu(&init_net, dev) {
|
||||||
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE)
|
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE)
|
||||||
if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
|
if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
|
||||||
first = dev;
|
first = dev;
|
||||||
}
|
}
|
||||||
read_unlock(&dev_base_lock);
|
rcu_read_unlock();
|
||||||
|
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
@ -618,8 +618,8 @@ struct net_device *rose_dev_get(rose_address *addr)
|
|||||||
{
|
{
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
|
|
||||||
read_lock(&dev_base_lock);
|
rcu_read_lock();
|
||||||
for_each_netdev(&init_net, dev) {
|
for_each_netdev_rcu(&init_net, dev) {
|
||||||
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0) {
|
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0) {
|
||||||
dev_hold(dev);
|
dev_hold(dev);
|
||||||
goto out;
|
goto out;
|
||||||
@ -627,7 +627,7 @@ struct net_device *rose_dev_get(rose_address *addr)
|
|||||||
}
|
}
|
||||||
dev = NULL;
|
dev = NULL;
|
||||||
out:
|
out:
|
||||||
read_unlock(&dev_base_lock);
|
rcu_read_unlock();
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -635,14 +635,14 @@ static int rose_dev_exists(rose_address *addr)
|
|||||||
{
|
{
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
|
|
||||||
read_lock(&dev_base_lock);
|
rcu_read_lock();
|
||||||
for_each_netdev(&init_net, dev) {
|
for_each_netdev_rcu(&init_net, dev) {
|
||||||
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0)
|
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
dev = NULL;
|
dev = NULL;
|
||||||
out:
|
out:
|
||||||
read_unlock(&dev_base_lock);
|
rcu_read_unlock();
|
||||||
return dev != NULL;
|
return dev != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,14 +205,14 @@ static void sctp_get_local_addr_list(void)
|
|||||||
struct list_head *pos;
|
struct list_head *pos;
|
||||||
struct sctp_af *af;
|
struct sctp_af *af;
|
||||||
|
|
||||||
read_lock(&dev_base_lock);
|
rcu_read_lock();
|
||||||
for_each_netdev(&init_net, dev) {
|
for_each_netdev_rcu(&init_net, dev) {
|
||||||
__list_for_each(pos, &sctp_address_families) {
|
__list_for_each(pos, &sctp_address_families) {
|
||||||
af = list_entry(pos, struct sctp_af, list);
|
af = list_entry(pos, struct sctp_af, list);
|
||||||
af->copy_addrlist(&sctp_local_addr_list, dev);
|
af->copy_addrlist(&sctp_local_addr_list, dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
read_unlock(&dev_base_lock);
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free the existing local addresses. */
|
/* Free the existing local addresses. */
|
||||||
|
Loading…
Reference in New Issue
Block a user