First pass at softc list locking for if_ppp.c. Many parts of
this patch were submitted by Maurycy Pawlowski-Wieronski. In addition to Maurycy's change, break out softc tear down from ppp_clone_destroy() into ppp_destroy() rather than performing a convoluted series of extraction casts and indirections during tear down at mod unload. Submitted by: Maurycy Pawlowski-Wieronski <maurycy@fouk.org>
This commit is contained in:
parent
2e80ca8a68
commit
b2073c7d9e
@ -132,8 +132,16 @@
|
||||
|
||||
#define PPPNAME "ppp"
|
||||
static MALLOC_DEFINE(M_PPP, PPPNAME, "PPP interface");
|
||||
|
||||
static struct mtx ppp_softc_list_mtx;
|
||||
static LIST_HEAD(, ppp_softc) ppp_softc_list;
|
||||
|
||||
#define PPP_LIST_LOCK_INIT() mtx_init(&ppp_softc_list_mtx, \
|
||||
"ppp_softc_list_mtx", NULL, MTX_DEF)
|
||||
#define PPP_LIST_LOCK_DESTROY() mtx_destroy(&ppp_softc_list_mtx)
|
||||
#define PPP_LIST_LOCK() mtx_lock(&ppp_softc_list_mtx)
|
||||
#define PPP_LIST_UNLOCK() mtx_unlock(&ppp_softc_list_mtx)
|
||||
|
||||
/* XXX layering violation */
|
||||
extern void pppasyncattach(void *);
|
||||
extern void pppasyncdetach(void);
|
||||
@ -217,33 +225,48 @@ ppp_clone_create(struct if_clone *ifc, int unit)
|
||||
mtx_init(&sc->sc_rawq.ifq_mtx, "ppp_rawq", NULL, MTX_DEF);
|
||||
if_attach(&sc->sc_if);
|
||||
bpfattach(&sc->sc_if, DLT_PPP, PPP_HDRLEN);
|
||||
|
||||
PPP_LIST_LOCK();
|
||||
LIST_INSERT_HEAD(&ppp_softc_list, sc, sc_list);
|
||||
PPP_LIST_UNLOCK();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
ppp_clone_destroy(struct ifnet *ifp)
|
||||
ppp_destroy(struct ppp_softc *sc)
|
||||
{
|
||||
struct ppp_softc *sc;
|
||||
struct ifnet *ifp;
|
||||
|
||||
sc = ifp->if_softc;
|
||||
|
||||
LIST_REMOVE(sc, sc_list);
|
||||
ifp = &sc->sc_if;
|
||||
bpfdetach(ifp);
|
||||
if_detach(ifp);
|
||||
mtx_destroy(&sc->sc_rawq.ifq_mtx);
|
||||
mtx_destroy(&sc->sc_fastq.ifq_mtx);
|
||||
mtx_destroy(&sc->sc_inq.ifq_mtx);
|
||||
|
||||
free(sc, M_PPP);
|
||||
}
|
||||
|
||||
static void
|
||||
ppp_clone_destroy(struct ifnet *ifp)
|
||||
{
|
||||
struct ppp_softc *sc;
|
||||
|
||||
sc = ifp->if_softc;
|
||||
PPP_LIST_LOCK();
|
||||
LIST_REMOVE(sc, sc_list);
|
||||
PPP_LIST_UNLOCK();
|
||||
ppp_destroy(sc);
|
||||
}
|
||||
|
||||
static int
|
||||
ppp_modevent(module_t mod, int type, void *data)
|
||||
{
|
||||
{
|
||||
struct ppp_softc *sc;
|
||||
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
PPP_LIST_LOCK_INIT();
|
||||
LIST_INIT(&ppp_softc_list);
|
||||
if_clone_attach(&ppp_cloner);
|
||||
|
||||
@ -262,9 +285,14 @@ ppp_modevent(module_t mod, int type, void *data)
|
||||
|
||||
if_clone_detach(&ppp_cloner);
|
||||
|
||||
while (!LIST_EMPTY(&ppp_softc_list))
|
||||
ppp_clone_destroy(
|
||||
&LIST_FIRST(&ppp_softc_list)->sc_if);
|
||||
PPP_LIST_LOCK();
|
||||
while ((sc = LIST_FIRST(&ppp_softc_list)) != NULL) {
|
||||
LIST_REMOVE(sc, sc_list);
|
||||
PPP_LIST_UNLOCK();
|
||||
ppp_destroy(sc);
|
||||
PPP_LIST_LOCK();
|
||||
}
|
||||
PPP_LIST_LOCK_DESTROY();
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@ -290,9 +318,11 @@ pppalloc(pid)
|
||||
struct ifnet *ifp;
|
||||
struct ppp_softc *sc;
|
||||
|
||||
PPP_LIST_LOCK();
|
||||
LIST_FOREACH(sc, &ppp_softc_list, sc_list) {
|
||||
if (sc->sc_xfer == pid) {
|
||||
sc->sc_xfer = 0;
|
||||
PPP_LIST_UNLOCK();
|
||||
return sc;
|
||||
}
|
||||
}
|
||||
@ -300,6 +330,7 @@ pppalloc(pid)
|
||||
if (sc->sc_devp == NULL)
|
||||
break;
|
||||
}
|
||||
PPP_LIST_UNLOCK();
|
||||
/* Try to clone an interface if we don't have a free one */
|
||||
if (sc == NULL) {
|
||||
strcpy(tmpname, PPPNAME);
|
||||
@ -1135,6 +1166,7 @@ pppintr()
|
||||
|
||||
GIANT_REQUIRED;
|
||||
|
||||
PPP_LIST_LOCK();
|
||||
LIST_FOREACH(sc, &ppp_softc_list, sc_list) {
|
||||
s = splimp();
|
||||
if (!(sc->sc_flags & SC_TBUSY)
|
||||
@ -1156,6 +1188,7 @@ pppintr()
|
||||
ppp_inproc(sc, m);
|
||||
}
|
||||
}
|
||||
PPP_LIST_UNLOCK();
|
||||
}
|
||||
|
||||
#ifdef PPP_COMPRESS
|
||||
|
Loading…
x
Reference in New Issue
Block a user