Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netinet6 Improve atomicity of in6_leavegroup and in6_del...



details:   https://anonhg.NetBSD.org/src/rev/186f796e0892
branches:  trunk
changeset: 319414:186f796e0892
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Tue May 29 04:36:47 2018 +0000

description:
Improve atomicity of in6_leavegroup and in6_delmulti

diffstat:

 sys/netinet6/in6_var.h |   3 ++-
 sys/netinet6/mld6.c    |  25 +++++++++++++++++--------
 2 files changed, 19 insertions(+), 9 deletions(-)

diffs (83 lines):

diff -r 94fa64a975eb -r 186f796e0892 sys/netinet6/in6_var.h
--- a/sys/netinet6/in6_var.h    Tue May 29 04:36:15 2018 +0000
+++ b/sys/netinet6/in6_var.h    Tue May 29 04:36:47 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6_var.h,v 1.98 2018/04/19 21:22:02 christos Exp $    */
+/*     $NetBSD: in6_var.h,v 1.99 2018/05/29 04:36:47 ozaki-r Exp $     */
 /*     $KAME: in6_var.h,v 1.81 2002/06/08 11:16:51 itojun Exp $        */
 
 /*
@@ -691,6 +691,7 @@
 struct in6_multi *in6_addmulti(struct in6_addr *, struct ifnet *,
        int *, int);
 void   in6_delmulti(struct in6_multi *);
+void   in6_delmulti_locked(struct in6_multi *);
 struct in6_multi_mship *in6_joingroup(struct ifnet *, struct in6_addr *,
        int *, int);
 int    in6_leavegroup(struct in6_multi_mship *);
diff -r 94fa64a975eb -r 186f796e0892 sys/netinet6/mld6.c
--- a/sys/netinet6/mld6.c       Tue May 29 04:36:15 2018 +0000
+++ b/sys/netinet6/mld6.c       Tue May 29 04:36:47 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mld6.c,v 1.94 2018/05/29 04:36:15 ozaki-r Exp $        */
+/*     $NetBSD: mld6.c,v 1.95 2018/05/29 04:36:47 ozaki-r Exp $        */
 /*     $KAME: mld6.c,v 1.25 2001/01/16 14:14:18 itojun Exp $   */
 
 /*
@@ -102,7 +102,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mld6.c,v 1.94 2018/05/29 04:36:15 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mld6.c,v 1.95 2018/05/29 04:36:47 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -815,12 +815,12 @@
  * Delete a multicast address record.
  */
 void
-in6_delmulti(struct in6_multi *in6m)
+in6_delmulti_locked(struct in6_multi *in6m)
 {
 
+       KASSERT(rw_write_held(&in6_multilock));
        KASSERT(in6m->in6m_refcount > 0);
 
-       rw_enter(&in6_multilock, RW_WRITER);
        /*
         * The caller should have a reference to in6m. So we don't need to care
         * of releasing the lock in mld_stoptimer.
@@ -828,6 +828,14 @@
        mld_stoptimer(in6m);
        if (--in6m->in6m_refcount == 0)
                in6m_destroy(in6m);
+}
+
+void
+in6_delmulti(struct in6_multi *in6m)
+{
+
+       rw_enter(&in6_multilock, RW_WRITER);
+       in6_delmulti_locked(in6m);
        rw_exit(&in6_multilock);
 }
 
@@ -937,12 +945,13 @@
 {
        struct in6_multi *in6m;
 
-       rw_enter(&in6_multilock, RW_READER);
+       rw_enter(&in6_multilock, RW_WRITER);
        in6m = imm->i6mm_maddr;
+       imm->i6mm_maddr = NULL;
+       if (in6m != NULL) {
+               in6_delmulti_locked(in6m);
+       }
        rw_exit(&in6_multilock);
-       if (in6m != NULL) {
-               in6_delmulti(in6m);
-       }
        free(imm, M_IPMADDR);
        return 0;
 }



Home | Main Index | Thread Index | Old Index