aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincenzo Maffione <vmaffione@FreeBSD.org>2022-01-14 21:09:04 +0000
committerVincenzo Maffione <vmaffione@FreeBSD.org>2022-02-13 10:20:55 +0000
commitea25a6af57e0ce1551341e3b1652233cdb11bee1 (patch)
treedd2ec273458531e75fe9a8df4e02697f1a73cf84
parent2460d015c9dcfed280711244fa9ddfc3798b574f (diff)
netmap: fix LOR in iflib_netmap_register
In iflib_device_register(), the CTX_LOCK is acquired first and then IFNET_WLOCK is acquired by ether_ifattach(). However, in netmap_hw_reg() we do the opposite: IFNET_RLOCK is acquired first, and then CTX_LOCK is acquired by iflib_netmap_register(). Fix this LOR issue by wrapping the CTX_LOCK/UNLOCK calls in iflib_device_register with an additional IFNET_WLOCK. This is safe since the IFNET_WLOCK is recursive. MFC after: 1 month (cherry picked from commit e0e12405285b61a724c646b8f8e99e3ec775291e)
-rw-r--r--sys/net/iflib.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/sys/net/iflib.c b/sys/net/iflib.c
index d2d073b82945..f057b7deba91 100644
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -5021,6 +5021,7 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct
ifp = ctx->ifc_ifp;
iflib_reset_qvalues(ctx);
+ IFNET_WLOCK();
CTX_LOCK(ctx);
if ((err = IFDI_ATTACH_PRE(ctx)) != 0) {
device_printf(dev, "IFDI_ATTACH_PRE failed %d\n", err);
@@ -5218,6 +5219,7 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct
iflib_add_device_sysctl_post(ctx);
ctx->ifc_flags |= IFC_INIT_DONE;
CTX_UNLOCK(ctx);
+ IFNET_WUNLOCK();
return (0);
@@ -5233,6 +5235,7 @@ fail_intr_free:
iflib_free_intr_mem(ctx);
fail_unlock:
CTX_UNLOCK(ctx);
+ IFNET_WUNLOCK();
iflib_deregister(ctx);
fail_ctx_free:
device_set_softc(ctx->ifc_dev, NULL);