diff options
author | Navdeep Parhar <np@FreeBSD.org> | 2023-09-09 19:39:15 +0000 |
---|---|---|
committer | Navdeep Parhar <np@FreeBSD.org> | 2023-09-19 14:28:28 +0000 |
commit | f976dbaeb482ebbddf70c7374671ce9c27e4ad7f (patch) | |
tree | 017dc6c3d1bf9b1452374d9a8daad1b57da67f26 | |
parent | dda585f2c84be0f04239227249c85c54da58a485 (diff) |
cxgbe(4): Fix tracing with netlink enabled kernels.
1. The tracing ifnet's name must match the nexus name. One way to do
this is to not use a unit number.
2. Do not hold the tracer lock around ether_ifattach or ether_ifdetach.
netlink calls back into the driver (see stack below) and that leads
to illegal lock recursion.
tracer_ioctl
if_ioctl
get_operstate_ether
get_operstate
dump_iface
rtnl_handle_ifevent
rtnl_handle_ifattach
if_attach_internal
if_attach
ether_ifattach
t4_cloner_create
Sponsored by: Chelsio Communications
Approved by: re (kib)
(cherry picked from commit e203cb393fe0b963dd585d0576dcc6a47a28c386)
(cherry picked from commit 38da3db5f9e3e9bc9eba30a2c560bfe660ce95ec)
-rw-r--r-- | sys/dev/cxgbe/t4_tracer.c | 21 |
1 files changed, 7 insertions, 14 deletions
diff --git a/sys/dev/cxgbe/t4_tracer.c b/sys/dev/cxgbe/t4_tracer.c index 4190aa627b14..d9b336c4b64a 100644 --- a/sys/dev/cxgbe/t4_tracer.c +++ b/sys/dev/cxgbe/t4_tracer.c @@ -138,7 +138,7 @@ t4_cloner_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) struct match_rr mrr; struct adapter *sc; if_t ifp; - int rc, unit; + int rc; const uint8_t lla[ETHER_ADDR_LEN] = {0, 0, 0, 0, 0, 0}; mrr.name = name; @@ -166,21 +166,14 @@ t4_cloner_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) goto done; } - - unit = -1; - rc = ifc_alloc_unit(ifc, &unit); - if (rc != 0) - goto done; - ifp = if_alloc(IFT_ETHER); if (ifp == NULL) { - ifc_free_unit(ifc, unit); rc = ENOMEM; goto done; } - /* Note that if_xname is not <if_dname><if_dunit>. */ - if_initname(ifp, name, unit); + /* Note that if_xname is identical to the nexus nameunit */ + if_initname(ifp, name, -1); if_setdname(ifp, t4_cloner_name); if_setinitfn(ifp, tracer_init); if_setflags(ifp, IFF_SIMPLEX | IFF_DRV_RUNNING); @@ -192,12 +185,14 @@ t4_cloner_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) tracer_media_status); ifmedia_add(&sc->media, IFM_ETHER | IFM_FDX | IFM_NONE, 0, NULL); ifmedia_set(&sc->media, IFM_ETHER | IFM_FDX | IFM_NONE); + sx_xunlock(&t4_trace_lock); ether_ifattach(ifp, lla); - + sx_xlock(&t4_trace_lock); mtx_lock(&sc->ifp_lock); if_setsoftc(ifp, sc); sc->ifp = ifp; mtx_unlock(&sc->ifp_lock); + rc = 0; done: sx_xunlock(&t4_trace_lock); end_synchronized_op(sc, 0); @@ -208,7 +203,6 @@ static int t4_cloner_destroy(struct if_clone *ifc, if_t ifp) { struct adapter *sc; - int unit = if_getdunit(ifp); sx_xlock(&t4_trace_lock); sc = if_getsoftc(ifp); @@ -219,10 +213,9 @@ t4_cloner_destroy(struct if_clone *ifc, if_t ifp) mtx_unlock(&sc->ifp_lock); ifmedia_removeall(&sc->media); } + sx_xunlock(&t4_trace_lock); ether_ifdetach(ifp); if_free(ifp); - ifc_free_unit(ifc, unit); - sx_xunlock(&t4_trace_lock); return (0); } |