aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNavdeep Parhar <np@FreeBSD.org>2023-09-09 19:39:15 +0000
committerNavdeep Parhar <np@FreeBSD.org>2023-09-19 14:28:28 +0000
commitf976dbaeb482ebbddf70c7374671ce9c27e4ad7f (patch)
tree017dc6c3d1bf9b1452374d9a8daad1b57da67f26
parentdda585f2c84be0f04239227249c85c54da58a485 (diff)
downloadsrc-f976dbaeb482ebbddf70c7374671ce9c27e4ad7f.tar.gz
src-f976dbaeb482ebbddf70c7374671ce9c27e4ad7f.zip
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.c21
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);
}