mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-27 04:47:05 +00:00
net: add netdev_set_operstate() helper
dev_base_lock is going away, add netdev_set_operstate() helper so that hsr does not have to know core internals. Remove dev_base_lock acquisition from rfc2863_policy() v3: use an "unsigned int" for dev->operstate, so that try_cmpxchg() can work on all arches. ( https://lore.kernel.org/oe-kbuild-all/202402081918.OLyGaea3-lkp@intel.com/ ) Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
328771deab
commit
6a2968ee1e
5 changed files with 26 additions and 31 deletions
|
@ -2258,7 +2258,7 @@ struct net_device {
|
||||||
const struct tlsdev_ops *tlsdev_ops;
|
const struct tlsdev_ops *tlsdev_ops;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned char operstate;
|
unsigned int operstate;
|
||||||
unsigned char link_mode;
|
unsigned char link_mode;
|
||||||
|
|
||||||
unsigned char if_port;
|
unsigned char if_port;
|
||||||
|
|
|
@ -172,4 +172,6 @@ rtnl_notify_needed(const struct net *net, u16 nlflags, u32 group)
|
||||||
return (nlflags & NLM_F_ECHO) || rtnl_has_listeners(net, group);
|
return (nlflags & NLM_F_ECHO) || rtnl_has_listeners(net, group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void netdev_set_operstate(struct net_device *dev, int newstate);
|
||||||
|
|
||||||
#endif /* __LINUX_RTNETLINK_H */
|
#endif /* __LINUX_RTNETLINK_H */
|
||||||
|
|
|
@ -33,7 +33,7 @@ static DECLARE_DELAYED_WORK(linkwatch_work, linkwatch_event);
|
||||||
static LIST_HEAD(lweventlist);
|
static LIST_HEAD(lweventlist);
|
||||||
static DEFINE_SPINLOCK(lweventlist_lock);
|
static DEFINE_SPINLOCK(lweventlist_lock);
|
||||||
|
|
||||||
static unsigned char default_operstate(const struct net_device *dev)
|
static unsigned int default_operstate(const struct net_device *dev)
|
||||||
{
|
{
|
||||||
if (netif_testing(dev))
|
if (netif_testing(dev))
|
||||||
return IF_OPER_TESTING;
|
return IF_OPER_TESTING;
|
||||||
|
@ -62,16 +62,13 @@ static unsigned char default_operstate(const struct net_device *dev)
|
||||||
return IF_OPER_UP;
|
return IF_OPER_UP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void rfc2863_policy(struct net_device *dev)
|
static void rfc2863_policy(struct net_device *dev)
|
||||||
{
|
{
|
||||||
unsigned char operstate = default_operstate(dev);
|
unsigned int operstate = default_operstate(dev);
|
||||||
|
|
||||||
if (operstate == READ_ONCE(dev->operstate))
|
if (operstate == READ_ONCE(dev->operstate))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
write_lock(&dev_base_lock);
|
|
||||||
|
|
||||||
switch(dev->link_mode) {
|
switch(dev->link_mode) {
|
||||||
case IF_LINK_MODE_TESTING:
|
case IF_LINK_MODE_TESTING:
|
||||||
if (operstate == IF_OPER_UP)
|
if (operstate == IF_OPER_UP)
|
||||||
|
@ -88,8 +85,6 @@ static void rfc2863_policy(struct net_device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE_ONCE(dev->operstate, operstate);
|
WRITE_ONCE(dev->operstate, operstate);
|
||||||
|
|
||||||
write_unlock(&dev_base_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -842,9 +842,22 @@ int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst, u32 id,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rtnl_put_cacheinfo);
|
EXPORT_SYMBOL_GPL(rtnl_put_cacheinfo);
|
||||||
|
|
||||||
|
void netdev_set_operstate(struct net_device *dev, int newstate)
|
||||||
|
{
|
||||||
|
unsigned int old = READ_ONCE(dev->operstate);
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (old == newstate)
|
||||||
|
return;
|
||||||
|
} while (!try_cmpxchg(&dev->operstate, &old, newstate));
|
||||||
|
|
||||||
|
netdev_state_change(dev);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(netdev_set_operstate);
|
||||||
|
|
||||||
static void set_operstate(struct net_device *dev, unsigned char transition)
|
static void set_operstate(struct net_device *dev, unsigned char transition)
|
||||||
{
|
{
|
||||||
unsigned char operstate = dev->operstate;
|
unsigned char operstate = READ_ONCE(dev->operstate);
|
||||||
|
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
case IF_OPER_UP:
|
case IF_OPER_UP:
|
||||||
|
@ -866,12 +879,7 @@ static void set_operstate(struct net_device *dev, unsigned char transition)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (READ_ONCE(dev->operstate) != operstate) {
|
netdev_set_operstate(dev, operstate);
|
||||||
write_lock(&dev_base_lock);
|
|
||||||
WRITE_ONCE(dev->operstate, operstate);
|
|
||||||
write_unlock(&dev_base_lock);
|
|
||||||
netdev_state_change(dev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int rtnl_dev_get_flags(const struct net_device *dev)
|
static unsigned int rtnl_dev_get_flags(const struct net_device *dev)
|
||||||
|
|
|
@ -28,29 +28,19 @@ static bool is_slave_up(struct net_device *dev)
|
||||||
return dev && is_admin_up(dev) && netif_oper_up(dev);
|
return dev && is_admin_up(dev) && netif_oper_up(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __hsr_set_operstate(struct net_device *dev, int transition)
|
|
||||||
{
|
|
||||||
write_lock(&dev_base_lock);
|
|
||||||
if (READ_ONCE(dev->operstate) != transition) {
|
|
||||||
WRITE_ONCE(dev->operstate, transition);
|
|
||||||
write_unlock(&dev_base_lock);
|
|
||||||
netdev_state_change(dev);
|
|
||||||
} else {
|
|
||||||
write_unlock(&dev_base_lock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hsr_set_operstate(struct hsr_port *master, bool has_carrier)
|
static void hsr_set_operstate(struct hsr_port *master, bool has_carrier)
|
||||||
{
|
{
|
||||||
if (!is_admin_up(master->dev)) {
|
struct net_device *dev = master->dev;
|
||||||
__hsr_set_operstate(master->dev, IF_OPER_DOWN);
|
|
||||||
|
if (!is_admin_up(dev)) {
|
||||||
|
netdev_set_operstate(dev, IF_OPER_DOWN);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_carrier)
|
if (has_carrier)
|
||||||
__hsr_set_operstate(master->dev, IF_OPER_UP);
|
netdev_set_operstate(dev, IF_OPER_UP);
|
||||||
else
|
else
|
||||||
__hsr_set_operstate(master->dev, IF_OPER_LOWERLAYERDOWN);
|
netdev_set_operstate(dev, IF_OPER_LOWERLAYERDOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hsr_check_carrier(struct hsr_port *master)
|
static bool hsr_check_carrier(struct hsr_port *master)
|
||||||
|
|
Loading…
Reference in a new issue