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

Reply via email to