Page MenuHomeFreeBSD

D16808.id46952.diff
No OneTemporary

D16808.id46952.diff

Index: sys/net/if_var.h
===================================================================
--- sys/net/if_var.h
+++ sys/net/if_var.h
@@ -411,7 +411,7 @@
#define NET_EPOCH_ENTER_ET(et) epoch_enter_preempt(net_epoch_preempt, &(et))
#define NET_EPOCH_EXIT() epoch_exit_preempt(net_epoch_preempt, &nep_et)
#define NET_EPOCH_EXIT_ET(et) epoch_exit_preempt(net_epoch_preempt, &(et))
-
+#define NET_EPOCH_WAIT() epoch_wait_preempt(net_epoch_preempt)
/*
* Function variations on locking macros intended to be used by loadable
Index: sys/net/if_vlan.c
===================================================================
--- sys/net/if_vlan.c
+++ sys/net/if_vlan.c
@@ -87,11 +87,11 @@
#define UP_AND_RUNNING(ifp) \
((ifp)->if_flags & IFF_UP && (ifp)->if_drv_flags & IFF_DRV_RUNNING)
-LIST_HEAD(ifvlanhead, ifvlan);
+CK_SLIST_HEAD(ifvlanhead, ifvlan);
struct ifvlantrunk {
struct ifnet *parent; /* parent interface of this trunk */
- struct rmlock lock;
+ struct mtx lock;
#ifdef VLAN_ARRAY
#define VLAN_ARRAY_SIZE (EVL_VLID_MASK + 1)
struct ifvlan *vlans[VLAN_ARRAY_SIZE]; /* static table */
@@ -117,7 +117,7 @@
struct ifvlan *_next; \
size_t _i; \
for (_i = 0; _i < (1 << (_trunk)->hwidth); _i++) \
- LIST_FOREACH_SAFE((_ifv), &(_trunk)->hash[_i], ifv_list, _next)
+ CK_SLIST_FOREACH_SAFE((_ifv), &(_trunk)->hash[_i], ifv_list, _next)
#endif /* VLAN_ARRAY */
/*
@@ -146,13 +146,13 @@
for (_i = 0; \
!(_cond) && _i < (1 << (_trunk)->hwidth); \
_i = (_touch && ((_trunk) != NULL) ? 0 : _i + 1), _touch = false) \
- if (((_ifv) = LIST_FIRST(&(_trunk)->hash[_i])) != NULL && \
+ if (((_ifv) = CK_SLIST_FIRST(&(_trunk)->hash[_i])) != NULL && \
(_touch = true))
#endif /* VLAN_ARRAY */
struct vlan_mc_entry {
struct sockaddr_dl mc_addr;
- SLIST_ENTRY(vlan_mc_entry) mc_entries;
+ CK_SLIST_ENTRY(vlan_mc_entry) mc_entries;
};
struct ifvlan {
@@ -173,9 +173,9 @@
uint8_t ifvm_pcp; /* Priority Code Point (PCP). */
} ifv_mib;
struct task lladdr_task;
- SLIST_HEAD(, vlan_mc_entry) vlan_mc_listhead;
+ CK_SLIST_HEAD(, vlan_mc_entry) vlan_mc_listhead;
#ifndef VLAN_ARRAY
- LIST_ENTRY(ifvlan) ifv_list;
+ CK_SLIST_ENTRY(ifvlan) ifv_list;
#endif
};
#define ifv_proto ifv_mib.ifvm_proto
@@ -229,31 +229,19 @@
* freed/reused when the tx/rx functions are called by the stack. This can only
* be fixed by addressing ifnet's lifetime issues.
*/
-#define _VLAN_RM_ID ifv_rm_lock
#define _VLAN_SX_ID ifv_sx
-static struct rmlock _VLAN_RM_ID;
static struct sx _VLAN_SX_ID;
#define VLAN_LOCKING_INIT() \
- rm_init(&_VLAN_RM_ID, "vlan_rm"); \
sx_init(&_VLAN_SX_ID, "vlan_sx")
#define VLAN_LOCKING_DESTROY() \
- rm_destroy(&_VLAN_RM_ID); \
sx_destroy(&_VLAN_SX_ID)
-#define _VLAN_RM_TRACKER _vlan_rm_tracker
-#define VLAN_RLOCK() rm_rlock(&_VLAN_RM_ID, \
- &_VLAN_RM_TRACKER)
-#define VLAN_RUNLOCK() rm_runlock(&_VLAN_RM_ID, \
- &_VLAN_RM_TRACKER)
-#define VLAN_WLOCK() rm_wlock(&_VLAN_RM_ID)
-#define VLAN_WUNLOCK() rm_wunlock(&_VLAN_RM_ID)
-#define VLAN_RLOCK_ASSERT() rm_assert(&_VLAN_RM_ID, RA_RLOCKED)
-#define VLAN_WLOCK_ASSERT() rm_assert(&_VLAN_RM_ID, RA_WLOCKED)
-#define VLAN_RWLOCK_ASSERT() rm_assert(&_VLAN_RM_ID, RA_LOCKED)
-#define VLAN_LOCK_READER struct rm_priotracker _VLAN_RM_TRACKER
+#define VLAN_RLOCK() NET_EPOCH_ENTER();
+#define VLAN_RUNLOCK() NET_EPOCH_EXIT();
+#define VLAN_RLOCK_ASSERT() MPASS(in_epoch(net_epoch_preempt))
#define VLAN_SLOCK() sx_slock(&_VLAN_SX_ID)
#define VLAN_SUNLOCK() sx_sunlock(&_VLAN_SX_ID)
@@ -271,19 +259,15 @@
* via VLAN_SLOCK or VLAN_RLOCK. Thus, an exclusive lock on the global locks
* makes a call to TRUNK_RLOCK/TRUNK_WLOCK technically superfluous.
*/
-#define _TRUNK_RM_TRACKER _trunk_rm_tracker
-#define TRUNK_LOCK_INIT(trunk) rm_init(&(trunk)->lock, vlanname)
-#define TRUNK_LOCK_DESTROY(trunk) rm_destroy(&(trunk)->lock)
-#define TRUNK_RLOCK(trunk) rm_rlock(&(trunk)->lock, \
- &_TRUNK_RM_TRACKER)
-#define TRUNK_WLOCK(trunk) rm_wlock(&(trunk)->lock)
-#define TRUNK_RUNLOCK(trunk) rm_runlock(&(trunk)->lock, \
- &_TRUNK_RM_TRACKER)
-#define TRUNK_WUNLOCK(trunk) rm_wunlock(&(trunk)->lock)
-#define TRUNK_RLOCK_ASSERT(trunk) rm_assert(&(trunk)->lock, RA_RLOCKED)
-#define TRUNK_LOCK_ASSERT(trunk) rm_assert(&(trunk)->lock, RA_LOCKED)
-#define TRUNK_WLOCK_ASSERT(trunk) rm_assert(&(trunk)->lock, RA_WLOCKED)
-#define TRUNK_LOCK_READER struct rm_priotracker _TRUNK_RM_TRACKER
+#define TRUNK_LOCK_INIT(trunk) mtx_init(&(trunk)->lock, vlanname, NULL, MTX_DEF)
+#define TRUNK_LOCK_DESTROY(trunk) mtx_destroy(&(trunk)->lock)
+#define TRUNK_RLOCK(trunk) NET_EPOCH_ENTER()
+#define TRUNK_WLOCK(trunk) mtx_lock(&(trunk)->lock)
+#define TRUNK_RUNLOCK(trunk) NET_EPOCH_EXIT();
+#define TRUNK_WUNLOCK(trunk) mtx_unlock(&(trunk)->lock)
+#define TRUNK_RLOCK_ASSERT(trunk) MPASS(in_epoch(net_epoch_preempt))
+#define TRUNK_LOCK_ASSERT(trunk) MPASS(in_epoch(net_epoch_preempt) || mtx_owned(&(trunk)->lock))
+#define TRUNK_WLOCK_ASSERT(trunk) mtx_assert(&(trunk)->lock, MA_OWNED);
/*
* The VLAN_ARRAY substitutes the dynamic hash with a static array
@@ -361,7 +345,7 @@
trunk->hmask = n - 1;
trunk->hash = malloc(sizeof(struct ifvlanhead) * n, M_VLAN, M_WAITOK);
for (i = 0; i < n; i++)
- LIST_INIT(&trunk->hash[i]);
+ CK_SLIST_INIT(&trunk->hash[i]);
}
static void
@@ -372,7 +356,7 @@
KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__));
for (i = 0; i < (1 << trunk->hwidth); i++)
- KASSERT(LIST_EMPTY(&trunk->hash[i]),
+ KASSERT(CK_SLIST_EMPTY(&trunk->hash[i]),
("%s: hash table not empty", __func__));
#endif
free(trunk->hash, M_VLAN);
@@ -391,7 +375,7 @@
b = 1 << trunk->hwidth;
i = HASH(ifv->ifv_vid, trunk->hmask);
- LIST_FOREACH(ifv2, &trunk->hash[i], ifv_list)
+ CK_SLIST_FOREACH(ifv2, &trunk->hash[i], ifv_list)
if (ifv->ifv_vid == ifv2->ifv_vid)
return (EEXIST);
@@ -404,7 +388,7 @@
vlan_growhash(trunk, 1);
i = HASH(ifv->ifv_vid, trunk->hmask);
}
- LIST_INSERT_HEAD(&trunk->hash[i], ifv, ifv_list);
+ CK_SLIST_INSERT_HEAD(&trunk->hash[i], ifv, ifv_list);
trunk->refcnt++;
return (0);
@@ -421,10 +405,10 @@
b = 1 << trunk->hwidth;
i = HASH(ifv->ifv_vid, trunk->hmask);
- LIST_FOREACH(ifv2, &trunk->hash[i], ifv_list)
+ CK_SLIST_FOREACH(ifv2, &trunk->hash[i], ifv_list)
if (ifv2 == ifv) {
trunk->refcnt--;
- LIST_REMOVE(ifv2, ifv_list);
+ CK_SLIST_REMOVE(&trunk->hash[i], ifv2, ifvlan, ifv_list);
if (trunk->refcnt < (b * b) / 2)
vlan_growhash(trunk, -1);
return (0);
@@ -468,13 +452,14 @@
return; /* We can live with the old hash table */
}
for (j = 0; j < n2; j++)
- LIST_INIT(&hash2[j]);
+ CK_SLIST_INIT(&hash2[j]);
for (i = 0; i < n; i++)
- while ((ifv = LIST_FIRST(&trunk->hash[i])) != NULL) {
- LIST_REMOVE(ifv, ifv_list);
+ while ((ifv = CK_SLIST_FIRST(&trunk->hash[i])) != NULL) {
+ CK_SLIST_REMOVE(&trunk->hash[i], ifv, ifvlan, ifv_list);
j = HASH(ifv->ifv_vid, n2 - 1);
- LIST_INSERT_HEAD(&hash2[j], ifv, ifv_list);
+ CK_SLIST_INSERT_HEAD(&hash2[j], ifv, ifv_list);
}
+ NET_EPOCH_WAIT();
free(trunk->hash, M_VLAN);
trunk->hash = hash2;
trunk->hwidth = hwidth2;
@@ -492,7 +477,7 @@
TRUNK_RLOCK_ASSERT(trunk);
- LIST_FOREACH(ifv, &trunk->hash[HASH(vid, trunk->hmask)], ifv_list)
+ CK_SLIST_FOREACH(ifv, &trunk->hash[HASH(vid, trunk->hmask)], ifv_list)
if (ifv->ifv_vid == vid)
return (ifv);
return (NULL);
@@ -508,7 +493,7 @@
for (i = 0; i < (1 << trunk->hwidth); i++) {
printf("%d: ", i);
- LIST_FOREACH(ifv, &trunk->hash[i], ifv_list)
+ CK_SLIST_FOREACH(ifv, &trunk->hash[i], ifv_list)
printf("%s ", ifv->ifv_ifp->if_xname);
printf("\n");
}
@@ -561,7 +546,6 @@
trunk_destroy(struct ifvlantrunk *trunk)
{
VLAN_XLOCK_ASSERT();
- VLAN_WLOCK_ASSERT();
vlan_freehash(trunk);
trunk->parent->if_vlantrunk = NULL;
@@ -591,19 +575,19 @@
* XXX This stupidly needs the rmlock to avoid sleeping while holding
* the in6_multi_mtx (see in6_mc_join_locked).
*/
- VLAN_RWLOCK_ASSERT();
+ VLAN_XLOCK_ASSERT();
/* Find the parent. */
sc = ifp->if_softc;
- TRUNK_WLOCK_ASSERT(TRUNK(sc));
ifp_p = PARENT(sc);
CURVNET_SET_QUIET(ifp_p->if_vnet);
/* First, remove any existing filter entries. */
- while ((mc = SLIST_FIRST(&sc->vlan_mc_listhead)) != NULL) {
- SLIST_REMOVE_HEAD(&sc->vlan_mc_listhead, mc_entries);
+ while ((mc = CK_SLIST_FIRST(&sc->vlan_mc_listhead)) != NULL) {
+ CK_SLIST_REMOVE_HEAD(&sc->vlan_mc_listhead, mc_entries);
(void)if_delmulti(ifp_p, (struct sockaddr *)&mc->mc_addr);
+ NET_EPOCH_WAIT();
free(mc, M_VLAN);
}
@@ -619,10 +603,10 @@
}
bcopy(ifma->ifma_addr, &mc->mc_addr, ifma->ifma_addr->sa_len);
mc->mc_addr.sdl_index = ifp_p->if_index;
- SLIST_INSERT_HEAD(&sc->vlan_mc_listhead, mc, mc_entries);
+ CK_SLIST_INSERT_HEAD(&sc->vlan_mc_listhead, mc, mc_entries);
}
IF_ADDR_WUNLOCK(ifp);
- SLIST_FOREACH (mc, &sc->vlan_mc_listhead, mc_entries) {
+ CK_SLIST_FOREACH (mc, &sc->vlan_mc_listhead, mc_entries) {
error = if_addmulti(ifp_p, (struct sockaddr *)&mc->mc_addr,
NULL);
if (error)
@@ -645,7 +629,6 @@
struct ifnet *ifv_ifp;
struct ifvlantrunk *trunk;
struct sockaddr_dl *sdl;
- VLAN_LOCK_READER;
/* Need the rmlock since this is run on taskqueue_swi. */
VLAN_RLOCK();
@@ -724,7 +707,6 @@
vlan_trunkdev(struct ifnet *ifp)
{
struct ifvlan *ifv;
- VLAN_LOCK_READER;
if (ifp->if_type != IFT_L2VLAN)
return (NULL);
@@ -809,8 +791,6 @@
{
struct ifvlantrunk *trunk;
struct ifvlan *ifv;
- VLAN_LOCK_READER;
- TRUNK_LOCK_READER;
/* Not clear if callers are sleepable, so acquire the rmlock. */
VLAN_RLOCK();
@@ -820,11 +800,9 @@
return (NULL);
}
ifp = NULL;
- TRUNK_RLOCK(trunk);
ifv = vlan_gethash(trunk, vid);
if (ifv)
ifp = ifv->ifv_ifp;
- TRUNK_RUNLOCK(trunk);
VLAN_RUNLOCK();
return (ifp);
}
@@ -1076,7 +1054,7 @@
if_rele(p);
return (ENOSPC);
}
- SLIST_INIT(&ifv->vlan_mc_listhead);
+ CK_SLIST_INIT(&ifv->vlan_mc_listhead);
ifp->if_softc = ifv;
/*
* Set the name manually rather than using if_initname because
@@ -1167,7 +1145,6 @@
struct ifvlan *ifv;
struct ifnet *p;
int error, len, mcast;
- VLAN_LOCK_READER;
VLAN_RLOCK();
ifv = ifp->if_softc;
@@ -1227,8 +1204,6 @@
{
struct ifvlantrunk *trunk;
struct ifvlan *ifv;
- VLAN_LOCK_READER;
- TRUNK_LOCK_READER;
struct m_tag *mtag;
uint16_t vid, tag;
@@ -1289,16 +1264,13 @@
vid = EVL_VLANOFTAG(tag);
- TRUNK_RLOCK(trunk);
ifv = vlan_gethash(trunk, vid);
if (ifv == NULL || !UP_AND_RUNNING(ifv->ifv_ifp)) {
- TRUNK_RUNLOCK(trunk);
- if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1);
VLAN_RUNLOCK();
+ if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1);
m_freem(m);
return;
}
- TRUNK_RUNLOCK(trunk);
if (vlan_mtag_pcp) {
/*
@@ -1376,13 +1348,11 @@
M_VLAN, M_WAITOK | M_ZERO);
vlan_inithash(trunk);
TRUNK_LOCK_INIT(trunk);
- VLAN_WLOCK();
TRUNK_WLOCK(trunk);
p->if_vlantrunk = trunk;
trunk->parent = p;
if_ref(trunk->parent);
} else {
- VLAN_WLOCK();
trunk = p->if_vlantrunk;
TRUNK_WLOCK(trunk);
}
@@ -1391,8 +1361,10 @@
ifv->ifv_pcp = 0; /* Default: best effort delivery. */
vlan_tag_recalculate(ifv);
error = vlan_inshash(trunk, ifv);
- if (error)
+ if (error) {
+ TRUNK_WUNLOCK(trunk);
goto done;
+ }
ifv->ifv_proto = ETHERTYPE_VLAN;
ifv->ifv_encaplen = ETHER_VLAN_ENCAP_LEN;
ifv->ifv_mintu = ETHERMIN;
@@ -1458,12 +1430,6 @@
((struct sockaddr_dl *)ifp->if_addr->ifa_addr)->sdl_alen =
p->if_addrlen;
- /*
- * Configure multicast addresses that may already be
- * joined on the vlan device.
- */
- (void)vlan_setmulti(ifp);
-
TASK_INIT(&ifv->lladdr_task, 0, vlan_lladdr_fn, ifv);
/* We are ready for operation now. */
@@ -1471,13 +1437,14 @@
/* Update flags on the parent, if necessary. */
vlan_setflags(ifp, 1);
-done:
+ TRUNK_WUNLOCK(trunk);
/*
- * We need to drop the non-sleepable rmlock so that the underlying
- * devices can sleep in their vlan_config hooks.
+ * Configure multicast addresses that may already be
+ * joined on the vlan device.
*/
- TRUNK_WUNLOCK(trunk);
- VLAN_WUNLOCK();
+ (void)vlan_setmulti(ifp);
+
+done:
if (error == 0)
EVENTHANDLER_INVOKE(vlan_config, p, ifv->ifv_vid);
VLAN_XUNLOCK();
@@ -1516,7 +1483,6 @@
* an exclusive lock here to prevent them from using bad
* ifvlans.
*/
- VLAN_WLOCK();
parent = trunk->parent;
/*
@@ -1524,7 +1490,7 @@
* empty the list of multicast groups that we may have joined
* while we were alive from the parent's list.
*/
- while ((mc = SLIST_FIRST(&ifv->vlan_mc_listhead)) != NULL) {
+ while ((mc = CK_SLIST_FIRST(&ifv->vlan_mc_listhead)) != NULL) {
/*
* If the parent interface is being detached,
* all its multicast addresses have already
@@ -1541,7 +1507,7 @@
"Failed to delete multicast address from parent: %d\n",
error);
}
- SLIST_REMOVE_HEAD(&ifv->vlan_mc_listhead, mc_entries);
+ CK_SLIST_REMOVE_HEAD(&ifv->vlan_mc_listhead, mc_entries);
free(mc, M_VLAN);
}
@@ -1561,9 +1527,9 @@
*/
if (trunk->refcnt == 0) {
parent->if_vlantrunk = NULL;
+ NET_EPOCH_WAIT();
trunk_destroy(trunk);
}
- VLAN_WUNLOCK();
}
/* Disconnect from parent. */
@@ -1640,7 +1606,6 @@
{
struct ifvlantrunk *trunk;
struct ifvlan *ifv;
- VLAN_LOCK_READER;
/* Called from a taskqueue_swi task, so we cannot sleep. */
VLAN_RLOCK();
@@ -1789,7 +1754,6 @@
struct ifvlantrunk *trunk;
struct vlanreq vlr;
int error = 0;
- VLAN_LOCK_READER;
ifr = (struct ifreq *)data;
ifa = (struct ifaddr *) data;
@@ -1925,16 +1889,13 @@
* XXX We need the rmlock here to avoid sleeping while
* holding in6_multi_mtx.
*/
- VLAN_RLOCK();
+ VLAN_XLOCK();
trunk = TRUNK(ifv);
- if (trunk != NULL) {
- TRUNK_WLOCK(trunk);
+ if (trunk != NULL)
error = vlan_setmulti(ifp);
- TRUNK_WUNLOCK(trunk);
- }
- VLAN_RUNLOCK();
- break;
+ VLAN_XUNLOCK();
+ break;
case SIOCGVLANPCP:
#ifdef VIMAGE
if (ifp->if_vnet != ifp->if_home_vnet) {

File Metadata

Mime Type
text/plain
Expires
Sat, May 16, 12:57 PM (19 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33130433
Default Alt Text
D16808.id46952.diff (13 KB)

Event Timeline