Author: rwatson
Date: Fri Aug 28 21:10:26 2009
New Revision: 196630
URL: http://svn.freebsd.org/changeset/base/196630

Log:
  Merge r196535 from head to stable/8:
  
    Use locks specific to the lltable code, rather than borrow the ifnet
    list/index locks, to protect link layer address tables.  This avoids
    lock order issues during interface teardown, but maintains the bug that
    sysctl copy routines may be called while a non-sleepable lock is held.
  
    Reviewed by:  bz, kmacy, qingli
  
  Approved by:  re (kib)

Modified:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)
  stable/8/sys/net/if_llatbl.c
  stable/8/sys/net/if_llatbl.h
  stable/8/sys/netinet/in.c
  stable/8/sys/netinet6/in6.c

Modified: stable/8/sys/net/if_llatbl.c
==============================================================================
--- stable/8/sys/net/if_llatbl.c        Fri Aug 28 21:07:43 2009        
(r196629)
+++ stable/8/sys/net/if_llatbl.c        Fri Aug 28 21:10:26 2009        
(r196630)
@@ -62,6 +62,9 @@ static        SLIST_HEAD(, lltable) lltables = 
 extern void arprequest(struct ifnet *, struct in_addr *, struct in_addr *,
        u_char *);
 
+struct rwlock lltable_rwlock;
+RW_SYSINIT(lltable_rwlock, &lltable_rwlock, "lltable_rwlock");
+
 /*
  * Dump arp state for a specific address family.
  */
@@ -71,7 +74,7 @@ lltable_sysctl_dumparp(int af, struct sy
        struct lltable *llt;
        int error = 0;
 
-       IFNET_RLOCK();
+       LLTABLE_RLOCK();
        SLIST_FOREACH(llt, &lltables, llt_link) {
                if (llt->llt_af == af) {
                        error = llt->llt_dump(llt, wr);
@@ -80,7 +83,7 @@ lltable_sysctl_dumparp(int af, struct sy
                }
        }
 done:
-       IFNET_RUNLOCK();
+       LLTABLE_RUNLOCK();
        return (error);
 }
 
@@ -144,8 +147,6 @@ llentry_update(struct llentry **llep, st
 
 /*
  * Free all entries from given table and free itself.
- * Since lltables collects from all of the intefaces,
- * the caller of this function must acquire IFNET_WLOCK().
  */
 void
 lltable_free(struct lltable *llt)
@@ -155,9 +156,9 @@ lltable_free(struct lltable *llt)
 
        KASSERT(llt != NULL, ("%s: llt is NULL", __func__));
 
-       IFNET_WLOCK();
+       LLTABLE_WLOCK();
        SLIST_REMOVE(&lltables, llt, lltable, llt_link);
-       IFNET_WUNLOCK();
+       LLTABLE_WUNLOCK();
 
        for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
                LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
@@ -178,7 +179,7 @@ lltable_drain(int af)
        struct llentry  *lle;
        register int i;
 
-       IFNET_RLOCK();
+       LLTABLE_RLOCK();
        SLIST_FOREACH(llt, &lltables, llt_link) {
                if (llt->llt_af != af)
                        continue;
@@ -192,7 +193,7 @@ lltable_drain(int af)
                        }
                }
        }
-       IFNET_RUNLOCK();
+       LLTABLE_RUNLOCK();
 }
 
 void
@@ -200,14 +201,14 @@ lltable_prefix_free(int af, struct socka
 {
        struct lltable *llt;
 
-       IFNET_RLOCK_NOSLEEP();
+       LLTABLE_RLOCK();
        SLIST_FOREACH(llt, &lltables, llt_link) {
                if (llt->llt_af != af)
                        continue;
 
                llt->llt_prefix_free(llt, prefix, mask);
        }
-       IFNET_RUNLOCK_NOSLEEP();
+       LLTABLE_RUNLOCK();
 }
 
 
@@ -230,9 +231,9 @@ lltable_init(struct ifnet *ifp, int af)
        for (i = 0; i < LLTBL_HASHTBL_SIZE; i++)
                LIST_INIT(&llt->lle_head[i]);
 
-       IFNET_WLOCK();
+       LLTABLE_WLOCK();
        SLIST_INSERT_HEAD(&lltables, llt, llt_link);
-       IFNET_WUNLOCK();
+       LLTABLE_WUNLOCK();
 
        return (llt);
 }
@@ -300,13 +301,13 @@ lla_rt_output(struct rt_msghdr *rtm, str
        }
 
        /* XXX linked list may be too expensive */
-       IFNET_RLOCK_NOSLEEP();
+       LLTABLE_RLOCK();
        SLIST_FOREACH(llt, &lltables, llt_link) {
                if (llt->llt_af == dst->sa_family &&
                    llt->llt_ifp == ifp)
                        break;
        }
-       IFNET_RUNLOCK_NOSLEEP();
+       LLTABLE_RUNLOCK();
        KASSERT(llt != NULL, ("Yep, ugly hacks are bad\n"));
 
        if (flags && LLE_CREATE)

Modified: stable/8/sys/net/if_llatbl.h
==============================================================================
--- stable/8/sys/net/if_llatbl.h        Fri Aug 28 21:07:43 2009        
(r196629)
+++ stable/8/sys/net/if_llatbl.h        Fri Aug 28 21:10:26 2009        
(r196630)
@@ -41,6 +41,13 @@ struct rt_addrinfo;
 struct llentry;
 LIST_HEAD(llentries, llentry);
 
+extern struct rwlock lltable_rwlock;
+#define        LLTABLE_RLOCK()         rw_rlock(&lltable_rwlock)
+#define        LLTABLE_RUNLOCK()       rw_runlock(&lltable_rwlock)
+#define        LLTABLE_WLOCK()         rw_wlock(&lltable_rwlock)
+#define        LLTABLE_WUNLOCK()       rw_wunlock(&lltable_rwlock)
+#define        LLTABLE_LOCK_ASSERT()   rw_assert(&lltable_rwlock, RA_LOCKED)
+
 /*
  * Code referencing llentry must at least hold
  * a shared lock

Modified: stable/8/sys/netinet/in.c
==============================================================================
--- stable/8/sys/netinet/in.c   Fri Aug 28 21:07:43 2009        (r196629)
+++ stable/8/sys/netinet/in.c   Fri Aug 28 21:10:26 2009        (r196630)
@@ -1407,7 +1407,7 @@ in_lltable_dump(struct lltable *llt, str
        } arpc;
        int error, i;
 
-       IFNET_RLOCK_ASSERT();
+       LLTABLE_LOCK_ASSERT();
 
        error = 0;
        for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {

Modified: stable/8/sys/netinet6/in6.c
==============================================================================
--- stable/8/sys/netinet6/in6.c Fri Aug 28 21:07:43 2009        (r196629)
+++ stable/8/sys/netinet6/in6.c Fri Aug 28 21:10:26 2009        (r196630)
@@ -2495,7 +2495,7 @@ in6_lltable_dump(struct lltable *llt, st
        } ndpc;
        int i, error;
 
-       IFNET_RLOCK_ASSERT();
+       LLTABLE_LOCK_ASSERT();
 
        error = 0;
        for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to