aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/igmp.c27
1 files changed, 11 insertions, 16 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index bd24f6560a49..6110c6d6e613 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -2313,7 +2313,8 @@ static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq)
2313 state->in_dev = NULL; 2313 state->in_dev = NULL;
2314 for_each_netdev_rcu(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
2317 in_dev = __in_dev_get_rcu(state->dev);
2317 if (!in_dev) 2318 if (!in_dev)
2318 continue; 2319 continue;
2319 read_lock(&in_dev->mc_list_lock); 2320 read_lock(&in_dev->mc_list_lock);
@@ -2323,7 +2324,6 @@ static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq)
2323 break; 2324 break;
2324 } 2325 }
2325 read_unlock(&in_dev->mc_list_lock); 2326 read_unlock(&in_dev->mc_list_lock);
2326 in_dev_put(in_dev);
2327 } 2327 }
2328 return im; 2328 return im;
2329} 2329}
@@ -2333,16 +2333,15 @@ static struct ip_mc_list *igmp_mc_get_next(struct seq_file *seq, struct ip_mc_li
2333 struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); 2333 struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq);
2334 im = im->next; 2334 im = im->next;
2335 while (!im) { 2335 while (!im) {
2336 if (likely(state->in_dev != NULL)) { 2336 if (likely(state->in_dev != NULL))
2337 read_unlock(&state->in_dev->mc_list_lock); 2337 read_unlock(&state->in_dev->mc_list_lock);
2338 in_dev_put(state->in_dev); 2338
2339 } 2339 state->dev = next_net_device_rcu(state->dev);
2340 state->dev = next_net_device(state->dev);
2341 if (!state->dev) { 2340 if (!state->dev) {
2342 state->in_dev = NULL; 2341 state->in_dev = NULL;
2343 break; 2342 break;
2344 } 2343 }
2345 state->in_dev = in_dev_get(state->dev); 2344 state->in_dev = __in_dev_get_rcu(state->dev);
2346 if (!state->in_dev) 2345 if (!state->in_dev)
2347 continue; 2346 continue;
2348 read_lock(&state->in_dev->mc_list_lock); 2347 read_lock(&state->in_dev->mc_list_lock);
@@ -2384,7 +2383,6 @@ static void igmp_mc_seq_stop(struct seq_file *seq, void *v)
2384 struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); 2383 struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq);
2385 if (likely(state->in_dev != NULL)) { 2384 if (likely(state->in_dev != NULL)) {
2386 read_unlock(&state->in_dev->mc_list_lock); 2385 read_unlock(&state->in_dev->mc_list_lock);
2387 in_dev_put(state->in_dev);
2388 state->in_dev = NULL; 2386 state->in_dev = NULL;
2389 } 2387 }
2390 state->dev = NULL; 2388 state->dev = NULL;
@@ -2464,7 +2462,7 @@ static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq)
2464 state->im = NULL; 2462 state->im = NULL;
2465 for_each_netdev_rcu(net, state->dev) { 2463 for_each_netdev_rcu(net, state->dev) {
2466 struct in_device *idev; 2464 struct in_device *idev;
2467 idev = in_dev_get(state->dev); 2465 idev = __in_dev_get_rcu(state->dev);
2468 if (unlikely(idev == NULL)) 2466 if (unlikely(idev == NULL))
2469 continue; 2467 continue;
2470 read_lock(&idev->mc_list_lock); 2468 read_lock(&idev->mc_list_lock);
@@ -2480,7 +2478,6 @@ static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq)
2480 spin_unlock_bh(&im->lock); 2478 spin_unlock_bh(&im->lock);
2481 } 2479 }
2482 read_unlock(&idev->mc_list_lock); 2480 read_unlock(&idev->mc_list_lock);
2483 in_dev_put(idev);
2484 } 2481 }
2485 return psf; 2482 return psf;
2486} 2483}
@@ -2494,16 +2491,15 @@ static struct ip_sf_list *igmp_mcf_get_next(struct seq_file *seq, struct ip_sf_l
2494 spin_unlock_bh(&state->im->lock); 2491 spin_unlock_bh(&state->im->lock);
2495 state->im = state->im->next; 2492 state->im = state->im->next;
2496 while (!state->im) { 2493 while (!state->im) {
2497 if (likely(state->idev != NULL)) { 2494 if (likely(state->idev != NULL))
2498 read_unlock(&state->idev->mc_list_lock); 2495 read_unlock(&state->idev->mc_list_lock);
2499 in_dev_put(state->idev); 2496
2500 } 2497 state->dev = next_net_device_rcu(state->dev);
2501 state->dev = next_net_device(state->dev);
2502 if (!state->dev) { 2498 if (!state->dev) {
2503 state->idev = NULL; 2499 state->idev = NULL;
2504 goto out; 2500 goto out;
2505 } 2501 }
2506 state->idev = in_dev_get(state->dev); 2502 state->idev = __in_dev_get_rcu(state->dev);
2507 if (!state->idev) 2503 if (!state->idev)
2508 continue; 2504 continue;
2509 read_lock(&state->idev->mc_list_lock); 2505 read_lock(&state->idev->mc_list_lock);
@@ -2555,7 +2551,6 @@ static void igmp_mcf_seq_stop(struct seq_file *seq, void *v)
2555 } 2551 }
2556 if (likely(state->idev != NULL)) { 2552 if (likely(state->idev != NULL)) {
2557 read_unlock(&state->idev->mc_list_lock); 2553 read_unlock(&state->idev->mc_list_lock);
2558 in_dev_put(state->idev);
2559 state->idev = NULL; 2554 state->idev = NULL;
2560 } 2555 }
2561 state->dev = NULL; 2556 state->dev = NULL;