Skip to content

Commit 8888013

Browse files
Rémi Denis-Courmontdavem330
authored andcommitted
Phonet: convert routing table to RCU
Signed-off-by: Rémi Denis-Courmont <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7ed0132 commit 8888013

File tree

1 file changed

+34
-25
lines changed

1 file changed

+34
-25
lines changed

net/phonet/pn_dev.c

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
#include <net/phonet/pn_dev.h>
3535

3636
struct phonet_routes {
37-
spinlock_t lock;
37+
struct mutex lock;
3838
struct net_device *table[64];
3939
};
4040

@@ -248,17 +248,22 @@ static void phonet_route_autodel(struct net_device *dev)
248248

249249
/* Remove left-over Phonet routes */
250250
bitmap_zero(deleted, 64);
251-
spin_lock_bh(&pnn->routes.lock);
251+
mutex_lock(&pnn->routes.lock);
252252
for (i = 0; i < 64; i++)
253253
if (dev == pnn->routes.table[i]) {
254+
rcu_assign_pointer(pnn->routes.table[i], NULL);
254255
set_bit(i, deleted);
255-
pnn->routes.table[i] = NULL;
256-
dev_put(dev);
257256
}
258-
spin_unlock_bh(&pnn->routes.lock);
257+
mutex_unlock(&pnn->routes.lock);
258+
259+
if (bitmap_empty(deleted, 64))
260+
return; /* short-circuit RCU */
261+
synchronize_rcu();
259262
for (i = find_first_bit(deleted, 64); i < 64;
260-
i = find_next_bit(deleted, 64, i + 1))
263+
i = find_next_bit(deleted, 64, i + 1)) {
261264
rtm_phonet_notify(RTM_DELROUTE, dev, i);
265+
dev_put(dev);
266+
}
262267
}
263268

264269
/* notify Phonet of device events */
@@ -300,7 +305,7 @@ static int phonet_init_net(struct net *net)
300305

301306
INIT_LIST_HEAD(&pnn->pndevs.list);
302307
spin_lock_init(&pnn->pndevs.lock);
303-
spin_lock_init(&pnn->routes.lock);
308+
mutex_init(&pnn->routes.lock);
304309
net_assign_generic(net, phonet_net_id, pnn);
305310
return 0;
306311
}
@@ -361,31 +366,34 @@ int phonet_route_add(struct net_device *dev, u8 daddr)
361366
int err = -EEXIST;
362367

363368
daddr = daddr >> 2;
364-
spin_lock_bh(&routes->lock);
369+
mutex_lock(&routes->lock);
365370
if (routes->table[daddr] == NULL) {
366-
routes->table[daddr] = dev;
371+
rcu_assign_pointer(routes->table[daddr], dev);
367372
dev_hold(dev);
368373
err = 0;
369374
}
370-
spin_unlock_bh(&routes->lock);
375+
mutex_unlock(&routes->lock);
371376
return err;
372377
}
373378

374379
int phonet_route_del(struct net_device *dev, u8 daddr)
375380
{
376381
struct phonet_net *pnn = net_generic(dev_net(dev), phonet_net_id);
377382
struct phonet_routes *routes = &pnn->routes;
378-
int err = -ENOENT;
379383

380384
daddr = daddr >> 2;
381-
spin_lock_bh(&routes->lock);
382-
if (dev == routes->table[daddr]) {
383-
routes->table[daddr] = NULL;
384-
dev_put(dev);
385-
err = 0;
386-
}
387-
spin_unlock_bh(&routes->lock);
388-
return err;
385+
mutex_lock(&routes->lock);
386+
if (dev == routes->table[daddr])
387+
rcu_assign_pointer(routes->table[daddr], NULL);
388+
else
389+
dev = NULL;
390+
mutex_unlock(&routes->lock);
391+
392+
if (!dev)
393+
return -ENOENT;
394+
synchronize_rcu();
395+
dev_put(dev);
396+
return 0;
389397
}
390398

391399
struct net_device *phonet_route_get(struct net *net, u8 daddr)
@@ -397,9 +405,9 @@ struct net_device *phonet_route_get(struct net *net, u8 daddr)
397405
ASSERT_RTNL(); /* no need to hold the device */
398406

399407
daddr >>= 2;
400-
spin_lock_bh(&routes->lock);
401-
dev = routes->table[daddr];
402-
spin_unlock_bh(&routes->lock);
408+
rcu_read_lock();
409+
dev = rcu_dereference(routes->table[daddr]);
410+
rcu_read_unlock();
403411
return dev;
404412
}
405413

@@ -409,11 +417,12 @@ struct net_device *phonet_route_output(struct net *net, u8 daddr)
409417
struct phonet_routes *routes = &pnn->routes;
410418
struct net_device *dev;
411419

412-
spin_lock_bh(&routes->lock);
413-
dev = routes->table[daddr >> 2];
420+
daddr >>= 2;
421+
rcu_read_lock();
422+
dev = rcu_dereference(routes->table[daddr]);
414423
if (dev)
415424
dev_hold(dev);
416-
spin_unlock_bh(&routes->lock);
425+
rcu_read_unlock();
417426

418427
if (!dev)
419428
dev = phonet_device_get(net); /* Default route */

0 commit comments

Comments
 (0)