mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-15 10:17:20 +00:00
Rather than using IFNET_RLOCK() when iterating over (and modifying) the
ifnet list during if_ef load, directly acquire the ifnet_sxlock exclusively. That way when if_alloc() recurses the lock, it's a write recursion rather than a read->write recursion. This code structure is arguably a bug, so add a comment indicating that this is the case. Post-8.0, we should fix this, but this commit resolves panic-on-load for if_ef. Discussed with: bz, julian Reported by: phk MFC after: 3 days
This commit is contained in:
parent
77dfcdc445
commit
6852110b64
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=196482
@ -492,7 +492,20 @@ ef_load(void)
|
||||
VNET_LIST_RLOCK();
|
||||
VNET_FOREACH(vnet_iter) {
|
||||
CURVNET_SET(vnet_iter);
|
||||
IFNET_RLOCK();
|
||||
|
||||
/*
|
||||
* XXXRW: The following loop walks the ifnet list while
|
||||
* modifying it, something not well-supported by ifnet
|
||||
* locking. To avoid lock upgrade/recursion issues, manually
|
||||
* acquire a write lock of ifnet_sxlock here, rather than a
|
||||
* read lock, so that when if_alloc() recurses the lock, we
|
||||
* don't panic. This structure, in which if_ef automatically
|
||||
* attaches to all ethernet interfaces, should be replaced
|
||||
* with a model like that found in if_vlan, in which
|
||||
* interfaces are explicitly configured, which would avoid
|
||||
* this (and other) problems.
|
||||
*/
|
||||
sx_xlock(&ifnet_sxlock);
|
||||
TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
|
||||
if (ifp->if_type != IFT_ETHER) continue;
|
||||
EFDEBUG("Found interface %s\n", ifp->if_xname);
|
||||
@ -523,7 +536,7 @@ ef_load(void)
|
||||
efcount++;
|
||||
SLIST_INSERT_HEAD(&efdev, efl, el_next);
|
||||
}
|
||||
IFNET_RUNLOCK();
|
||||
sx_xunlock(&ifnet_sxlock);
|
||||
CURVNET_RESTORE();
|
||||
}
|
||||
VNET_LIST_RUNLOCK();
|
||||
|
Loading…
Reference in New Issue
Block a user