The following commit has been merged in the master branch:
commit 754a3d081aa205e86af5f889c947157060340185
Merge: e35626f610f3d2b7953ccddf6a77453da22b3a9e
cfc83a3c71517b59c1047db57da31e26a9dc2f33
Author: Jakub Kicinski <[email protected]>
Date: Thu Feb 26 19:15:08 2026 -0800
Merge tag 'batadv-net-pullrequest-20260225' of
https://git.open-mesh.org/linux-merge
Simon Wunderlich says:
====================
Here is a batman-adv bugfix:
- Avoid double-rtnl_lock ELP metric worker, by Sven Eckelmann
* tag 'batadv-net-pullrequest-20260225' of
https://git.open-mesh.org/linux-merge:
batman-adv: Avoid double-rtnl_lock ELP metric worker
====================
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
diff --combined net/batman-adv/bat_v_elp.c
index 2ce4e5bf92922,fe832093d421f..fdc2abe96d777
--- a/net/batman-adv/bat_v_elp.c
+++ b/net/batman-adv/bat_v_elp.c
@@@ -111,7 -111,15 +111,15 @@@ static bool batadv_v_elp_get_throughput
/* unsupported WiFi driver version */
goto default_throughput;
- real_netdev = batadv_get_real_netdev(hard_iface->net_dev);
+ /* only use rtnl_trylock because the elp worker will be
cancelled while
+ * the rntl_lock is held. the cancel_delayed_work_sync() would
otherwise
+ * wait forever when the elp work_item was started and it is
then also
+ * trying to rtnl_lock
+ */
+ if (!rtnl_trylock())
+ return false;
+ real_netdev = __batadv_get_real_netdev(hard_iface->net_dev);
+ rtnl_unlock();
if (!real_netdev)
goto default_throughput;
@@@ -355,7 -363,7 +363,7 @@@ static void batadv_v_elp_periodic_work(
* context. Therefore add it to metric_queue and process it
* outside rcu protected context.
*/
- metric_entry = kzalloc(sizeof(*metric_entry), GFP_ATOMIC);
+ metric_entry = kzalloc_obj(*metric_entry, GFP_ATOMIC);
if (!metric_entry) {
batadv_hardif_neigh_put(hardif_neigh);
continue;
diff --combined net/batman-adv/hard-interface.c
index 7b7640f3ffe24,1c488049d5546..d6732c34aeafc
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@@ -204,7 -204,7 +204,7 @@@ static bool batadv_is_valid_iface(cons
}
/**
- * batadv_get_real_netdevice() - check if the given netdev struct is a virtual
+ * __batadv_get_real_netdev() - check if the given netdev struct is a virtual
* interface on top of another 'real' interface
* @netdev: the device to check
*
@@@ -214,7 -214,7 +214,7 @@@
* Return: the 'real' net device or the original net device and NULL in case
* of an error.
*/
- static struct net_device *batadv_get_real_netdevice(struct net_device *netdev)
+ struct net_device *__batadv_get_real_netdev(struct net_device *netdev)
{
struct batadv_hard_iface *hard_iface = NULL;
struct net_device *real_netdev = NULL;
@@@ -267,7 -267,7 +267,7 @@@ struct net_device *batadv_get_real_netd
struct net_device *real_netdev;
rtnl_lock();
- real_netdev = batadv_get_real_netdevice(net_device);
+ real_netdev = __batadv_get_real_netdev(net_device);
rtnl_unlock();
return real_netdev;
@@@ -336,7 -336,7 +336,7 @@@ static u32 batadv_wifi_flags_evaluate(s
if (batadv_is_cfg80211_netdev(net_device))
wifi_flags |= BATADV_HARDIF_WIFI_CFG80211_DIRECT;
- real_netdev = batadv_get_real_netdevice(net_device);
+ real_netdev = __batadv_get_real_netdev(net_device);
if (!real_netdev)
return wifi_flags;
@@@ -871,7 -871,7 +871,7 @@@ batadv_hardif_add_interface(struct net_
if (!batadv_is_valid_iface(net_dev))
return NULL;
- hard_iface = kzalloc(sizeof(*hard_iface), GFP_ATOMIC);
+ hard_iface = kzalloc_obj(*hard_iface, GFP_ATOMIC);
if (!hard_iface)
return NULL;
--
LinuxNextTracking