Merge pull request #624 from ecsv/batadv-for-18.06
[feed/routing.git] / batman-adv / patches / 0038-batman-adv-Introduce-own-OGM2-buffer-mutex.patch
1 From: Sven Eckelmann <sven@narfation.org>
2 Date: Sun, 13 Oct 2019 21:03:06 +0200
3 Subject: batman-adv: Introduce own OGM2 buffer mutex
4
5 Only a single function is currently automatically locked by the rtnl_lock
6 because (unlike B.A.T.M.A.N. IV) the OGM2 buffer is independent of the hard
7 interfaces on which it will be transmitted. A private mutex can be used
8 instead to avoid unnecessary delays which would have been introduced by the
9 global lock.
10
11 Signed-off-by: Sven Eckelmann <sven@narfation.org>
12
13 Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/8069c581f9097f1f9398f2d49047a1dab8093821
14
15 diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
16 index a9f949501ff3c354d38e3ad333901310391f27d8..bf9ea404abe7cbe1dd2113881856cd35b718b7d1 100644
17 --- a/net/batman-adv/bat_v_ogm.c
18 +++ b/net/batman-adv/bat_v_ogm.c
19 @@ -29,11 +29,12 @@
20 #include <linux/kernel.h>
21 #include <linux/kref.h>
22 #include <linux/list.h>
23 +#include <linux/lockdep.h>
24 +#include <linux/mutex.h>
25 #include <linux/netdevice.h>
26 #include <linux/random.h>
27 #include <linux/rculist.h>
28 #include <linux/rcupdate.h>
29 -#include <linux/rtnetlink.h>
30 #include <linux/skbuff.h>
31 #include <linux/slab.h>
32 #include <linux/stddef.h>
33 @@ -142,7 +143,7 @@ static void batadv_v_ogm_send_softif(struct batadv_priv *bat_priv)
34 u16 tvlv_len = 0;
35 int ret;
36
37 - ASSERT_RTNL();
38 + lockdep_assert_held(&bat_priv->bat_v.ogm_buff_mutex);
39
40 if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
41 goto out;
42 @@ -242,11 +243,12 @@ static void batadv_v_ogm_send(struct work_struct *work)
43 struct batadv_priv_bat_v *bat_v;
44 struct batadv_priv *bat_priv;
45
46 - rtnl_lock();
47 bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work);
48 bat_priv = container_of(bat_v, struct batadv_priv, bat_v);
49 +
50 + mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
51 batadv_v_ogm_send_softif(bat_priv);
52 - rtnl_unlock();
53 + mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
54 }
55
56 /**
57 @@ -275,13 +277,15 @@ void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface)
58 struct batadv_priv *bat_priv = netdev_priv(primary_iface->soft_iface);
59 struct batadv_ogm2_packet *ogm_packet;
60
61 - ASSERT_RTNL();
62 -
63 + mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
64 if (!bat_priv->bat_v.ogm_buff)
65 - return;
66 + goto unlock;
67
68 ogm_packet = (struct batadv_ogm2_packet *)bat_priv->bat_v.ogm_buff;
69 ether_addr_copy(ogm_packet->orig, primary_iface->net_dev->dev_addr);
70 +
71 +unlock:
72 + mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
73 }
74
75 /**
76 @@ -885,8 +889,6 @@ int batadv_v_ogm_init(struct batadv_priv *bat_priv)
77 unsigned char *ogm_buff;
78 u32 random_seqno;
79
80 - ASSERT_RTNL();
81 -
82 bat_priv->bat_v.ogm_buff_len = BATADV_OGM2_HLEN;
83 ogm_buff = kzalloc(bat_priv->bat_v.ogm_buff_len, GFP_ATOMIC);
84 if (!ogm_buff)
85 @@ -905,6 +907,8 @@ int batadv_v_ogm_init(struct batadv_priv *bat_priv)
86 atomic_set(&bat_priv->bat_v.ogm_seqno, random_seqno);
87 INIT_DELAYED_WORK(&bat_priv->bat_v.ogm_wq, batadv_v_ogm_send);
88
89 + mutex_init(&bat_priv->bat_v.ogm_buff_mutex);
90 +
91 return 0;
92 }
93
94 @@ -916,7 +920,11 @@ void batadv_v_ogm_free(struct batadv_priv *bat_priv)
95 {
96 cancel_delayed_work_sync(&bat_priv->bat_v.ogm_wq);
97
98 + mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
99 +
100 kfree(bat_priv->bat_v.ogm_buff);
101 bat_priv->bat_v.ogm_buff = NULL;
102 bat_priv->bat_v.ogm_buff_len = 0;
103 +
104 + mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
105 }
106 diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
107 index 49e4e6cb506f192e85e96e8b3e68be3fdc2dca57..44c423447fe163eb3b9df5ec5cf229bed6b8d65b 100644
108 --- a/net/batman-adv/types.h
109 +++ b/net/batman-adv/types.h
110 @@ -28,6 +28,7 @@
111 #include <linux/compiler.h>
112 #include <linux/if_ether.h>
113 #include <linux/kref.h>
114 +#include <linux/mutex.h>
115 #include <linux/netdevice.h>
116 #include <linux/netlink.h>
117 #include <linux/sched.h> /* for linux/wait.h */
118 @@ -1479,15 +1480,18 @@ struct batadv_softif_vlan {
119 * struct batadv_priv_bat_v - B.A.T.M.A.N. V per soft-interface private data
120 */
121 struct batadv_priv_bat_v {
122 - /** @ogm_buff: buffer holding the OGM packet. rtnl protected */
123 + /** @ogm_buff: buffer holding the OGM packet */
124 unsigned char *ogm_buff;
125
126 - /** @ogm_buff_len: length of the OGM packet buffer. rtnl protected */
127 + /** @ogm_buff_len: length of the OGM packet buffer */
128 int ogm_buff_len;
129
130 /** @ogm_seqno: OGM sequence number - used to identify each OGM */
131 atomic_t ogm_seqno;
132
133 + /** @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len */
134 + struct mutex ogm_buff_mutex;
135 +
136 /** @ogm_wq: workqueue used to schedule OGM transmissions */
137 struct delayed_work ogm_wq;
138 };