Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: allow netdev_all_upper_get_next_dev_rcu with rtnl lock held

It is useful to be able to walk all upper devices when bringing
a device online where the RTNL lock is held. In this case it
is safe to walk the all_adj_list because the RTNL lock is used
to protect the write side as well.

This patch adds a check to see if the rtnl lock is held before
throwing a warning in netdev_all_upper_get_next_dev_rcu().

Also because we now have a call site for lockdep_rtnl_is_held()
outside COFIG_LOCK_PROVING an inline definition returning 1 is
needed. Similar to the rcu_read_lock_is_held().

Fixes: 2a47fa45d4df ("ixgbe: enable l2 forwarding acceleration for macvlans")
CC: Veaceslav Falico <vfalico@redhat.com>
Reported-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

authored by

John Fastabend and committed by
Jeff Kirsher
85328240 78106927

+6 -1
+5
include/linux/rtnetlink.h
··· 24 24 extern int rtnl_is_locked(void); 25 25 #ifdef CONFIG_PROVE_LOCKING 26 26 extern int lockdep_rtnl_is_held(void); 27 + #else 28 + static inline int lockdep_rtnl_is_held(void) 29 + { 30 + return 1; 31 + } 27 32 #endif /* #ifdef CONFIG_PROVE_LOCKING */ 28 33 29 34 /**
+1 -1
net/core/dev.c
··· 4500 4500 { 4501 4501 struct netdev_adjacent *upper; 4502 4502 4503 - WARN_ON_ONCE(!rcu_read_lock_held()); 4503 + WARN_ON_ONCE(!rcu_read_lock_held() && !lockdep_rtnl_is_held()); 4504 4504 4505 4505 upper = list_entry_rcu((*iter)->next, struct netdev_adjacent, list); 4506 4506