Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

phonet: Convert phonet_routes.lock to spinlock_t.

route_doit() calls phonet_route_add() or phonet_route_del()
for RTM_NEWROUTE or RTM_DELROUTE, respectively.

Both functions only touch phonet_pernet(dev_net(dev))->routes,
which is currently protected by RTNL and its dedicated mutex,
phonet_routes.lock.

We will convert route_doit() to RCU and cannot use mutex inside RCU.

Let's convert the mutex to spinlock_t.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Kuniyuki Iwashima and committed by
Paolo Abeni
3deec3b4 de51ad08

+14 -10
-1
include/net/phonet/pn_dev.h
··· 11 11 #define PN_DEV_H 12 12 13 13 #include <linux/list.h> 14 - #include <linux/mutex.h> 15 14 #include <linux/spinlock.h> 16 15 17 16 struct net;
+14 -9
net/phonet/pn_dev.c
··· 22 22 #include <net/phonet/pn_dev.h> 23 23 24 24 struct phonet_routes { 25 - struct mutex lock; 25 + spinlock_t lock; 26 26 struct net_device __rcu *table[64]; 27 27 }; 28 28 ··· 273 273 274 274 /* Remove left-over Phonet routes */ 275 275 bitmap_zero(deleted, 64); 276 - mutex_lock(&pnn->routes.lock); 277 - for (i = 0; i < 64; i++) 276 + 277 + spin_lock(&pnn->routes.lock); 278 + for (i = 0; i < 64; i++) { 278 279 if (rcu_access_pointer(pnn->routes.table[i]) == dev) { 279 280 RCU_INIT_POINTER(pnn->routes.table[i], NULL); 280 281 set_bit(i, deleted); 281 282 } 282 - mutex_unlock(&pnn->routes.lock); 283 + } 284 + spin_unlock(&pnn->routes.lock); 283 285 284 286 if (bitmap_empty(deleted, 64)) 285 287 return; /* short-circuit RCU */ ··· 328 326 329 327 INIT_LIST_HEAD(&pnn->pndevs.list); 330 328 spin_lock_init(&pnn->pndevs.lock); 331 - mutex_init(&pnn->routes.lock); 329 + spin_lock_init(&pnn->routes.lock); 332 330 return 0; 333 331 } 334 332 ··· 378 376 int err = -EEXIST; 379 377 380 378 daddr = daddr >> 2; 381 - mutex_lock(&routes->lock); 379 + 380 + spin_lock(&routes->lock); 382 381 if (routes->table[daddr] == NULL) { 383 382 rcu_assign_pointer(routes->table[daddr], dev); 384 383 dev_hold(dev); 385 384 err = 0; 386 385 } 387 - mutex_unlock(&routes->lock); 386 + spin_unlock(&routes->lock); 387 + 388 388 return err; 389 389 } 390 390 ··· 396 392 struct phonet_routes *routes = &pnn->routes; 397 393 398 394 daddr = daddr >> 2; 399 - mutex_lock(&routes->lock); 395 + 396 + spin_lock(&routes->lock); 400 397 if (rcu_access_pointer(routes->table[daddr]) == dev) 401 398 RCU_INIT_POINTER(routes->table[daddr], NULL); 402 399 else 403 400 dev = NULL; 404 - mutex_unlock(&routes->lock); 401 + spin_unlock(&routes->lock); 405 402 406 403 if (!dev) 407 404 return -ENOENT;