svn commit: r274917 - in projects/routing/sys: net netinet netinet6
Alexander V. Chernikov
melifaro at FreeBSD.org
Sun Nov 23 15:38:10 UTC 2014
Author: melifaro
Date: Sun Nov 23 15:38:06 2014
New Revision: 274917
URL: https://svnweb.freebsd.org/changeset/base/274917
Log:
Do more fine-grained lltable locking: use table runtime lock as rare
as we can.
Modified:
projects/routing/sys/net/if.c
projects/routing/sys/net/if_llatbl.c
projects/routing/sys/net/if_var.h
projects/routing/sys/net/rt_nhops.c
projects/routing/sys/netinet/if_ether.c
projects/routing/sys/netinet/in.c
projects/routing/sys/netinet/toecore.c
projects/routing/sys/netinet6/in6.c
projects/routing/sys/netinet6/nd6.c
projects/routing/sys/netinet6/scope6.c
Modified: projects/routing/sys/net/if.c
==============================================================================
--- projects/routing/sys/net/if.c Sun Nov 23 12:15:28 2014 (r274916)
+++ projects/routing/sys/net/if.c Sun Nov 23 15:38:06 2014 (r274917)
@@ -774,16 +774,16 @@ if_attachdomain1(struct ifnet *ifp)
* Since dp->dom_ifattach calls malloc() with M_WAITOK, we
* cannot lock ifp->if_afdata initialization, entirely.
*/
- if (IF_AFDATA_TRY_WLOCK(ifp) == 0)
+ if (IF_AFDATA_CFG_TRY_WLOCK(ifp) == 0)
return;
if (ifp->if_afdata_initialized >= domain_init_status) {
- IF_AFDATA_UNLOCK(ifp);
+ IF_AFDATA_CFG_WUNLOCK(ifp);
log(LOG_WARNING, "%s called more than once on %s\n",
__func__, ifp->if_xname);
return;
}
ifp->if_afdata_initialized = domain_init_status;
- IF_AFDATA_UNLOCK(ifp);
+ IF_AFDATA_CFG_WUNLOCK(ifp);
/* address family dependent data region */
bzero(ifp->if_afdata, sizeof(ifp->if_afdata));
@@ -961,10 +961,10 @@ if_detach_internal(struct ifnet *ifp, in
* sleep, for example trying to drain a callout, thus open up the
* theoretical race with re-attaching.
*/
- IF_AFDATA_LOCK(ifp);
+ IF_AFDATA_CFG_WLOCK(ifp);
i = ifp->if_afdata_initialized;
ifp->if_afdata_initialized = 0;
- IF_AFDATA_UNLOCK(ifp);
+ IF_AFDATA_CFG_WUNLOCK(ifp);
for (dp = domains; i > 0 && dp; dp = dp->dom_next) {
if (dp->dom_ifdetach && ifp->if_afdata[dp->dom_family])
(*dp->dom_ifdetach)(ifp,
@@ -3967,36 +3967,10 @@ if_afdata_cfg_wunlock(struct ifnet *ifp)
rw_wunlock(&ifp->if_afdata_cfg_lock);
}
-void
-if_afdata_cfg_lock_assert(struct ifnet *ifp, int what)
-{
-
- rw_assert(&ifp->if_afdata_cfg_lock, what);
-}
-
-void
-if_afdata_wlock(struct ifnet *ifp)
-{
-
- if_afdata_cfg_wlock(ifp);
- IF_AFDATA_RUN_WLOCK(ifp);
-}
-
-void
-if_afdata_wunlock(struct ifnet *ifp)
-{
-
- if_afdata_cfg_wunlock(ifp);
- IF_AFDATA_RUN_WUNLOCK(ifp);
-}
-
int
-if_afdata_try_wlock(struct ifnet *ifp)
+if_afdata_cfg_try_wlock(struct ifnet *ifp)
{
- if (rw_try_wlock(&ifp->if_afdata_cfg_lock) == 0)
- return (0);
- IF_AFDATA_RUN_WLOCK(ifp);
- return (1);
+ return (rw_try_wlock(&ifp->if_afdata_cfg_lock));
}
Modified: projects/routing/sys/net/if_llatbl.c
==============================================================================
--- projects/routing/sys/net/if_llatbl.c Sun Nov 23 12:15:28 2014 (r274916)
+++ projects/routing/sys/net/if_llatbl.c Sun Nov 23 15:38:06 2014 (r274917)
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/rwlock.h>
+#include <sys/rmlock.h>
#ifdef DDB
#include <ddb/ddb.h>
@@ -99,6 +100,11 @@ llentry_link(struct lltable *llt, struct
struct llentries *lleh;
uint32_t hashkey;
+ if ((lle->la_flags & LLE_LINKED) != 0)
+ return;
+
+ IF_AFDATA_RUN_WLOCK_ASSERT(llt->llt_ifp);
+
hashkey = llt->llt_hash(lle);
lleh = &llt->lle_head[LLATBL_HASH(hashkey, LLTBL_HASHMASK)];
@@ -112,10 +118,13 @@ void
llentry_unlink(struct llentry *lle)
{
- LIST_REMOVE(lle, lle_next);
- lle->la_flags &= ~(LLE_VALID | LLE_LINKED);
- lle->lle_tbl = NULL;
- lle->lle_head = NULL;
+ if ((lle->la_flags & LLE_LINKED) != 0) {
+ IF_AFDATA_RUN_WLOCK_ASSERT(lle->lle_tbl->llt_ifp);
+ LIST_REMOVE(lle, lle_next);
+ lle->la_flags &= ~(LLE_VALID | LLE_LINKED);
+ lle->lle_tbl = NULL;
+ lle->lle_head = NULL;
+ }
}
void
@@ -143,12 +152,7 @@ llentry_free(struct llentry *lle)
struct mbuf *next;
LLE_WLOCK_ASSERT(lle);
-
- if ((lle->la_flags & LLE_LINKED) != 0) {
- IF_AFDATA_WLOCK_ASSERT(lle->lle_tbl->llt_ifp);
- LIST_REMOVE(lle, lle_next);
- lle->la_flags &= ~(LLE_VALID | LLE_LINKED);
- }
+ KASSERT((lle->la_flags & LLE_LINKED) == 0, ("Freeing linked lle"));
pkts_dropped = 0;
while ((lle->la_numheld > 0) && (lle->la_hold != NULL)) {
@@ -172,6 +176,8 @@ llentry_free(struct llentry *lle)
* (al)locate an llentry for address dst (equivalent to rtalloc for new-arp).
*
* If found the llentry * is returned referenced and unlocked.
+ *
+ * XXX: Remove after converting flowtable
*/
struct llentry *
llentry_alloc(struct ifnet *ifp, struct lltable *lt,
@@ -184,9 +190,14 @@ llentry_alloc(struct ifnet *ifp, struct
IF_AFDATA_RUNLOCK(ifp);
if ((la == NULL) &&
(ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) == 0) {
- IF_AFDATA_WLOCK(ifp);
+ IF_AFDATA_CFG_WLOCK(ifp);
la = lla_create(lt, 0, (struct sockaddr *)dst);
- IF_AFDATA_WUNLOCK(ifp);
+ if (la != NULL) {
+ IF_AFDATA_RUN_WLOCK(ifp);
+ llentry_link(lt, la);
+ IF_AFDATA_RUN_WUNLOCK(ifp);
+ }
+ IF_AFDATA_CFG_WUNLOCK(ifp);
}
if (la != NULL) {
@@ -204,6 +215,7 @@ void
lltable_free(struct lltable *llt)
{
struct llentry *lle, *next;
+ struct llentries dchain;
int i;
KASSERT(llt != NULL, ("%s: llt is NULL", __func__));
@@ -212,7 +224,8 @@ lltable_free(struct lltable *llt)
SLIST_REMOVE(&V_lltables, llt, lltable, llt_link);
LLTABLE_WUNLOCK();
- IF_AFDATA_WLOCK(llt->llt_ifp);
+ LIST_INIT(&dchain);
+ IF_AFDATA_CFG_WLOCK(llt->llt_ifp);
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
LLE_WLOCK(lle);
@@ -220,10 +233,15 @@ lltable_free(struct lltable *llt)
LLE_REMREF(lle);
lle->la_flags &= ~LLE_CALLOUTREF;
}
- llentry_free(lle);
+ LIST_INSERT_HEAD(&dchain, lle, lle_chain);
}
}
- IF_AFDATA_WUNLOCK(llt->llt_ifp);
+ IF_AFDATA_RUN_WLOCK(llt->llt_ifp);
+ llentries_unlink(&dchain);
+ IF_AFDATA_RUN_WUNLOCK(llt->llt_ifp);
+ LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next)
+ llentry_free(lle);
+ IF_AFDATA_CFG_WUNLOCK(llt->llt_ifp);
free(llt, M_LLTABLE);
}
@@ -337,14 +355,15 @@ lla_rt_output(struct rt_msghdr *rtm, str
switch (rtm->rtm_type) {
case RTM_ADD:
/* Add static LLE */
- IF_AFDATA_WLOCK(ifp);
+ IF_AFDATA_CFG_WLOCK(ifp);
lle = lla_create(llt, 0, dst);
if (lle == NULL) {
- IF_AFDATA_WUNLOCK(ifp);
+ IF_AFDATA_CFG_WUNLOCK(ifp);
return (ENOMEM);
}
+ IF_AFDATA_RUN_WLOCK(ifp);
bcopy(LLADDR(dl), &lle->ll_addr, ifp->if_addrlen);
if ((rtm->rtm_flags & RTF_ANNOUNCE))
lle->la_flags |= LLE_PUB;
@@ -366,9 +385,11 @@ lla_rt_output(struct rt_msghdr *rtm, str
lle->la_expire = 0;
} else
lle->la_expire = rtm->rtm_rmx.rmx_expire;
+ llentry_link(llt, lle);
+ IF_AFDATA_RUN_WUNLOCK(ifp);
laflags = lle->la_flags;
LLE_WUNLOCK(lle);
- IF_AFDATA_WUNLOCK(ifp);
+ IF_AFDATA_CFG_WUNLOCK(ifp);
#ifdef INET
/* gratuitous ARP */
if ((laflags & LLE_PUB) && dst->sa_family == AF_INET)
@@ -381,9 +402,9 @@ lla_rt_output(struct rt_msghdr *rtm, str
break;
case RTM_DELETE:
- IF_AFDATA_WLOCK(ifp);
+ IF_AFDATA_CFG_WLOCK(ifp);
error = lla_delete(llt, 0, dst);
- IF_AFDATA_WUNLOCK(ifp);
+ IF_AFDATA_CFG_WUNLOCK(ifp);
return (error == 0 ? 0 : ENOENT);
default:
Modified: projects/routing/sys/net/if_var.h
==============================================================================
--- projects/routing/sys/net/if_var.h Sun Nov 23 12:15:28 2014 (r274916)
+++ projects/routing/sys/net/if_var.h Sun Nov 23 15:38:06 2014 (r274917)
@@ -355,17 +355,26 @@ EVENTHANDLER_DECLARE(group_change_event,
#define IF_AFDATA_CFG_RUNLOCK(ifp) if_afdata_cfg_runlock(ifp)
#define IF_AFDATA_CFG_WLOCK(ifp) if_afdata_cfg_wlock(ifp)
#define IF_AFDATA_CFG_WUNLOCK(ifp) if_afdata_cfg_wunlock(ifp)
+#define IF_AFDATA_CFG_TRY_WLOCK(ifp) if_afdata_cfg_try_wlock(ifp)
#define IF_AFDATA_CFG_LOCK_ASSERT(i) if_afdata_cfg_lock_assert(i, RA_LOCKED)
#define IF_AFDATA_CFG_RLOCK_ASSERT(i) if_afdata_cfg_lock_assert(i, RA_RLOCKED)
#define IF_AFDATA_CFG_WLOCK_ASSERT(i) if_afdata_cfg_lock_assert(i, RA_WLOCKED)
#define IF_AFDATA_CFG_UNLOCK_ASSERT(i) if_afdata_cfg_lock_assert(i,RA_UNLOCKED)
+#define if_afdata_cfg_lock_assert(ifp, what) \
+ rw_assert(&(ifp)->if_afdata_cfg_lock, what)
+
void if_afdata_cfg_rlock(struct ifnet *ifp);
void if_afdata_cfg_runlock(struct ifnet *ifp);
void if_afdata_cfg_wlock(struct ifnet *ifp);
void if_afdata_cfg_wunlock(struct ifnet *ifp);
-void if_afdata_cfg_lock_assert(struct ifnet *ifp, int what);
+int if_afdata_cfg_try_wlock(struct ifnet *ifp);
+
+/* Wrappers */
+#define IF_AFDATA_RLOCK IF_AFDATA_CFG_RLOCK
+#define IF_AFDATA_RUNLOCK IF_AFDATA_CFG_RUNLOCK
+
/* if_afdata lock: fast path */
#define IF_AFDATA_RUN_WLOCK(ifp) rm_wlock(&(ifp)->if_afdata_run_lock)
@@ -376,23 +385,8 @@ void if_afdata_cfg_lock_assert(struct if
rm_runlock(&(ifp)->if_afdata_run_lock, &if_afdata_tracker)
#define IF_AFDATA_RUN_TRACKER struct rm_priotracker if_afdata_tracker
-/* Common wrappers */
-#define IF_AFDATA_RLOCK(ifp) IF_AFDATA_CFG_RLOCK(ifp)
-#define IF_AFDATA_RUNLOCK(ifp) IF_AFDATA_CFG_RUNLOCK(ifp)
-#define IF_AFDATA_WLOCK(ifp) if_afdata_wlock(ifp)
-#define IF_AFDATA_WUNLOCK(ifp) if_afdata_wunlock(ifp)
-
-#define IF_AFDATA_TRY_WLOCK(ifp) if_afdata_try_wlock(ifp)
-#define IF_AFDATA_LOCK(ifp) IF_AFDATA_WLOCK(ifp)
-#define IF_AFDATA_UNLOCK(ifp) IF_AFDATA_WUNLOCK(ifp)
-void if_afdata_wlock(struct ifnet *ifp);
-void if_afdata_wunlock(struct ifnet *ifp);
-int if_afdata_try_wlock(struct ifnet *ifp);
-
-#define IF_AFDATA_LOCK_ASSERT(ifp) IF_AFDATA_CFG_LOCK_ASSERT(ifp)
-#define IF_AFDATA_RLOCK_ASSERT(ifp) IF_AFDATA_CFG_RLOCK_ASSERT(ifp)
-#define IF_AFDATA_WLOCK_ASSERT(ifp) IF_AFDATA_CFG_WLOCK_ASSERT(ifp)
-#define IF_AFDATA_UNLOCK_ASSERT(ifp) IF_AFDATA_CFG_UNLOCK_ASSERT(ifp)
+#define IF_AFDATA_RUN_WLOCK_ASSERT(ifp) \
+ rm_assert(&(ifp)->if_afdata_run_lock, RA_WLOCKED)
/*
* 72 was chosen below because it is the size of a TCP/IP
Modified: projects/routing/sys/net/rt_nhops.c
==============================================================================
--- projects/routing/sys/net/rt_nhops.c Sun Nov 23 12:15:28 2014 (r274916)
+++ projects/routing/sys/net/rt_nhops.c Sun Nov 23 15:38:06 2014 (r274917)
@@ -699,7 +699,7 @@ fib6_storelladdr(struct ifnet *ifp, stru
* the entry should have been created in nd6_store_lladdr
*/
IF_AFDATA_RUN_RLOCK(ifp);
- ln = lla_lookup(LLTABLE6(ifp), 0, (struct sockaddr *)&dst_sa);
+ ln = lla_lookup(LLTABLE6(ifp), LLE_UNLOCKED, (struct sockaddr *)&dst_sa);
/*
* Perform fast path for the following cases:
Modified: projects/routing/sys/netinet/if_ether.c
==============================================================================
--- projects/routing/sys/netinet/if_ether.c Sun Nov 23 12:15:28 2014 (r274916)
+++ projects/routing/sys/netinet/if_ether.c Sun Nov 23 15:38:06 2014 (r274917)
@@ -164,9 +164,9 @@ arp_ifscrub(struct ifnet *ifp, uint32_t
addr4.sin_len = sizeof(addr4);
addr4.sin_family = AF_INET;
addr4.sin_addr.s_addr = addr;
- IF_AFDATA_WLOCK(ifp);
+ IF_AFDATA_CFG_WLOCK(ifp);
lla_delete(LLTABLE(ifp), LLE_IFADDR, (struct sockaddr *)&addr4);
- IF_AFDATA_WUNLOCK(ifp);
+ IF_AFDATA_CFG_WUNLOCK(ifp);
}
#endif
@@ -247,7 +247,7 @@ arptimer(void *arg)
/* XXX: LOR avoidance. We still have ref on lle. */
LLE_WUNLOCK(lle);
- IF_AFDATA_LOCK(ifp);
+ IF_AFDATA_CFG_WLOCK(ifp);
LLE_WLOCK(lle);
/*
@@ -262,7 +262,7 @@ arptimer(void *arg)
pkts_dropped = llentry_free(lle);
ARPSTAT_ADD(dropped, pkts_dropped);
- IF_AFDATA_UNLOCK(ifp);
+ IF_AFDATA_CFG_WUNLOCK(ifp);
ARPSTAT_INC(timeouts);
@@ -492,9 +492,14 @@ arpresolve_slow(struct ifnet *ifp, int i
IF_AFDATA_RUNLOCK(ifp);
if (la == NULL && (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) == 0) {
create = 1;
- IF_AFDATA_WLOCK(ifp);
+ IF_AFDATA_CFG_WLOCK(ifp);
la = lla_create(LLTABLE(ifp), 0, dst);
- IF_AFDATA_WUNLOCK(ifp);
+ if (la != NULL) {
+ IF_AFDATA_RUN_WLOCK(ifp);
+ llentry_link(LLTABLE(ifp), la);
+ IF_AFDATA_RUN_WUNLOCK(ifp);
+ }
+ IF_AFDATA_CFG_WUNLOCK(ifp);
}
if (la == NULL) {
if (create != 0)
@@ -508,6 +513,7 @@ arpresolve_slow(struct ifnet *ifp, int i
if ((la->la_flags & LLE_VALID) &&
((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime)) {
bcopy(&la->ll_addr, desten, ifp->if_addrlen);
+#if 0
/*
* If entry has an expiry time and it is approaching,
* see if we need to send an ARP request within this
@@ -518,7 +524,7 @@ arpresolve_slow(struct ifnet *ifp, int i
arprequest(ifp, NULL, &SIN(dst)->sin_addr, NULL);
la->la_preempt--;
}
-
+#endif
*lle = la;
error = 0;
goto done;
@@ -851,15 +857,15 @@ match:
sin.sin_addr = isaddr;
create = (itaddr.s_addr == myaddr.s_addr) ? 1 : 0;
flags = LLE_EXCLUSIVE;
- IF_AFDATA_LOCK(ifp);
- if (create != 0)
+ IF_AFDATA_CFG_WLOCK(ifp);
+ if (create != 0) {
la = lla_create(LLTABLE(ifp), 0, (struct sockaddr *)&sin);
- else
+ } else
la = lla_lookup(LLTABLE(ifp), flags, (struct sockaddr *)&sin);
- IF_AFDATA_UNLOCK(ifp);
+ IF_AFDATA_CFG_WUNLOCK(ifp);
if (la != NULL) {
/* the following is not an error when doing bridging */
- if (!bridged && la->lle_tbl->llt_ifp != ifp) {
+ if (!bridged && la->lle_tbl && la->lle_tbl->llt_ifp != ifp) {
if (log_arp_wrong_iface)
ARP_LOG(LOG_WARNING, "%s is on %s "
"but got reply from %*D on %s\n",
@@ -910,17 +916,20 @@ match:
/* use afdata WLOCK to update fields */
LLE_ADDREF(la);
LLE_WUNLOCK(la);
- IF_AFDATA_WLOCK(ifp);
+ IF_AFDATA_CFG_WLOCK(ifp);
LLE_WLOCK(la);
/* Update data */
+ IF_AFDATA_RUN_WLOCK(ifp);
memcpy(&la->ll_addr, ar_sha(ah), ifp->if_addrlen);
la->la_flags |= LLE_VALID;
la->r_flags |= RLLE_VALID;
if ((la->la_flags & LLE_STATIC) == 0)
la->la_expire = time_uptime + V_arpt_keep;
+ llentry_link(LLTABLE(ifp), la);
+ IF_AFDATA_RUN_WUNLOCK(ifp);
- IF_AFDATA_WUNLOCK(ifp);
+ IF_AFDATA_CFG_WUNLOCK(ifp);
LLE_REMREF(la);
}
@@ -1084,12 +1093,18 @@ arp_ifinit(struct ifnet *ifp, struct ifa
* because the output of the arp utility shows
* that L2 entry as permanent
*/
- IF_AFDATA_LOCK(ifp);
+ IF_AFDATA_CFG_WLOCK(ifp);
lle = lla_create(LLTABLE(ifp), LLE_IFADDR | LLE_STATIC,
(struct sockaddr *)IA_SIN(ifa));
- if (lle != NULL)
+ if (lle != NULL) {
+ IF_AFDATA_RUN_WLOCK(ifp);
+ bcopy(IF_LLADDR(ifp), &lle->ll_addr, ifp->if_addrlen);
+ lle->la_flags |= (LLE_VALID | LLE_STATIC);
lle->r_flags |= RLLE_VALID;
- IF_AFDATA_UNLOCK(ifp);
+ llentry_link(LLTABLE(ifp), lle);
+ IF_AFDATA_RUN_WUNLOCK(ifp);
+ }
+ IF_AFDATA_CFG_WUNLOCK(ifp);
if (lle == NULL)
log(LOG_INFO, "arp_ifinit: cannot create arp "
"entry for interface address\n");
Modified: projects/routing/sys/netinet/in.c
==============================================================================
--- projects/routing/sys/netinet/in.c Sun Nov 23 12:15:28 2014 (r274916)
+++ projects/routing/sys/netinet/in.c Sun Nov 23 15:38:06 2014 (r274917)
@@ -1050,7 +1050,7 @@ in_lltable_prefix_free(struct lltable *l
size_t pkts_dropped;
LIST_INIT(&dchain);
- IF_AFDATA_WLOCK(llt->llt_ifp);
+ IF_AFDATA_CFG_WLOCK(llt->llt_ifp);
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
/*
@@ -1070,12 +1070,14 @@ in_lltable_prefix_free(struct lltable *l
}
}
/* Unlink chain */
+ IF_AFDATA_RUN_WLOCK(llt->llt_ifp);
llentries_unlink(&dchain);
+ IF_AFDATA_RUN_WUNLOCK(llt->llt_ifp);
LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next) {
pkts_dropped = llentry_free(lle);
ARPSTAT_ADD(dropped, pkts_dropped);
}
- IF_AFDATA_WUNLOCK(llt->llt_ifp);
+ IF_AFDATA_CFG_WUNLOCK(llt->llt_ifp);
}
@@ -1159,7 +1161,7 @@ in_lltable_delete(struct lltable *llt, u
struct ifnet *ifp = llt->llt_ifp;
struct llentry *lle;
- IF_AFDATA_WLOCK_ASSERT(ifp);
+ IF_AFDATA_CFG_WLOCK_ASSERT(ifp);
KASSERT(l3addr->sa_family == AF_INET,
("sin_family %d", l3addr->sa_family));
@@ -1175,7 +1177,9 @@ in_lltable_delete(struct lltable *llt, u
LLE_WLOCK(lle);
lle->la_flags |= LLE_DELETED;
EVENTHANDLER_INVOKE(lle_event, lle, LLENTRY_DELETED);
+ IF_AFDATA_RUN_WLOCK(ifp);
llentry_unlink(lle);
+ IF_AFDATA_RUN_WUNLOCK(ifp);
#ifdef DIAGNOSTIC
log(LOG_INFO, "ifaddr cache = %p is deleted\n", lle);
#endif
@@ -1195,7 +1199,7 @@ in_lltable_create(struct lltable *llt, u
struct ifnet *ifp = llt->llt_ifp;
struct llentry *lle;
- IF_AFDATA_WLOCK_ASSERT(ifp);
+ IF_AFDATA_CFG_WLOCK_ASSERT(ifp);
KASSERT(l3addr->sa_family == AF_INET,
("sin_family %d", l3addr->sa_family));
@@ -1223,12 +1227,6 @@ in_lltable_create(struct lltable *llt, u
return (NULL);
}
lle->la_flags = flags;
- if ((flags & LLE_IFADDR) == LLE_IFADDR) {
- bcopy(IF_LLADDR(ifp), &lle->ll_addr, ifp->if_addrlen);
- lle->la_flags |= (LLE_VALID | LLE_STATIC);
- }
-
- llentry_link(llt, lle);
LLE_WLOCK(lle);
return (lle);
Modified: projects/routing/sys/netinet/toecore.c
==============================================================================
--- projects/routing/sys/netinet/toecore.c Sun Nov 23 12:15:28 2014 (r274916)
+++ projects/routing/sys/netinet/toecore.c Sun Nov 23 15:38:06 2014 (r274917)
@@ -462,9 +462,9 @@ restart:
lle = lla_lookup(LLTABLE6(ifp), flags, sa);
IF_AFDATA_RUNLOCK(ifp);
if (lle == NULL) {
- IF_AFDATA_LOCK(ifp);
+ IF_AFDATA_CFG_WLOCK(ifp);
lle = nd6_create(&sin6->sin6_addr, 0, ifp);
- IF_AFDATA_UNLOCK(ifp);
+ IF_AFDATA_CFG_WUNLOCK(ifp);
if (lle == NULL)
return (ENOMEM); /* Couldn't create entry in cache. */
lle->ln_state = ND6_LLINFO_INCOMPLETE;
Modified: projects/routing/sys/netinet6/in6.c
==============================================================================
--- projects/routing/sys/netinet6/in6.c Sun Nov 23 12:15:28 2014 (r274916)
+++ projects/routing/sys/netinet6/in6.c Sun Nov 23 15:38:06 2014 (r274917)
@@ -72,6 +72,8 @@ __FBSDID("$FreeBSD$");
#include <sys/errno.h>
#include <sys/jail.h>
#include <sys/malloc.h>
+#include <sys/lock.h>
+#include <sys/rmlock.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sockio.h>
@@ -2100,7 +2102,7 @@ in6_lltable_prefix_free(struct lltable *
* including static ND6 entries.
*/
LIST_INIT(&dchain);
- IF_AFDATA_WLOCK(llt->llt_ifp);
+ IF_AFDATA_CFG_WLOCK(llt->llt_ifp);
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
if (IN6_ARE_MASKED_ADDR_EQUAL(
@@ -2117,10 +2119,12 @@ in6_lltable_prefix_free(struct lltable *
}
}
}
+ IF_AFDATA_RUN_WLOCK(llt->llt_ifp);
llentries_unlink(&dchain);
+ IF_AFDATA_RUN_WUNLOCK(llt->llt_ifp);
LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next)
llentry_free(lle);
- IF_AFDATA_WUNLOCK(llt->llt_ifp);
+ IF_AFDATA_CFG_WUNLOCK(llt->llt_ifp);
}
static int
@@ -2198,7 +2202,7 @@ in6_lltable_delete(struct lltable *llt,
const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)l3addr;
struct llentry *lle;
- IF_AFDATA_LOCK_ASSERT(llt->llt_ifp);
+ IF_AFDATA_CFG_WLOCK_ASSERT(llt->llt_ifp);
KASSERT(l3addr->sa_family == AF_INET6,
("sin_family %d", l3addr->sa_family));
@@ -2210,7 +2214,9 @@ in6_lltable_delete(struct lltable *llt,
if (!(lle->la_flags & LLE_IFADDR) || (flags & LLE_IFADDR)) {
LLE_WLOCK(lle);
lle->la_flags |= LLE_DELETED;
+ IF_AFDATA_RUN_WLOCK(llt->llt_ifp);
llentry_unlink(lle);
+ IF_AFDATA_RUN_WUNLOCK(llt->llt_ifp);
#ifdef DIAGNOSTIC
log(LOG_INFO, "ifaddr cache = %p is deleted\n", lle);
#endif
@@ -2231,7 +2237,7 @@ in6_lltable_create(struct lltable *llt,
struct ifnet *ifp = llt->llt_ifp;
struct llentry *lle;
- IF_AFDATA_WLOCK_ASSERT(ifp);
+ IF_AFDATA_CFG_WLOCK_ASSERT(ifp);
KASSERT(l3addr->sa_family == AF_INET6,
("sin_family %d", l3addr->sa_family));
@@ -2257,12 +2263,6 @@ in6_lltable_create(struct lltable *llt,
return NULL;
}
lle->la_flags = flags;
- if ((flags & LLE_IFADDR) == LLE_IFADDR) {
- bcopy(IF_LLADDR(ifp), &lle->ll_addr, ifp->if_addrlen);
- lle->la_flags |= (LLE_VALID | LLE_STATIC);
- }
-
- llentry_link(llt, lle);
LLE_WLOCK(lle);
return (lle);
@@ -2290,7 +2290,7 @@ in6_lltable_lookup(struct lltable *llt,
if (flags & LLE_EXCLUSIVE)
LLE_WLOCK(lle);
- else
+ else if ((flags & LLE_UNLOCKED) == 0)
LLE_RLOCK(lle);
return (lle);
}
Modified: projects/routing/sys/netinet6/nd6.c
==============================================================================
--- projects/routing/sys/netinet6/nd6.c Sun Nov 23 12:15:28 2014 (r274916)
+++ projects/routing/sys/netinet6/nd6.c Sun Nov 23 15:38:06 2014 (r274917)
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
#include <sys/syslog.h>
#include <sys/lock.h>
#include <sys/rwlock.h>
+#include <sys/rmlock.h>
#include <sys/queue.h>
#include <sys/sdt.h>
#include <sys/sysctl.h>
@@ -854,7 +855,9 @@ nd6_lookup(struct in6_addr *addr6, int f
sin6.sin6_family = AF_INET6;
sin6.sin6_addr = *addr6;
- IF_AFDATA_LOCK_ASSERT(ifp);
+ /*
+ * IF_AFDATA_LOCK_ASSERT(ifp);
+ */
llflags = (flags & ND6_EXCLUSIVE) ? LLE_EXCLUSIVE : 0;
ln = lla_lookup(LLTABLE6(ifp), llflags, (struct sockaddr *)&sin6);
@@ -877,11 +880,15 @@ nd6_create(struct in6_addr *addr6, int f
sin6.sin6_family = AF_INET6;
sin6.sin6_addr = *addr6;
- IF_AFDATA_WLOCK_ASSERT(ifp);
+ IF_AFDATA_CFG_WLOCK_ASSERT(ifp);
ln = lla_create(LLTABLE6(ifp), 0, (struct sockaddr *)&sin6);
- if (ln != NULL)
+ if (ln != NULL) {
+ IF_AFDATA_RUN_WLOCK(ifp);
ln->ln_state = ND6_LLINFO_NOSTATE;
+ llentry_link(LLTABLE6(ifp), ln);
+ IF_AFDATA_RUN_WUNLOCK(ifp);
+ }
return (ln);
}
@@ -998,7 +1005,7 @@ nd6_is_addr_neighbor(struct sockaddr_in6
struct llentry *lle;
int rc = 0;
- IF_AFDATA_UNLOCK_ASSERT(ifp);
+ IF_AFDATA_CFG_UNLOCK_ASSERT(ifp);
if (nd6_is_new_addr_neighbor(addr, ifp))
return (1);
@@ -1137,7 +1144,7 @@ nd6_free(struct llentry *ln, int gc)
* free(9) in llentry_free() if someone else holds one as well.
*/
LLE_WUNLOCK(ln);
- IF_AFDATA_LOCK(ifp);
+ IF_AFDATA_CFG_WLOCK(ifp);
LLE_WLOCK(ln);
/*
@@ -1149,9 +1156,13 @@ nd6_free(struct llentry *ln, int gc)
ln->la_flags &= ~LLE_CALLOUTREF;
}
+ IF_AFDATA_RUN_WLOCK(ifp);
+ llentry_unlink(ln);
+ IF_AFDATA_RUN_WUNLOCK(ifp);
+
llentry_free(ln);
- IF_AFDATA_UNLOCK(ifp);
+ IF_AFDATA_CFG_WUNLOCK(ifp);
return (next);
}
@@ -1579,7 +1590,7 @@ nd6_cache_lladdr(struct ifnet *ifp, stru
struct mbuf *chain = NULL;
int static_route = 0;
- IF_AFDATA_UNLOCK_ASSERT(ifp);
+ IF_AFDATA_CFG_UNLOCK_ASSERT(ifp);
KASSERT(ifp != NULL, ("%s: ifp == NULL", __func__));
KASSERT(from != NULL, ("%s: from == NULL", __func__));
@@ -1598,14 +1609,14 @@ nd6_cache_lladdr(struct ifnet *ifp, stru
* description on it in NS section (RFC 2461 7.2.3).
*/
flags = lladdr ? ND6_EXCLUSIVE : 0;
- IF_AFDATA_RLOCK(ifp);
+ IF_AFDATA_CFG_RLOCK(ifp);
ln = nd6_lookup(from, flags, ifp);
- IF_AFDATA_RUNLOCK(ifp);
+ IF_AFDATA_CFG_RUNLOCK(ifp);
if (ln == NULL) {
flags |= ND6_EXCLUSIVE;
- IF_AFDATA_LOCK(ifp);
+ IF_AFDATA_CFG_WLOCK(ifp);
ln = nd6_create(from, 0, ifp);
- IF_AFDATA_UNLOCK(ifp);
+ IF_AFDATA_CFG_WUNLOCK(ifp);
is_newentry = 1;
} else {
/* do nothing if static ndp is set */
@@ -2004,9 +2015,9 @@ nd6_output_lle(struct ifnet *ifp, struct
* the condition below is not very efficient. But we believe
* it is tolerable, because this should be a rare case.
*/
- IF_AFDATA_LOCK(ifp);
+ IF_AFDATA_CFG_WLOCK(ifp);
lle = nd6_create(&dst->sin6_addr, 0, ifp);
- IF_AFDATA_UNLOCK(ifp);
+ IF_AFDATA_CFG_WUNLOCK(ifp);
}
}
if (lle == NULL) {
@@ -2257,14 +2268,23 @@ nd6_add_ifa_lle(struct in6_ifaddr *ia)
struct llentry *ln;
ifp = ia->ia_ifa.ifa_ifp;
- IF_AFDATA_LOCK(ifp);
- ia->ia_ifa.ifa_rtrequest = nd6_rtrequest;
+ IF_AFDATA_CFG_WLOCK(ifp);
ln = lla_create(LLTABLE6(ifp), LLE_IFADDR,
(struct sockaddr *)&ia->ia_addr);
- IF_AFDATA_UNLOCK(ifp);
if (ln != NULL) {
+ IF_AFDATA_RUN_WLOCK(ifp);
+ bcopy(IF_LLADDR(ifp), &ln->ll_addr, ifp->if_addrlen);
+ ln->la_flags |= (LLE_VALID | LLE_STATIC);
+ ln->r_flags |= RLLE_VALID;
ln->la_expire = 0; /* for IPv6 this means permanent */
ln->ln_state = ND6_LLINFO_REACHABLE;
+ llentry_link(LLTABLE6(ifp), ln);
+ IF_AFDATA_RUN_WUNLOCK(ifp);
+ }
+
+ ia->ia_ifa.ifa_rtrequest = nd6_rtrequest;
+ IF_AFDATA_CFG_WUNLOCK(ifp);
+ if (ln != NULL) {
LLE_WUNLOCK(ln);
in6_newaddrmsg(ia, RTM_ADD);
return (0);
@@ -2306,7 +2326,7 @@ nd6_storelladdr(struct ifnet *ifp, struc
struct llentry *ln;
*lle = NULL;
- IF_AFDATA_UNLOCK_ASSERT(ifp);
+ IF_AFDATA_CFG_UNLOCK_ASSERT(ifp);
if (m != NULL && m->m_flags & M_MCAST) {
int i;
Modified: projects/routing/sys/netinet6/scope6.c
==============================================================================
--- projects/routing/sys/netinet6/scope6.c Sun Nov 23 12:15:28 2014 (r274916)
+++ projects/routing/sys/netinet6/scope6.c Sun Nov 23 15:38:06 2014 (r274917)
@@ -148,11 +148,11 @@ scope6_set(struct ifnet *ifp, struct sco
int error = 0;
struct scope6_id *sid = NULL;
- IF_AFDATA_WLOCK(ifp);
+ IF_AFDATA_CFG_WLOCK(ifp);
sid = SID(ifp);
if (!sid) { /* paranoid? */
- IF_AFDATA_WUNLOCK(ifp);
+ IF_AFDATA_CFG_WUNLOCK(ifp);
return (EINVAL);
}
@@ -175,7 +175,7 @@ scope6_set(struct ifnet *ifp, struct sco
*/
if (i == IPV6_ADDR_SCOPE_INTFACELOCAL &&
idlist->s6id_list[i] != ifp->if_index) {
- IF_AFDATA_WUNLOCK(ifp);
+ IF_AFDATA_CFG_WUNLOCK(ifp);
return (EINVAL);
}
@@ -187,7 +187,7 @@ scope6_set(struct ifnet *ifp, struct sco
* IDs, but we check the consistency for
* safety in later use.
*/
- IF_AFDATA_WUNLOCK(ifp);
+ IF_AFDATA_CFG_WUNLOCK(ifp);
return (EINVAL);
}
@@ -196,10 +196,11 @@ scope6_set(struct ifnet *ifp, struct sco
* but we simply set the new value in this initial
* implementation.
*/
+ /* XXX: Use runtime lock? */
sid->s6id_list[i] = idlist->s6id_list[i];
}
}
- IF_AFDATA_WUNLOCK(ifp);
+ IF_AFDATA_CFG_WUNLOCK(ifp);
return (error);
}
More information about the svn-src-projects
mailing list