@@ -69,7 +69,7 @@ static const struct proto_ops macvtap_socket_ops;
69
69
* RCU usage:
70
70
* The macvtap_queue and the macvlan_dev are loosely coupled, the
71
71
* pointers from one to the other can only be read while rcu_read_lock
72
- * or macvtap_lock is held.
72
+ * or rtnl is held.
73
73
*
74
74
* Both the file and the macvlan_dev hold a reference on the macvtap_queue
75
75
* through sock_hold(&q->sk). When the macvlan_dev goes away first,
@@ -81,15 +81,14 @@ static const struct proto_ops macvtap_socket_ops;
81
81
* file or the dev. The data structure is freed through __sk_free
82
82
* when both our references and any pending SKBs are gone.
83
83
*/
84
- static DEFINE_SPINLOCK (macvtap_lock );
85
84
86
85
static int macvtap_enable_queue (struct net_device * dev , struct file * file ,
87
86
struct macvtap_queue * q )
88
87
{
89
88
struct macvlan_dev * vlan = netdev_priv (dev );
90
89
int err = - EINVAL ;
91
90
92
- spin_lock ( & macvtap_lock );
91
+ ASSERT_RTNL ( );
93
92
94
93
if (q -> enabled )
95
94
goto out ;
@@ -101,7 +100,6 @@ static int macvtap_enable_queue(struct net_device *dev, struct file *file,
101
100
102
101
vlan -> numvtaps ++ ;
103
102
out :
104
- spin_unlock (& macvtap_lock );
105
103
return err ;
106
104
}
107
105
@@ -111,7 +109,7 @@ static int macvtap_set_queue(struct net_device *dev, struct file *file,
111
109
struct macvlan_dev * vlan = netdev_priv (dev );
112
110
int err = - EBUSY ;
113
111
114
- spin_lock ( & macvtap_lock );
112
+ rtnl_lock ( );
115
113
if (vlan -> numqueues == MAX_MACVTAP_QUEUES )
116
114
goto out ;
117
115
@@ -130,26 +128,25 @@ static int macvtap_set_queue(struct net_device *dev, struct file *file,
130
128
vlan -> numqueues ++ ;
131
129
132
130
out :
133
- spin_unlock ( & macvtap_lock );
131
+ rtnl_unlock ( );
134
132
return err ;
135
133
}
136
134
137
- static int __macvtap_disable_queue (struct macvtap_queue * q )
135
+ static int macvtap_disable_queue (struct macvtap_queue * q )
138
136
{
139
137
struct macvlan_dev * vlan ;
140
138
struct macvtap_queue * nq ;
141
139
142
- vlan = rcu_dereference_protected (q -> vlan ,
143
- lockdep_is_held (& macvtap_lock ));
144
-
140
+ ASSERT_RTNL ();
145
141
if (!q -> enabled )
146
142
return - EINVAL ;
147
143
144
+ vlan = rtnl_dereference (q -> vlan );
145
+
148
146
if (vlan ) {
149
147
int index = q -> queue_index ;
150
148
BUG_ON (index >= vlan -> numvtaps );
151
- nq = rcu_dereference_protected (vlan -> taps [vlan -> numvtaps - 1 ],
152
- lockdep_is_held (& macvtap_lock ));
149
+ nq = rtnl_dereference (vlan -> taps [vlan -> numvtaps - 1 ]);
153
150
nq -> queue_index = index ;
154
151
155
152
rcu_assign_pointer (vlan -> taps [index ], nq );
@@ -162,17 +159,6 @@ static int __macvtap_disable_queue(struct macvtap_queue *q)
162
159
return 0 ;
163
160
}
164
161
165
- static int macvtap_disable_queue (struct macvtap_queue * q )
166
- {
167
- int err ;
168
-
169
- spin_lock (& macvtap_lock );
170
- err = __macvtap_disable_queue (q );
171
- spin_unlock (& macvtap_lock );
172
-
173
- return err ;
174
- }
175
-
176
162
/*
177
163
* The file owning the queue got closed, give up both
178
164
* the reference that the files holds as well as the
@@ -185,20 +171,20 @@ static void macvtap_put_queue(struct macvtap_queue *q)
185
171
{
186
172
struct macvlan_dev * vlan ;
187
173
188
- spin_lock ( & macvtap_lock );
189
- vlan = rcu_dereference_protected (q -> vlan ,
190
- lockdep_is_held ( & macvtap_lock ));
174
+ rtnl_lock ( );
175
+ vlan = rtnl_dereference (q -> vlan );
176
+
191
177
if (vlan ) {
192
178
if (q -> enabled )
193
- BUG_ON (__macvtap_disable_queue (q ));
179
+ BUG_ON (macvtap_disable_queue (q ));
194
180
195
181
vlan -> numqueues -- ;
196
182
RCU_INIT_POINTER (q -> vlan , NULL );
197
183
sock_put (& q -> sk );
198
184
list_del_init (& q -> next );
199
185
}
200
186
201
- spin_unlock ( & macvtap_lock );
187
+ rtnl_unlock ( );
202
188
203
189
synchronize_rcu ();
204
190
sock_put (& q -> sk );
@@ -260,7 +246,7 @@ static void macvtap_del_queues(struct net_device *dev)
260
246
struct macvtap_queue * q , * tmp , * qlist [MAX_MACVTAP_QUEUES ];
261
247
int i , j = 0 ;
262
248
263
- spin_lock ( & macvtap_lock );
249
+ ASSERT_RTNL ( );
264
250
list_for_each_entry_safe (q , tmp , & vlan -> queue_list , next ) {
265
251
list_del_init (& q -> next );
266
252
qlist [j ++ ] = q ;
@@ -275,9 +261,6 @@ static void macvtap_del_queues(struct net_device *dev)
275
261
BUG_ON (vlan -> numqueues );
276
262
/* guarantee that any future macvtap_set_queue will fail */
277
263
vlan -> numvtaps = MAX_MACVTAP_QUEUES ;
278
- spin_unlock (& macvtap_lock );
279
-
280
- synchronize_rcu ();
281
264
282
265
for (-- j ; j >= 0 ; j -- )
283
266
sock_put (& qlist [j ]-> sk );
@@ -941,11 +924,10 @@ static struct macvlan_dev *macvtap_get_vlan(struct macvtap_queue *q)
941
924
{
942
925
struct macvlan_dev * vlan ;
943
926
944
- rcu_read_lock_bh ();
945
- vlan = rcu_dereference_bh (q -> vlan );
927
+ ASSERT_RTNL ();
928
+ vlan = rtnl_dereference (q -> vlan );
946
929
if (vlan )
947
930
dev_hold (vlan -> dev );
948
- rcu_read_unlock_bh ();
949
931
950
932
return vlan ;
951
933
}
@@ -1008,21 +990,27 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
1008
990
return ret ;
1009
991
1010
992
case TUNGETIFF :
993
+ rtnl_lock ();
1011
994
vlan = macvtap_get_vlan (q );
1012
- if (!vlan )
995
+ if (!vlan ) {
996
+ rtnl_unlock ();
1013
997
return - ENOLINK ;
998
+ }
1014
999
1015
1000
ret = 0 ;
1016
1001
if (copy_to_user (& ifr -> ifr_name , vlan -> dev -> name , IFNAMSIZ ) ||
1017
1002
put_user (q -> flags , & ifr -> ifr_flags ))
1018
1003
ret = - EFAULT ;
1019
1004
macvtap_put_vlan (vlan );
1005
+ rtnl_unlock ();
1020
1006
return ret ;
1021
1007
1022
1008
case TUNSETQUEUE :
1023
1009
if (get_user (u , & ifr -> ifr_flags ))
1024
1010
return - EFAULT ;
1025
- return macvtap_ioctl_set_queue (file , u );
1011
+ rtnl_lock ();
1012
+ ret = macvtap_ioctl_set_queue (file , u );
1013
+ rtnl_unlock ();
1026
1014
1027
1015
case TUNGETFEATURES :
1028
1016
if (put_user (IFF_TAP | IFF_NO_PI | IFF_VNET_HDR |
0 commit comments