diff options
author | stephen hemminger <shemminger@vyatta.com> | 2009-11-10 02:54:55 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-11 01:27:12 -0500 |
commit | 61fbab77a843d2e772322ac130715cc9a98bf718 (patch) | |
tree | ceb0046726e50bb72366d57aa2316f85dacf6744 /net/ipv4/igmp.c | |
parent | fa918602b61a71b4a9f47861b7e65c70258516c1 (diff) |
IPV4: use rcu to walk list of devices in IGMP
This also needs to be optimized for large number of devices.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/igmp.c')
-rw-r--r-- | net/ipv4/igmp.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index d41e5de79a82..bd24f6560a49 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -2311,7 +2311,7 @@ static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq) | |||
2311 | struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); | 2311 | struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); |
2312 | 2312 | ||
2313 | state->in_dev = NULL; | 2313 | state->in_dev = NULL; |
2314 | for_each_netdev(net, state->dev) { | 2314 | for_each_netdev_rcu(net, state->dev) { |
2315 | struct in_device *in_dev; | 2315 | struct in_device *in_dev; |
2316 | in_dev = in_dev_get(state->dev); | 2316 | in_dev = in_dev_get(state->dev); |
2317 | if (!in_dev) | 2317 | if (!in_dev) |
@@ -2361,9 +2361,9 @@ static struct ip_mc_list *igmp_mc_get_idx(struct seq_file *seq, loff_t pos) | |||
2361 | } | 2361 | } |
2362 | 2362 | ||
2363 | static void *igmp_mc_seq_start(struct seq_file *seq, loff_t *pos) | 2363 | static void *igmp_mc_seq_start(struct seq_file *seq, loff_t *pos) |
2364 | __acquires(dev_base_lock) | 2364 | __acquires(rcu) |
2365 | { | 2365 | { |
2366 | read_lock(&dev_base_lock); | 2366 | rcu_read_lock(); |
2367 | return *pos ? igmp_mc_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; | 2367 | return *pos ? igmp_mc_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; |
2368 | } | 2368 | } |
2369 | 2369 | ||
@@ -2379,7 +2379,7 @@ static void *igmp_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
2379 | } | 2379 | } |
2380 | 2380 | ||
2381 | static void igmp_mc_seq_stop(struct seq_file *seq, void *v) | 2381 | static void igmp_mc_seq_stop(struct seq_file *seq, void *v) |
2382 | __releases(dev_base_lock) | 2382 | __releases(rcu) |
2383 | { | 2383 | { |
2384 | struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); | 2384 | struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); |
2385 | if (likely(state->in_dev != NULL)) { | 2385 | if (likely(state->in_dev != NULL)) { |
@@ -2388,7 +2388,7 @@ static void igmp_mc_seq_stop(struct seq_file *seq, void *v) | |||
2388 | state->in_dev = NULL; | 2388 | state->in_dev = NULL; |
2389 | } | 2389 | } |
2390 | state->dev = NULL; | 2390 | state->dev = NULL; |
2391 | read_unlock(&dev_base_lock); | 2391 | rcu_read_unlock(); |
2392 | } | 2392 | } |
2393 | 2393 | ||
2394 | static int igmp_mc_seq_show(struct seq_file *seq, void *v) | 2394 | static int igmp_mc_seq_show(struct seq_file *seq, void *v) |
@@ -2462,7 +2462,7 @@ static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq) | |||
2462 | 2462 | ||
2463 | state->idev = NULL; | 2463 | state->idev = NULL; |
2464 | state->im = NULL; | 2464 | state->im = NULL; |
2465 | for_each_netdev(net, state->dev) { | 2465 | for_each_netdev_rcu(net, state->dev) { |
2466 | struct in_device *idev; | 2466 | struct in_device *idev; |
2467 | idev = in_dev_get(state->dev); | 2467 | idev = in_dev_get(state->dev); |
2468 | if (unlikely(idev == NULL)) | 2468 | if (unlikely(idev == NULL)) |
@@ -2528,8 +2528,9 @@ static struct ip_sf_list *igmp_mcf_get_idx(struct seq_file *seq, loff_t pos) | |||
2528 | } | 2528 | } |
2529 | 2529 | ||
2530 | static void *igmp_mcf_seq_start(struct seq_file *seq, loff_t *pos) | 2530 | static void *igmp_mcf_seq_start(struct seq_file *seq, loff_t *pos) |
2531 | __acquires(rcu) | ||
2531 | { | 2532 | { |
2532 | read_lock(&dev_base_lock); | 2533 | rcu_read_lock(); |
2533 | return *pos ? igmp_mcf_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; | 2534 | return *pos ? igmp_mcf_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; |
2534 | } | 2535 | } |
2535 | 2536 | ||
@@ -2545,6 +2546,7 @@ static void *igmp_mcf_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
2545 | } | 2546 | } |
2546 | 2547 | ||
2547 | static void igmp_mcf_seq_stop(struct seq_file *seq, void *v) | 2548 | static void igmp_mcf_seq_stop(struct seq_file *seq, void *v) |
2549 | __releases(rcu) | ||
2548 | { | 2550 | { |
2549 | struct igmp_mcf_iter_state *state = igmp_mcf_seq_private(seq); | 2551 | struct igmp_mcf_iter_state *state = igmp_mcf_seq_private(seq); |
2550 | if (likely(state->im != NULL)) { | 2552 | if (likely(state->im != NULL)) { |
@@ -2557,7 +2559,7 @@ static void igmp_mcf_seq_stop(struct seq_file *seq, void *v) | |||
2557 | state->idev = NULL; | 2559 | state->idev = NULL; |
2558 | } | 2560 | } |
2559 | state->dev = NULL; | 2561 | state->dev = NULL; |
2560 | read_unlock(&dev_base_lock); | 2562 | rcu_read_unlock(); |
2561 | } | 2563 | } |
2562 | 2564 | ||
2563 | static int igmp_mcf_seq_show(struct seq_file *seq, void *v) | 2565 | static int igmp_mcf_seq_show(struct seq_file *seq, void *v) |