* [PATCH net-next v2 5/7] mld: convert ipv6_mc_socklist->sflist to RCU
@ 2021-02-13 17:52 Taehee Yoo
2021-02-13 19:41 ` kernel test robot
0 siblings, 1 reply; 3+ messages in thread
From: Taehee Yoo @ 2021-02-13 17:52 UTC (permalink / raw)
To: davem, kuba, xiyou.wangcong, netdev, jwi, kgraul, hca, gor,
borntraeger, mareklindner, sw, a, sven, yoshfuji, dsahern
Cc: Taehee Yoo
The sflist has been protected by rwlock so that the critical section
is atomic context.
In order to switch this context, changing locking is needed.
The sflist actually already protected by RTNL So if it's converted
to use RCU, its control path context can be switched to sleepable.
Suggested-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: Taehee Yoo <ap420073@gmail.com>
---
v1 -> v2:
- Separated from previous big one patch.
include/net/if_inet6.h | 4 ++--
net/ipv6/mcast.c | 52 ++++++++++++++++++------------------------
2 files changed, 24 insertions(+), 32 deletions(-)
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 4d9855be644c..d8507bef0a0c 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -78,6 +78,7 @@ struct inet6_ifaddr {
struct ip6_sf_socklist {
unsigned int sl_max;
unsigned int sl_count;
+ struct rcu_head rcu;
struct in6_addr sl_addr[];
};
@@ -91,8 +92,7 @@ struct ipv6_mc_socklist {
int ifindex;
unsigned int sfmode; /* MCAST_{INCLUDE,EXCLUDE} */
struct ipv6_mc_socklist __rcu *next;
- rwlock_t sflock;
- struct ip6_sf_socklist *sflist;
+ struct ip6_sf_socklist __rcu *sflist;
struct rcu_head rcu;
};
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index e80b78b1a8a7..cffa2eeb88c5 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -178,8 +178,7 @@ static int __ipv6_sock_mc_join(struct sock *sk, int ifindex,
mc_lst->ifindex = dev->ifindex;
mc_lst->sfmode = mode;
- rwlock_init(&mc_lst->sflock);
- mc_lst->sflist = NULL;
+ RCU_INIT_POINTER(mc_lst->sflist, NULL);
/*
* now add/increase the group membership on the device
@@ -335,7 +334,6 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
struct net *net = sock_net(sk);
int i, j, rv;
int leavegroup = 0;
- int pmclocked = 0;
int err;
source = &((struct sockaddr_in6 *)&pgsr->gsr_source)->sin6_addr;
@@ -364,7 +362,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
goto done;
}
/* if a source filter was set, must be the same mode as before */
- if (pmc->sflist) {
+ if (rcu_access_pointer(pmc->sflist)) {
if (pmc->sfmode != omode) {
err = -EINVAL;
goto done;
@@ -376,10 +374,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
pmc->sfmode = omode;
}
- write_lock(&pmc->sflock);
- pmclocked = 1;
-
- psl = pmc->sflist;
+ psl = rtnl_dereference(pmc->sflist);
if (!add) {
if (!psl)
goto done; /* err = -EADDRNOTAVAIL */
@@ -429,9 +424,11 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
if (psl) {
for (i = 0; i < psl->sl_count; i++)
newpsl->sl_addr[i] = psl->sl_addr[i];
- sock_kfree_s(sk, psl, IP6_SFLSIZE(psl->sl_max));
+ atomic_sub(IP6_SFLSIZE(psl->sl_max), &sk->sk_omem_alloc);
+ kfree_rcu(psl, rcu);
}
- pmc->sflist = psl = newpsl;
+ rcu_assign_pointer(psl, newpsl);
+ rcu_assign_pointer(pmc->sflist, psl);
}
rv = 1; /* > 0 for insert logic below if sl_count is 0 */
for (i = 0; i < psl->sl_count; i++) {
@@ -447,8 +444,6 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
/* update the interface list */
ip6_mc_add_src(idev, group, omode, 1, source, 1);
done:
- if (pmclocked)
- write_unlock(&pmc->sflock);
read_unlock_bh(&idev->lock);
rcu_read_unlock();
if (leavegroup)
@@ -526,17 +521,16 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf,
(void) ip6_mc_add_src(idev, group, gsf->gf_fmode, 0, NULL, 0);
}
- write_lock(&pmc->sflock);
- psl = pmc->sflist;
+ psl = rtnl_dereference(pmc->sflist);
if (psl) {
(void) ip6_mc_del_src(idev, group, pmc->sfmode,
psl->sl_count, psl->sl_addr, 0);
- sock_kfree_s(sk, psl, IP6_SFLSIZE(psl->sl_max));
+ atomic_sub(IP6_SFLSIZE(psl->sl_max), &sk->sk_omem_alloc);
+ kfree_rcu(psl, rcu);
} else
(void) ip6_mc_del_src(idev, group, pmc->sfmode, 0, NULL, 0);
- pmc->sflist = newpsl;
+ rcu_assign_pointer(pmc->sflist, newpsl);
pmc->sfmode = gsf->gf_fmode;
- write_unlock(&pmc->sflock);
err = 0;
done:
read_unlock_bh(&idev->lock);
@@ -585,16 +579,14 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,
if (!pmc) /* must have a prior join */
goto done;
gsf->gf_fmode = pmc->sfmode;
- psl = pmc->sflist;
+ psl = rtnl_dereference(pmc->sflist);
count = psl ? psl->sl_count : 0;
read_unlock_bh(&idev->lock);
rcu_read_unlock();
copycount = count < gsf->gf_numsrc ? count : gsf->gf_numsrc;
gsf->gf_numsrc = count;
- /* changes to psl require the socket lock, and a write lock
- * on pmc->sflock. We have the socket lock so reading here is safe.
- */
+
for (i = 0; i < copycount; i++, p++) {
struct sockaddr_in6 *psin6;
struct sockaddr_storage ss;
@@ -630,8 +622,7 @@ bool inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr,
rcu_read_unlock();
return np->mc_all;
}
- read_lock(&mc->sflock);
- psl = mc->sflist;
+ psl = rcu_dereference(mc->sflist);
if (!psl) {
rv = mc->sfmode == MCAST_EXCLUDE;
} else {
@@ -646,7 +637,6 @@ bool inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr,
if (mc->sfmode == MCAST_EXCLUDE && i < psl->sl_count)
rv = false;
}
- read_unlock(&mc->sflock);
rcu_read_unlock();
return rv;
@@ -2448,19 +2438,21 @@ static void igmp6_join_group(struct ifmcaddr6 *ma)
static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
struct inet6_dev *idev)
{
+ struct ip6_sf_socklist *psl;
int err;
- write_lock_bh(&iml->sflock);
- if (!iml->sflist) {
+ psl = rtnl_dereference(iml->sflist);
+
+ if (!psl) {
/* any-source empty exclude case */
err = ip6_mc_del_src(idev, &iml->addr, iml->sfmode, 0, NULL, 0);
} else {
err = ip6_mc_del_src(idev, &iml->addr, iml->sfmode,
- iml->sflist->sl_count, iml->sflist->sl_addr, 0);
- sock_kfree_s(sk, iml->sflist, IP6_SFLSIZE(iml->sflist->sl_max));
- iml->sflist = NULL;
+ psl->sl_count, psl->sl_addr, 0);
+ RCU_INIT_POINTER(iml->sflist, NULL);
+ atomic_sub(IP6_SFLSIZE(psl->sl_max), &sk->sk_omem_alloc);
+ kfree_rcu(psl, rcu);
}
- write_unlock_bh(&iml->sflock);
return err;
}
--
2.17.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH net-next v2 5/7] mld: convert ipv6_mc_socklist->sflist to RCU
2021-02-13 17:52 [PATCH net-next v2 5/7] mld: convert ipv6_mc_socklist->sflist to RCU Taehee Yoo
@ 2021-02-13 19:41 ` kernel test robot
2021-02-14 11:32 ` Taehee Yoo
0 siblings, 1 reply; 3+ messages in thread
From: kernel test robot @ 2021-02-13 19:41 UTC (permalink / raw)
To: Taehee Yoo, davem, kuba, xiyou.wangcong, netdev, jwi, kgraul,
hca, gor, borntraeger, mareklindner
Cc: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 7070 bytes --]
Hi Taehee,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on net-next/master]
url: https://github.com/0day-ci/linux/commits/Taehee-Yoo/mld-change-context-from-atomic-to-sleepable/20210214-015930
base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 3c5a2fd042d0bfac71a2dfb99515723d318df47b
config: x86_64-randconfig-s022-20210214 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce:
# apt-get install sparse
# sparse version: v0.6.3-215-g0fb77bb6-dirty
# https://github.com/0day-ci/linux/commit/5a21fa32b1401aa428cd0249ee5b02ddb12cff60
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Taehee-Yoo/mld-change-context-from-atomic-to-sleepable/20210214-015930
git checkout 5a21fa32b1401aa428cd0249ee5b02ddb12cff60
# save the attached .config to linux build tree
make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
"sparse warnings: (new ones prefixed by >>)"
>> net/ipv6/mcast.c:430:17: sparse: sparse: incompatible types in comparison expression (different address spaces):
>> net/ipv6/mcast.c:430:17: sparse: struct ip6_sf_socklist [noderef] __rcu *
>> net/ipv6/mcast.c:430:17: sparse: struct ip6_sf_socklist *
net/ipv6/mcast.c: note: in included file:
include/net/mld.h:32:43: sparse: sparse: array of flexible structures
net/ipv6/mcast.c:257:25: sparse: sparse: context imbalance in 'ip6_mc_find_dev_rcu' - different lock contexts for basic block
net/ipv6/mcast.c:447:9: sparse: sparse: context imbalance in 'ip6_mc_source' - unexpected unlock
net/ipv6/mcast.c:536:9: sparse: sparse: context imbalance in 'ip6_mc_msfilter' - unexpected unlock
net/ipv6/mcast.c:583:21: sparse: sparse: context imbalance in 'ip6_mc_msfget' - unexpected unlock
net/ipv6/mcast.c:2724:25: sparse: sparse: context imbalance in 'igmp6_mc_get_next' - unexpected unlock
net/ipv6/mcast.c:2746:9: sparse: sparse: context imbalance in 'igmp6_mc_get_idx' - wrong count at exit
net/ipv6/mcast.c:2773:9: sparse: sparse: context imbalance in 'igmp6_mc_seq_stop' - unexpected unlock
net/ipv6/mcast.c:2845:31: sparse: sparse: context imbalance in 'igmp6_mcf_get_next' - unexpected unlock
net/ipv6/mcast.c:2877:9: sparse: sparse: context imbalance in 'igmp6_mcf_get_idx' - wrong count at exit
net/ipv6/mcast.c:2894:9: sparse: sparse: context imbalance in 'igmp6_mcf_seq_next' - wrong count at exit
net/ipv6/mcast.c:2907:17: sparse: sparse: context imbalance in 'igmp6_mcf_seq_stop' - unexpected unlock
vim +430 net/ipv6/mcast.c
325
326 int ip6_mc_source(int add, int omode, struct sock *sk,
327 struct group_source_req *pgsr)
328 {
329 struct in6_addr *source, *group;
330 struct ipv6_mc_socklist *pmc;
331 struct inet6_dev *idev;
332 struct ipv6_pinfo *inet6 = inet6_sk(sk);
333 struct ip6_sf_socklist *psl;
334 struct net *net = sock_net(sk);
335 int i, j, rv;
336 int leavegroup = 0;
337 int err;
338
339 source = &((struct sockaddr_in6 *)&pgsr->gsr_source)->sin6_addr;
340 group = &((struct sockaddr_in6 *)&pgsr->gsr_group)->sin6_addr;
341
342 if (!ipv6_addr_is_multicast(group))
343 return -EINVAL;
344
345 rcu_read_lock();
346 idev = ip6_mc_find_dev_rcu(net, group, pgsr->gsr_interface);
347 if (!idev) {
348 rcu_read_unlock();
349 return -ENODEV;
350 }
351
352 err = -EADDRNOTAVAIL;
353
354 for_each_pmc_rcu(inet6, pmc) {
355 if (pgsr->gsr_interface && pmc->ifindex != pgsr->gsr_interface)
356 continue;
357 if (ipv6_addr_equal(&pmc->addr, group))
358 break;
359 }
360 if (!pmc) { /* must have a prior join */
361 err = -EINVAL;
362 goto done;
363 }
364 /* if a source filter was set, must be the same mode as before */
365 if (rcu_access_pointer(pmc->sflist)) {
366 if (pmc->sfmode != omode) {
367 err = -EINVAL;
368 goto done;
369 }
370 } else if (pmc->sfmode != omode) {
371 /* allow mode switches for empty-set filters */
372 ip6_mc_add_src(idev, group, omode, 0, NULL, 0);
373 ip6_mc_del_src(idev, group, pmc->sfmode, 0, NULL, 0);
374 pmc->sfmode = omode;
375 }
376
377 psl = rtnl_dereference(pmc->sflist);
378 if (!add) {
379 if (!psl)
380 goto done; /* err = -EADDRNOTAVAIL */
381 rv = !0;
382 for (i = 0; i < psl->sl_count; i++) {
383 rv = !ipv6_addr_equal(&psl->sl_addr[i], source);
384 if (rv == 0)
385 break;
386 }
387 if (rv) /* source not found */
388 goto done; /* err = -EADDRNOTAVAIL */
389
390 /* special case - (INCLUDE, empty) == LEAVE_GROUP */
391 if (psl->sl_count == 1 && omode == MCAST_INCLUDE) {
392 leavegroup = 1;
393 goto done;
394 }
395
396 /* update the interface filter */
397 ip6_mc_del_src(idev, group, omode, 1, source, 1);
398
399 for (j = i+1; j < psl->sl_count; j++)
400 psl->sl_addr[j-1] = psl->sl_addr[j];
401 psl->sl_count--;
402 err = 0;
403 goto done;
404 }
405 /* else, add a new source to the filter */
406
407 if (psl && psl->sl_count >= sysctl_mld_max_msf) {
408 err = -ENOBUFS;
409 goto done;
410 }
411 if (!psl || psl->sl_count == psl->sl_max) {
412 struct ip6_sf_socklist *newpsl;
413 int count = IP6_SFBLOCK;
414
415 if (psl)
416 count += psl->sl_max;
417 newpsl = sock_kmalloc(sk, IP6_SFLSIZE(count), GFP_ATOMIC);
418 if (!newpsl) {
419 err = -ENOBUFS;
420 goto done;
421 }
422 newpsl->sl_max = count;
423 newpsl->sl_count = count - IP6_SFBLOCK;
424 if (psl) {
425 for (i = 0; i < psl->sl_count; i++)
426 newpsl->sl_addr[i] = psl->sl_addr[i];
427 atomic_sub(IP6_SFLSIZE(psl->sl_max), &sk->sk_omem_alloc);
428 kfree_rcu(psl, rcu);
429 }
> 430 rcu_assign_pointer(psl, newpsl);
431 rcu_assign_pointer(pmc->sflist, psl);
432 }
433 rv = 1; /* > 0 for insert logic below if sl_count is 0 */
434 for (i = 0; i < psl->sl_count; i++) {
435 rv = !ipv6_addr_equal(&psl->sl_addr[i], source);
436 if (rv == 0) /* There is an error in the address. */
437 goto done;
438 }
439 for (j = psl->sl_count-1; j >= i; j--)
440 psl->sl_addr[j+1] = psl->sl_addr[j];
441 psl->sl_addr[i] = *source;
442 psl->sl_count++;
443 err = 0;
444 /* update the interface list */
445 ip6_mc_add_src(idev, group, omode, 1, source, 1);
446 done:
447 read_unlock_bh(&idev->lock);
448 rcu_read_unlock();
449 if (leavegroup)
450 err = ipv6_sock_mc_drop(sk, pgsr->gsr_interface, group);
451 return err;
452 }
453
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 32333 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH net-next v2 5/7] mld: convert ipv6_mc_socklist->sflist to RCU
2021-02-13 19:41 ` kernel test robot
@ 2021-02-14 11:32 ` Taehee Yoo
0 siblings, 0 replies; 3+ messages in thread
From: Taehee Yoo @ 2021-02-14 11:32 UTC (permalink / raw)
To: kernel test robot, davem, kuba, xiyou.wangcong, netdev, jwi,
kgraul, hca, gor, borntraeger, mareklindner
Cc: kbuild-all, ap420073
On 21. 2. 14. 오전 4:41, kernel test robot wrote:
> Hi Taehee,
>
> Thank you for the patch! Perhaps something to improve:
>
> [auto build test WARNING on net-next/master]
>
> url: https://github.com/0day-ci/linux/commits/Taehee-Yoo/mld-change-context-from-atomic-to-sleepable/20210214-015930
> base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 3c5a2fd042d0bfac71a2dfb99515723d318df47b
> config: x86_64-randconfig-s022-20210214 (attached as .config)
> compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
> reproduce:
> # apt-get install sparse
> # sparse version: v0.6.3-215-g0fb77bb6-dirty
> # https://github.com/0day-ci/linux/commit/5a21fa32b1401aa428cd0249ee5b02ddb12cff60
> git remote add linux-review https://github.com/0day-ci/linux
> git fetch --no-tags linux-review Taehee-Yoo/mld-change-context-from-atomic-to-sleepable/20210214-015930
> git checkout 5a21fa32b1401aa428cd0249ee5b02ddb12cff60
> # save the attached .config to linux build tree
> make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=x86_64
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp@intel.com>
>
>
> "sparse warnings: (new ones prefixed by >>)"
>>> net/ipv6/mcast.c:430:17: sparse: sparse: incompatible types in comparison expression (different address spaces):
>>> net/ipv6/mcast.c:430:17: sparse: struct ip6_sf_socklist [noderef] __rcu *
>>> net/ipv6/mcast.c:430:17: sparse: struct ip6_sf_socklist *
> net/ipv6/mcast.c: note: in included file:
> include/net/mld.h:32:43: sparse: sparse: array of flexible structures
> net/ipv6/mcast.c:257:25: sparse: sparse: context imbalance in 'ip6_mc_find_dev_rcu' - different lock contexts for basic block
> net/ipv6/mcast.c:447:9: sparse: sparse: context imbalance in 'ip6_mc_source' - unexpected unlock
> net/ipv6/mcast.c:536:9: sparse: sparse: context imbalance in 'ip6_mc_msfilter' - unexpected unlock
> net/ipv6/mcast.c:583:21: sparse: sparse: context imbalance in 'ip6_mc_msfget' - unexpected unlock
> net/ipv6/mcast.c:2724:25: sparse: sparse: context imbalance in 'igmp6_mc_get_next' - unexpected unlock
> net/ipv6/mcast.c:2746:9: sparse: sparse: context imbalance in 'igmp6_mc_get_idx' - wrong count at exit
> net/ipv6/mcast.c:2773:9: sparse: sparse: context imbalance in 'igmp6_mc_seq_stop' - unexpected unlock
> net/ipv6/mcast.c:2845:31: sparse: sparse: context imbalance in 'igmp6_mcf_get_next' - unexpected unlock
> net/ipv6/mcast.c:2877:9: sparse: sparse: context imbalance in 'igmp6_mcf_get_idx' - wrong count at exit
> net/ipv6/mcast.c:2894:9: sparse: sparse: context imbalance in 'igmp6_mcf_seq_next' - wrong count at exit
> net/ipv6/mcast.c:2907:17: sparse: sparse: context imbalance in 'igmp6_mcf_seq_stop' - unexpected unlock
>
> vim +430 net/ipv6/mcast.c
>
> 325
> 326 int ip6_mc_source(int add, int omode, struct sock *sk,
> 327 struct group_source_req *pgsr)
> 328 {
> 329 struct in6_addr *source, *group;
> 330 struct ipv6_mc_socklist *pmc;
> 331 struct inet6_dev *idev;
> 332 struct ipv6_pinfo *inet6 = inet6_sk(sk);
> 333 struct ip6_sf_socklist *psl;
> 334 struct net *net = sock_net(sk);
> 335 int i, j, rv;
> 336 int leavegroup = 0;
> 337 int err;
> 338
> 339 source = &((struct sockaddr_in6 *)&pgsr->gsr_source)->sin6_addr;
> 340 group = &((struct sockaddr_in6 *)&pgsr->gsr_group)->sin6_addr;
> 341
> 342 if (!ipv6_addr_is_multicast(group))
> 343 return -EINVAL;
> 344
> 345 rcu_read_lock();
> 346 idev = ip6_mc_find_dev_rcu(net, group, pgsr->gsr_interface);
> 347 if (!idev) {
> 348 rcu_read_unlock();
> 349 return -ENODEV;
> 350 }
> 351
> 352 err = -EADDRNOTAVAIL;
> 353
> 354 for_each_pmc_rcu(inet6, pmc) {
> 355 if (pgsr->gsr_interface && pmc->ifindex != pgsr->gsr_interface)
> 356 continue;
> 357 if (ipv6_addr_equal(&pmc->addr, group))
> 358 break;
> 359 }
> 360 if (!pmc) { /* must have a prior join */
> 361 err = -EINVAL;
> 362 goto done;
> 363 }
> 364 /* if a source filter was set, must be the same mode as before */
> 365 if (rcu_access_pointer(pmc->sflist)) {
> 366 if (pmc->sfmode != omode) {
> 367 err = -EINVAL;
> 368 goto done;
> 369 }
> 370 } else if (pmc->sfmode != omode) {
> 371 /* allow mode switches for empty-set filters */
> 372 ip6_mc_add_src(idev, group, omode, 0, NULL, 0);
> 373 ip6_mc_del_src(idev, group, pmc->sfmode, 0, NULL, 0);
> 374 pmc->sfmode = omode;
> 375 }
> 376
> 377 psl = rtnl_dereference(pmc->sflist);
> 378 if (!add) {
> 379 if (!psl)
> 380 goto done; /* err = -EADDRNOTAVAIL */
> 381 rv = !0;
> 382 for (i = 0; i < psl->sl_count; i++) {
> 383 rv = !ipv6_addr_equal(&psl->sl_addr[i], source);
> 384 if (rv == 0)
> 385 break;
> 386 }
> 387 if (rv) /* source not found */
> 388 goto done; /* err = -EADDRNOTAVAIL */
> 389
> 390 /* special case - (INCLUDE, empty) == LEAVE_GROUP */
> 391 if (psl->sl_count == 1 && omode == MCAST_INCLUDE) {
> 392 leavegroup = 1;
> 393 goto done;
> 394 }
> 395
> 396 /* update the interface filter */
> 397 ip6_mc_del_src(idev, group, omode, 1, source, 1);
> 398
> 399 for (j = i+1; j < psl->sl_count; j++)
> 400 psl->sl_addr[j-1] = psl->sl_addr[j];
> 401 psl->sl_count--;
> 402 err = 0;
> 403 goto done;
> 404 }
> 405 /* else, add a new source to the filter */
> 406
> 407 if (psl && psl->sl_count >= sysctl_mld_max_msf) {
> 408 err = -ENOBUFS;
> 409 goto done;
> 410 }
> 411 if (!psl || psl->sl_count == psl->sl_max) {
> 412 struct ip6_sf_socklist *newpsl;
> 413 int count = IP6_SFBLOCK;
> 414
> 415 if (psl)
> 416 count += psl->sl_max;
> 417 newpsl = sock_kmalloc(sk, IP6_SFLSIZE(count), GFP_ATOMIC);
> 418 if (!newpsl) {
> 419 err = -ENOBUFS;
> 420 goto done;
> 421 }
> 422 newpsl->sl_max = count;
> 423 newpsl->sl_count = count - IP6_SFBLOCK;
> 424 if (psl) {
> 425 for (i = 0; i < psl->sl_count; i++)
> 426 newpsl->sl_addr[i] = psl->sl_addr[i];
> 427 atomic_sub(IP6_SFLSIZE(psl->sl_max), &sk->sk_omem_alloc);
> 428 kfree_rcu(psl, rcu);
> 429 }
> > 430 rcu_assign_pointer(psl, newpsl);
> 431 rcu_assign_pointer(pmc->sflist, psl);
> 432 }
> 433 rv = 1; /* > 0 for insert logic below if sl_count is 0 */
> 434 for (i = 0; i < psl->sl_count; i++) {
> 435 rv = !ipv6_addr_equal(&psl->sl_addr[i], source);
> 436 if (rv == 0) /* There is an error in the address. */
> 437 goto done;
> 438 }
> 439 for (j = psl->sl_count-1; j >= i; j--)
> 440 psl->sl_addr[j+1] = psl->sl_addr[j];
> 441 psl->sl_addr[i] = *source;
> 442 psl->sl_count++;
> 443 err = 0;
> 444 /* update the interface list */
> 445 ip6_mc_add_src(idev, group, omode, 1, source, 1);
> 446 done:
> 447 read_unlock_bh(&idev->lock);
> 448 rcu_read_unlock();
> 449 if (leavegroup)
> 450 err = ipv6_sock_mc_drop(sk, pgsr->gsr_interface, group);
> 451 return err;
> 452 }
> 453
>
> ---
> 0-DAY CI Kernel Test Service, Intel Corporation
> https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
>
I will add __rcu annotation in a v3 patch to avoid sparse warning.
Thanks!
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2021-02-14 11:33 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-13 17:52 [PATCH net-next v2 5/7] mld: convert ipv6_mc_socklist->sflist to RCU Taehee Yoo
2021-02-13 19:41 ` kernel test robot
2021-02-14 11:32 ` Taehee Yoo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).