|
@@ -2375,9 +2375,9 @@ static inline struct ifmcaddr6 *igmp6_mc_get_first(struct seq_file *seq)
|
|
struct net *net = seq_file_net(seq);
|
|
struct net *net = seq_file_net(seq);
|
|
|
|
|
|
state->idev = NULL;
|
|
state->idev = NULL;
|
|
- for_each_netdev(net, state->dev) {
|
|
|
|
|
|
+ for_each_netdev_rcu(net, state->dev) {
|
|
struct inet6_dev *idev;
|
|
struct inet6_dev *idev;
|
|
- idev = in6_dev_get(state->dev);
|
|
|
|
|
|
+ idev = __in6_dev_get(state->dev);
|
|
if (!idev)
|
|
if (!idev)
|
|
continue;
|
|
continue;
|
|
read_lock_bh(&idev->lock);
|
|
read_lock_bh(&idev->lock);
|
|
@@ -2387,7 +2387,6 @@ static inline struct ifmcaddr6 *igmp6_mc_get_first(struct seq_file *seq)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
read_unlock_bh(&idev->lock);
|
|
read_unlock_bh(&idev->lock);
|
|
- in6_dev_put(idev);
|
|
|
|
}
|
|
}
|
|
return im;
|
|
return im;
|
|
}
|
|
}
|
|
@@ -2398,16 +2397,15 @@ static struct ifmcaddr6 *igmp6_mc_get_next(struct seq_file *seq, struct ifmcaddr
|
|
|
|
|
|
im = im->next;
|
|
im = im->next;
|
|
while (!im) {
|
|
while (!im) {
|
|
- if (likely(state->idev != NULL)) {
|
|
|
|
|
|
+ if (likely(state->idev != NULL))
|
|
read_unlock_bh(&state->idev->lock);
|
|
read_unlock_bh(&state->idev->lock);
|
|
- in6_dev_put(state->idev);
|
|
|
|
- }
|
|
|
|
- state->dev = next_net_device(state->dev);
|
|
|
|
|
|
+
|
|
|
|
+ state->dev = next_net_device_rcu(state->dev);
|
|
if (!state->dev) {
|
|
if (!state->dev) {
|
|
state->idev = NULL;
|
|
state->idev = NULL;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- state->idev = in6_dev_get(state->dev);
|
|
|
|
|
|
+ state->idev = __in6_dev_get(state->dev);
|
|
if (!state->idev)
|
|
if (!state->idev)
|
|
continue;
|
|
continue;
|
|
read_lock_bh(&state->idev->lock);
|
|
read_lock_bh(&state->idev->lock);
|
|
@@ -2426,31 +2424,31 @@ static struct ifmcaddr6 *igmp6_mc_get_idx(struct seq_file *seq, loff_t pos)
|
|
}
|
|
}
|
|
|
|
|
|
static void *igmp6_mc_seq_start(struct seq_file *seq, loff_t *pos)
|
|
static void *igmp6_mc_seq_start(struct seq_file *seq, loff_t *pos)
|
|
- __acquires(dev_base_lock)
|
|
|
|
|
|
+ __acquires(RCU)
|
|
{
|
|
{
|
|
- read_lock(&dev_base_lock);
|
|
|
|
|
|
+ rcu_read_lock();
|
|
return igmp6_mc_get_idx(seq, *pos);
|
|
return igmp6_mc_get_idx(seq, *pos);
|
|
}
|
|
}
|
|
|
|
|
|
static void *igmp6_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
|
static void *igmp6_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
|
{
|
|
{
|
|
- struct ifmcaddr6 *im;
|
|
|
|
- im = igmp6_mc_get_next(seq, v);
|
|
|
|
|
|
+ struct ifmcaddr6 *im = igmp6_mc_get_next(seq, v);
|
|
|
|
+
|
|
++*pos;
|
|
++*pos;
|
|
return im;
|
|
return im;
|
|
}
|
|
}
|
|
|
|
|
|
static void igmp6_mc_seq_stop(struct seq_file *seq, void *v)
|
|
static void igmp6_mc_seq_stop(struct seq_file *seq, void *v)
|
|
- __releases(dev_base_lock)
|
|
|
|
|
|
+ __releases(RCU)
|
|
{
|
|
{
|
|
struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
|
|
struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
|
|
|
|
+
|
|
if (likely(state->idev != NULL)) {
|
|
if (likely(state->idev != NULL)) {
|
|
read_unlock_bh(&state->idev->lock);
|
|
read_unlock_bh(&state->idev->lock);
|
|
- in6_dev_put(state->idev);
|
|
|
|
state->idev = NULL;
|
|
state->idev = NULL;
|
|
}
|
|
}
|
|
state->dev = NULL;
|
|
state->dev = NULL;
|
|
- read_unlock(&dev_base_lock);
|
|
|
|
|
|
+ rcu_read_unlock();
|
|
}
|
|
}
|
|
|
|
|
|
static int igmp6_mc_seq_show(struct seq_file *seq, void *v)
|
|
static int igmp6_mc_seq_show(struct seq_file *seq, void *v)
|
|
@@ -2507,9 +2505,9 @@ static inline struct ip6_sf_list *igmp6_mcf_get_first(struct seq_file *seq)
|
|
|
|
|
|
state->idev = NULL;
|
|
state->idev = NULL;
|
|
state->im = NULL;
|
|
state->im = NULL;
|
|
- for_each_netdev(net, state->dev) {
|
|
|
|
|
|
+ for_each_netdev_rcu(net, state->dev) {
|
|
struct inet6_dev *idev;
|
|
struct inet6_dev *idev;
|
|
- idev = in6_dev_get(state->dev);
|
|
|
|
|
|
+ idev = __in6_dev_get(state->dev);
|
|
if (unlikely(idev == NULL))
|
|
if (unlikely(idev == NULL))
|
|
continue;
|
|
continue;
|
|
read_lock_bh(&idev->lock);
|
|
read_lock_bh(&idev->lock);
|
|
@@ -2525,7 +2523,6 @@ static inline struct ip6_sf_list *igmp6_mcf_get_first(struct seq_file *seq)
|
|
spin_unlock_bh(&im->mca_lock);
|
|
spin_unlock_bh(&im->mca_lock);
|
|
}
|
|
}
|
|
read_unlock_bh(&idev->lock);
|
|
read_unlock_bh(&idev->lock);
|
|
- in6_dev_put(idev);
|
|
|
|
}
|
|
}
|
|
return psf;
|
|
return psf;
|
|
}
|
|
}
|
|
@@ -2539,16 +2536,15 @@ static struct ip6_sf_list *igmp6_mcf_get_next(struct seq_file *seq, struct ip6_s
|
|
spin_unlock_bh(&state->im->mca_lock);
|
|
spin_unlock_bh(&state->im->mca_lock);
|
|
state->im = state->im->next;
|
|
state->im = state->im->next;
|
|
while (!state->im) {
|
|
while (!state->im) {
|
|
- if (likely(state->idev != NULL)) {
|
|
|
|
|
|
+ if (likely(state->idev != NULL))
|
|
read_unlock_bh(&state->idev->lock);
|
|
read_unlock_bh(&state->idev->lock);
|
|
- in6_dev_put(state->idev);
|
|
|
|
- }
|
|
|
|
- state->dev = next_net_device(state->dev);
|
|
|
|
|
|
+
|
|
|
|
+ state->dev = next_net_device_rcu(state->dev);
|
|
if (!state->dev) {
|
|
if (!state->dev) {
|
|
state->idev = NULL;
|
|
state->idev = NULL;
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
- state->idev = in6_dev_get(state->dev);
|
|
|
|
|
|
+ state->idev = __in6_dev_get(state->dev);
|
|
if (!state->idev)
|
|
if (!state->idev)
|
|
continue;
|
|
continue;
|
|
read_lock_bh(&state->idev->lock);
|
|
read_lock_bh(&state->idev->lock);
|
|
@@ -2573,9 +2569,9 @@ static struct ip6_sf_list *igmp6_mcf_get_idx(struct seq_file *seq, loff_t pos)
|
|
}
|
|
}
|
|
|
|
|
|
static void *igmp6_mcf_seq_start(struct seq_file *seq, loff_t *pos)
|
|
static void *igmp6_mcf_seq_start(struct seq_file *seq, loff_t *pos)
|
|
- __acquires(dev_base_lock)
|
|
|
|
|
|
+ __acquires(RCU)
|
|
{
|
|
{
|
|
- read_lock(&dev_base_lock);
|
|
|
|
|
|
+ rcu_read_lock();
|
|
return *pos ? igmp6_mcf_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
|
|
return *pos ? igmp6_mcf_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2591,7 +2587,7 @@ static void *igmp6_mcf_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
|
}
|
|
}
|
|
|
|
|
|
static void igmp6_mcf_seq_stop(struct seq_file *seq, void *v)
|
|
static void igmp6_mcf_seq_stop(struct seq_file *seq, void *v)
|
|
- __releases(dev_base_lock)
|
|
|
|
|
|
+ __releases(RCU)
|
|
{
|
|
{
|
|
struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq);
|
|
struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq);
|
|
if (likely(state->im != NULL)) {
|
|
if (likely(state->im != NULL)) {
|
|
@@ -2600,11 +2596,10 @@ static void igmp6_mcf_seq_stop(struct seq_file *seq, void *v)
|
|
}
|
|
}
|
|
if (likely(state->idev != NULL)) {
|
|
if (likely(state->idev != NULL)) {
|
|
read_unlock_bh(&state->idev->lock);
|
|
read_unlock_bh(&state->idev->lock);
|
|
- in6_dev_put(state->idev);
|
|
|
|
state->idev = NULL;
|
|
state->idev = NULL;
|
|
}
|
|
}
|
|
state->dev = NULL;
|
|
state->dev = NULL;
|
|
- read_unlock(&dev_base_lock);
|
|
|
|
|
|
+ rcu_read_unlock();
|
|
}
|
|
}
|
|
|
|
|
|
static int igmp6_mcf_seq_show(struct seq_file *seq, void *v)
|
|
static int igmp6_mcf_seq_show(struct seq_file *seq, void *v)
|