net-sysfs: convert netdev_show() to RCU
Make clear dev_isalive() can be called with RCU protection. Then convert netdev_show() to RCU, to remove dev_base_lock dependency. Also add RCU to broadcast_show(). Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
4d42b37def
commit
12692e3df2
@@ -34,10 +34,10 @@ static const char fmt_dec[] = "%d\n";
|
|||||||
static const char fmt_ulong[] = "%lu\n";
|
static const char fmt_ulong[] = "%lu\n";
|
||||||
static const char fmt_u64[] = "%llu\n";
|
static const char fmt_u64[] = "%llu\n";
|
||||||
|
|
||||||
/* Caller holds RTNL or dev_base_lock */
|
/* Caller holds RTNL, RCU or dev_base_lock */
|
||||||
static inline int dev_isalive(const struct net_device *dev)
|
static inline int dev_isalive(const struct net_device *dev)
|
||||||
{
|
{
|
||||||
return dev->reg_state <= NETREG_REGISTERED;
|
return READ_ONCE(dev->reg_state) <= NETREG_REGISTERED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* use same locking rules as GIF* ioctl's */
|
/* use same locking rules as GIF* ioctl's */
|
||||||
@@ -48,10 +48,10 @@ static ssize_t netdev_show(const struct device *dev,
|
|||||||
struct net_device *ndev = to_net_dev(dev);
|
struct net_device *ndev = to_net_dev(dev);
|
||||||
ssize_t ret = -EINVAL;
|
ssize_t ret = -EINVAL;
|
||||||
|
|
||||||
read_lock(&dev_base_lock);
|
rcu_read_lock();
|
||||||
if (dev_isalive(ndev))
|
if (dev_isalive(ndev))
|
||||||
ret = (*format)(ndev, buf);
|
ret = (*format)(ndev, buf);
|
||||||
read_unlock(&dev_base_lock);
|
rcu_read_unlock();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,7 @@ static ssize_t netdev_show(const struct device *dev,
|
|||||||
#define NETDEVICE_SHOW(field, format_string) \
|
#define NETDEVICE_SHOW(field, format_string) \
|
||||||
static ssize_t format_##field(const struct net_device *dev, char *buf) \
|
static ssize_t format_##field(const struct net_device *dev, char *buf) \
|
||||||
{ \
|
{ \
|
||||||
return sysfs_emit(buf, format_string, dev->field); \
|
return sysfs_emit(buf, format_string, READ_ONCE(dev->field)); \
|
||||||
} \
|
} \
|
||||||
static ssize_t field##_show(struct device *dev, \
|
static ssize_t field##_show(struct device *dev, \
|
||||||
struct device_attribute *attr, char *buf) \
|
struct device_attribute *attr, char *buf) \
|
||||||
@@ -161,10 +161,13 @@ static ssize_t broadcast_show(struct device *dev,
|
|||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct net_device *ndev = to_net_dev(dev);
|
struct net_device *ndev = to_net_dev(dev);
|
||||||
|
int ret = -EINVAL;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
if (dev_isalive(ndev))
|
if (dev_isalive(ndev))
|
||||||
return sysfs_format_mac(buf, ndev->broadcast, ndev->addr_len);
|
ret = sysfs_format_mac(buf, ndev->broadcast, ndev->addr_len);
|
||||||
return -EINVAL;
|
rcu_read_unlock();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
static DEVICE_ATTR_RO(broadcast);
|
static DEVICE_ATTR_RO(broadcast);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user