batman-adv: Merge bugfixes from 2019.5
[feed/routing.git] / batman-adv / patches / 0072-batman-adv-Introduce-own-OGM2-buffer-mutex.patch
diff --git a/batman-adv/patches/0072-batman-adv-Introduce-own-OGM2-buffer-mutex.patch b/batman-adv/patches/0072-batman-adv-Introduce-own-OGM2-buffer-mutex.patch
new file mode 100644 (file)
index 0000000..ad2a930
--- /dev/null
@@ -0,0 +1,137 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sun, 13 Oct 2019 21:03:06 +0200
+Subject: batman-adv: Introduce own OGM2 buffer mutex
+
+Only a single function is currently automatically locked by the rtnl_lock
+because (unlike B.A.T.M.A.N. IV) the OGM2 buffer is independent of the hard
+interfaces on which it will be transmitted. A private mutex can be used
+instead to avoid unnecessary delays which would have been introduced by the
+global lock.
+
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/8069c581f9097f1f9398f2d49047a1dab8093821
+
+diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
+index f5feaa8c4fd228228fea519771e2c9e123b10345..a9240a0bedad109aba58e30038fe91a421ab4126 100644
+--- a/net/batman-adv/bat_v_ogm.c
++++ b/net/batman-adv/bat_v_ogm.c
+@@ -28,11 +28,12 @@
+ #include <linux/kernel.h>
+ #include <linux/kref.h>
+ #include <linux/list.h>
++#include <linux/lockdep.h>
++#include <linux/mutex.h>
+ #include <linux/netdevice.h>
+ #include <linux/random.h>
+ #include <linux/rculist.h>
+ #include <linux/rcupdate.h>
+-#include <linux/rtnetlink.h>
+ #include <linux/skbuff.h>
+ #include <linux/slab.h>
+ #include <linux/stddef.h>
+@@ -141,7 +142,7 @@ static void batadv_v_ogm_send_softif(struct batadv_priv *bat_priv)
+       u16 tvlv_len = 0;
+       int ret;
+-      ASSERT_RTNL();
++      lockdep_assert_held(&bat_priv->bat_v.ogm_buff_mutex);
+       if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
+               goto out;
+@@ -242,11 +243,12 @@ static void batadv_v_ogm_send(struct work_struct *work)
+       struct batadv_priv_bat_v *bat_v;
+       struct batadv_priv *bat_priv;
+-      rtnl_lock();
+       bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work);
+       bat_priv = container_of(bat_v, struct batadv_priv, bat_v);
++
++      mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
+       batadv_v_ogm_send_softif(bat_priv);
+-      rtnl_unlock();
++      mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
+ }
+ /**
+@@ -275,13 +277,15 @@ void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface)
+       struct batadv_priv *bat_priv = netdev_priv(primary_iface->soft_iface);
+       struct batadv_ogm2_packet *ogm_packet;
+-      ASSERT_RTNL();
+-
++      mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
+       if (!bat_priv->bat_v.ogm_buff)
+-              return;
++              goto unlock;
+       ogm_packet = (struct batadv_ogm2_packet *)bat_priv->bat_v.ogm_buff;
+       ether_addr_copy(ogm_packet->orig, primary_iface->net_dev->dev_addr);
++
++unlock:
++      mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
+ }
+ /**
+@@ -886,8 +890,6 @@ int batadv_v_ogm_init(struct batadv_priv *bat_priv)
+       unsigned char *ogm_buff;
+       u32 random_seqno;
+-      ASSERT_RTNL();
+-
+       bat_priv->bat_v.ogm_buff_len = BATADV_OGM2_HLEN;
+       ogm_buff = kzalloc(bat_priv->bat_v.ogm_buff_len, GFP_ATOMIC);
+       if (!ogm_buff)
+@@ -906,6 +908,8 @@ int batadv_v_ogm_init(struct batadv_priv *bat_priv)
+       atomic_set(&bat_priv->bat_v.ogm_seqno, random_seqno);
+       INIT_DELAYED_WORK(&bat_priv->bat_v.ogm_wq, batadv_v_ogm_send);
++      mutex_init(&bat_priv->bat_v.ogm_buff_mutex);
++
+       return 0;
+ }
+@@ -917,7 +921,11 @@ void batadv_v_ogm_free(struct batadv_priv *bat_priv)
+ {
+       cancel_delayed_work_sync(&bat_priv->bat_v.ogm_wq);
++      mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
++
+       kfree(bat_priv->bat_v.ogm_buff);
+       bat_priv->bat_v.ogm_buff = NULL;
+       bat_priv->bat_v.ogm_buff_len = 0;
++
++      mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
+ }
+diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
+index 2489d5e403c1bcbcc9008f51303f7b1ea4753ea2..3d9704ce31b4a162c01a74021ef18d53d992d506 100644
+--- a/net/batman-adv/types.h
++++ b/net/batman-adv/types.h
+@@ -27,6 +27,7 @@
+ #include <linux/compiler.h>
+ #include <linux/if_ether.h>
+ #include <linux/kref.h>
++#include <linux/mutex.h>
+ #include <linux/netdevice.h>
+ #include <linux/netlink.h>
+ #include <linux/sched.h> /* for linux/wait.h */
+@@ -990,15 +991,17 @@ struct batadv_softif_vlan {
+ /**
+  * struct batadv_priv_bat_v - B.A.T.M.A.N. V per soft-interface private data
+- * @ogm_buff: buffer holding the OGM packet. rtnl protected
+- * @ogm_buff_len: length of the OGM packet buffer. rtnl protected
++ * @ogm_buff: buffer holding the OGM packet
++ * @ogm_buff_len: length of the OGM packet buffer
+  * @ogm_seqno: OGM sequence number - used to identify each OGM
++ * @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len
+  * @ogm_wq: workqueue used to schedule OGM transmissions
+  */
+ struct batadv_priv_bat_v {
+       unsigned char *ogm_buff;
+       int ogm_buff_len;
+       atomic_t ogm_seqno;
++      struct mutex ogm_buff_mutex;
+       struct delayed_work ogm_wq;
+ };