diff options
Diffstat (limited to 'net/ipv6/anycast.c')
-rw-r--r-- | net/ipv6/anycast.c | 35 |
1 files changed, 17 insertions, 18 deletions
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index 1ae58bec1de0..f1c74c8ef9de 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c | |||
@@ -404,13 +404,13 @@ int ipv6_chk_acast_addr(struct net *net, struct net_device *dev, | |||
404 | 404 | ||
405 | if (dev) | 405 | if (dev) |
406 | return ipv6_chk_acast_dev(dev, addr); | 406 | return ipv6_chk_acast_dev(dev, addr); |
407 | read_lock(&dev_base_lock); | 407 | rcu_read_lock(); |
408 | for_each_netdev(net, dev) | 408 | for_each_netdev_rcu(net, dev) |
409 | if (ipv6_chk_acast_dev(dev, addr)) { | 409 | if (ipv6_chk_acast_dev(dev, addr)) { |
410 | found = 1; | 410 | found = 1; |
411 | break; | 411 | break; |
412 | } | 412 | } |
413 | read_unlock(&dev_base_lock); | 413 | rcu_read_unlock(); |
414 | return found; | 414 | return found; |
415 | } | 415 | } |
416 | 416 | ||
@@ -431,9 +431,9 @@ static inline struct ifacaddr6 *ac6_get_first(struct seq_file *seq) | |||
431 | struct net *net = seq_file_net(seq); | 431 | struct net *net = seq_file_net(seq); |
432 | 432 | ||
433 | state->idev = NULL; | 433 | state->idev = NULL; |
434 | for_each_netdev(net, state->dev) { | 434 | for_each_netdev_rcu(net, state->dev) { |
435 | struct inet6_dev *idev; | 435 | struct inet6_dev *idev; |
436 | idev = in6_dev_get(state->dev); | 436 | idev = __in6_dev_get(state->dev); |
437 | if (!idev) | 437 | if (!idev) |
438 | continue; | 438 | continue; |
439 | read_lock_bh(&idev->lock); | 439 | read_lock_bh(&idev->lock); |
@@ -443,7 +443,6 @@ static inline struct ifacaddr6 *ac6_get_first(struct seq_file *seq) | |||
443 | break; | 443 | break; |
444 | } | 444 | } |
445 | read_unlock_bh(&idev->lock); | 445 | read_unlock_bh(&idev->lock); |
446 | in6_dev_put(idev); | ||
447 | } | 446 | } |
448 | return im; | 447 | return im; |
449 | } | 448 | } |
@@ -454,16 +453,15 @@ static struct ifacaddr6 *ac6_get_next(struct seq_file *seq, struct ifacaddr6 *im | |||
454 | 453 | ||
455 | im = im->aca_next; | 454 | im = im->aca_next; |
456 | while (!im) { | 455 | while (!im) { |
457 | if (likely(state->idev != NULL)) { | 456 | if (likely(state->idev != NULL)) |
458 | read_unlock_bh(&state->idev->lock); | 457 | read_unlock_bh(&state->idev->lock); |
459 | in6_dev_put(state->idev); | 458 | |
460 | } | 459 | state->dev = next_net_device_rcu(state->dev); |
461 | state->dev = next_net_device(state->dev); | ||
462 | if (!state->dev) { | 460 | if (!state->dev) { |
463 | state->idev = NULL; | 461 | state->idev = NULL; |
464 | break; | 462 | break; |
465 | } | 463 | } |
466 | state->idev = in6_dev_get(state->dev); | 464 | state->idev = __in6_dev_get(state->dev); |
467 | if (!state->idev) | 465 | if (!state->idev) |
468 | continue; | 466 | continue; |
469 | read_lock_bh(&state->idev->lock); | 467 | read_lock_bh(&state->idev->lock); |
@@ -482,29 +480,30 @@ static struct ifacaddr6 *ac6_get_idx(struct seq_file *seq, loff_t pos) | |||
482 | } | 480 | } |
483 | 481 | ||
484 | static void *ac6_seq_start(struct seq_file *seq, loff_t *pos) | 482 | static void *ac6_seq_start(struct seq_file *seq, loff_t *pos) |
485 | __acquires(dev_base_lock) | 483 | __acquires(RCU) |
486 | { | 484 | { |
487 | read_lock(&dev_base_lock); | 485 | rcu_read_lock(); |
488 | return ac6_get_idx(seq, *pos); | 486 | return ac6_get_idx(seq, *pos); |
489 | } | 487 | } |
490 | 488 | ||
491 | static void *ac6_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 489 | static void *ac6_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
492 | { | 490 | { |
493 | struct ifacaddr6 *im; | 491 | struct ifacaddr6 *im = ac6_get_next(seq, v); |
494 | im = ac6_get_next(seq, v); | 492 | |
495 | ++*pos; | 493 | ++*pos; |
496 | return im; | 494 | return im; |
497 | } | 495 | } |
498 | 496 | ||
499 | static void ac6_seq_stop(struct seq_file *seq, void *v) | 497 | static void ac6_seq_stop(struct seq_file *seq, void *v) |
500 | __releases(dev_base_lock) | 498 | __releases(RCU) |
501 | { | 499 | { |
502 | struct ac6_iter_state *state = ac6_seq_private(seq); | 500 | struct ac6_iter_state *state = ac6_seq_private(seq); |
501 | |||
503 | if (likely(state->idev != NULL)) { | 502 | if (likely(state->idev != NULL)) { |
504 | read_unlock_bh(&state->idev->lock); | 503 | read_unlock_bh(&state->idev->lock); |
505 | in6_dev_put(state->idev); | 504 | state->idev = NULL; |
506 | } | 505 | } |
507 | read_unlock(&dev_base_lock); | 506 | rcu_read_unlock(); |
508 | } | 507 | } |
509 | 508 | ||
510 | static int ac6_seq_show(struct seq_file *seq, void *v) | 509 | static int ac6_seq_show(struct seq_file *seq, void *v) |