From e87c4940156c9a218cab4fd35f4d487dc57e7aa3 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Mon, 24 Feb 2020 21:07:30 +0000 Subject: [PATCH] Although most of the NIC drivers are epoch ready, due to peer pressure switch over to opt-in instead of opt-out for epoch. Instead of IFF_NEEDSEPOCH, provide IFF_KNOWSEPOCH. If driver marks itself with IFF_KNOWSEPOCH, then ether_input() would not enter epoch when processing its packets. Now this will create recursive entrance in epoch in >90% network drivers, but will guarantee safeness of the transition. Mark several tested drivers as IFF_KNOWSEPOCH. Reviewed by: hselasky, jeff, bz, gallatin Differential Revision: https://reviews.freebsd.org/D23674 --- sys/dev/beri/virtio/network/if_vtbe.c | 2 +- sys/dev/dpaa/if_dtsec.c | 2 +- sys/dev/hyperv/netvsc/if_hn.c | 3 +-- sys/dev/if_ndis/if_ndis.c | 3 +-- sys/dev/mlx5/mlx5_en/mlx5_en_main.c | 3 ++- sys/dev/ntb/if_ntb/if_ntb.c | 3 +-- sys/dev/sbni/if_sbni.c | 3 +-- sys/dev/virtio/network/if_vtnet.c | 3 ++- sys/mips/nlm/dev/net/xlpge.c | 3 +-- sys/net/if.c | 6 ++---- sys/net/if.h | 4 ++-- sys/net/if_ethersubr.c | 7 +++++-- sys/net/iflib.c | 3 ++- 13 files changed, 22 insertions(+), 23 deletions(-) diff --git a/sys/dev/beri/virtio/network/if_vtbe.c b/sys/dev/beri/virtio/network/if_vtbe.c index 03853435a9de..5975a4a1c7f3 100644 --- a/sys/dev/beri/virtio/network/if_vtbe.c +++ b/sys/dev/beri/virtio/network/if_vtbe.c @@ -613,7 +613,7 @@ vtbe_attach(device_t dev) ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX | - IFF_MULTICAST | IFF_PROMISC | IFF_NEEDSEPOCH); + IFF_MULTICAST | IFF_PROMISC); ifp->if_capabilities = IFCAP_VLAN_MTU; ifp->if_capenable = ifp->if_capabilities; ifp->if_start = vtbe_txstart; diff --git a/sys/dev/dpaa/if_dtsec.c b/sys/dev/dpaa/if_dtsec.c index 704aa22eda54..2c6291b07e34 100644 --- a/sys/dev/dpaa/if_dtsec.c +++ b/sys/dev/dpaa/if_dtsec.c @@ -688,7 +688,7 @@ dtsec_attach(device_t dev) ifp->if_softc = sc; ifp->if_mtu = ETHERMTU; /* TODO: Configure */ - ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_NEEDSEPOCH; + ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST; ifp->if_init = dtsec_if_init; ifp->if_start = dtsec_if_start; ifp->if_ioctl = dtsec_if_ioctl; diff --git a/sys/dev/hyperv/netvsc/if_hn.c b/sys/dev/hyperv/netvsc/if_hn.c index bc96775ad553..e9d1b9439671 100644 --- a/sys/dev/hyperv/netvsc/if_hn.c +++ b/sys/dev/hyperv/netvsc/if_hn.c @@ -2362,8 +2362,7 @@ hn_attach(device_t dev) */ ifp->if_baudrate = IF_Gbps(10); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | - IFF_NEEDSEPOCH; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = hn_ioctl; ifp->if_init = hn_init; #ifdef HN_IFSTART_SUPPORT diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c index 37cf0e6bf703..1a5e8eeed4be 100644 --- a/sys/dev/if_ndis/if_ndis.c +++ b/sys/dev/if_ndis/if_ndis.c @@ -967,8 +967,7 @@ ndis_ifattach(struct ndis_softc *sc) if_initname(ifp, device_get_name(sc->ndis_dev), device_get_unit(sc->ndis_dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | - IFF_NEEDSEPOCH; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = ndis_ifioctl; ifp->if_start = ndis_ifstart; ifp->if_init = ndis_init; diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c index 98f06af5230c..45aa824eae9b 100644 --- a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c +++ b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c @@ -4275,7 +4275,8 @@ mlx5e_create_ifp(struct mlx5_core_dev *mdev) if_initname(ifp, "mce", device_get_unit(mdev->pdev->dev.bsddev)); ifp->if_mtu = ETHERMTU; ifp->if_init = mlx5e_open; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | + IFF_KNOWSEPOCH; ifp->if_ioctl = mlx5e_ioctl; ifp->if_transmit = mlx5e_xmit; ifp->if_qflush = if_qflush; diff --git a/sys/dev/ntb/if_ntb/if_ntb.c b/sys/dev/ntb/if_ntb/if_ntb.c index 1e1f98a54132..3bae01aae49d 100644 --- a/sys/dev/ntb/if_ntb/if_ntb.c +++ b/sys/dev/ntb/if_ntb/if_ntb.c @@ -172,8 +172,7 @@ ntb_net_attach(device_t dev) if_setinitfn(ifp, ntb_net_init); if_setsoftc(ifp, sc); - if_setflags(ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | - IFF_NEEDSEPOCH); + if_setflags(ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST); if_setioctlfn(ifp, ntb_ioctl); if_settransmitfn(ifp, ntb_transmit); if_setqflushfn(ifp, ntb_qflush); diff --git a/sys/dev/sbni/if_sbni.c b/sys/dev/sbni/if_sbni.c index 62b86112b26f..267001f7897d 100644 --- a/sys/dev/sbni/if_sbni.c +++ b/sys/dev/sbni/if_sbni.c @@ -243,8 +243,7 @@ sbni_attach(struct sbni_softc *sc, int unit, struct sbni_flags flags) ifp->if_baudrate = (csr0 & 0x01 ? 500000 : 2000000) / (1 << flags.rate); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | - IFF_NEEDSEPOCH; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; mtx_init(&sc->lock, ifp->if_xname, MTX_NETWORK_LOCK, MTX_DEF); callout_init_mtx(&sc->wch, &sc->lock, 0); diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c index ceb3ffaaf2b4..b388e43d92a6 100644 --- a/sys/dev/virtio/network/if_vtnet.c +++ b/sys/dev/virtio/network/if_vtnet.c @@ -950,7 +950,8 @@ vtnet_setup_interface(struct vtnet_softc *sc) if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_baudrate = IF_Gbps(10); /* Approx. */ ifp->if_softc = sc; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | + IFF_KNOWSEPOCH; ifp->if_init = vtnet_init; ifp->if_ioctl = vtnet_ioctl; ifp->if_get_counter = vtnet_get_counter; diff --git a/sys/mips/nlm/dev/net/xlpge.c b/sys/mips/nlm/dev/net/xlpge.c index e1beb9ad79aa..ac0c4d6e843d 100644 --- a/sys/mips/nlm/dev/net/xlpge.c +++ b/sys/mips/nlm/dev/net/xlpge.c @@ -1052,8 +1052,7 @@ nlm_xlpge_ifinit(struct nlm_xlpge_softc *sc) } ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | - IFF_NEEDSEPOCH; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; sc->if_flags = ifp->if_flags; /*ifp->if_capabilities = IFCAP_TXCSUM | IFCAP_VLAN_HWTAGGING;*/ ifp->if_capabilities = 0; diff --git a/sys/net/if.c b/sys/net/if.c index 42d34bb21ddb..d1c3cfba811c 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -551,8 +551,6 @@ if_alloc_domain(u_char type, int numa_domain) #ifdef VIMAGE ifp->if_vnet = curvnet; #endif - /* XXX */ - ifp->if_flags |= IFF_NEEDSEPOCH; if (if_com_alloc[type] != NULL) { ifp->if_l2com = if_com_alloc[type](type, ifp); if (ifp->if_l2com == NULL) { @@ -4167,8 +4165,8 @@ if_setdrvflags(if_t ifp, int flags) int if_setflags(if_t ifp, int flags) { - /* XXX Temporary */ - ((struct ifnet *)ifp)->if_flags = flags | IFF_NEEDSEPOCH; + + ifp->if_flags = flags; return (0); } diff --git a/sys/net/if.h b/sys/net/if.h index 974074473e1b..1e7430263fc3 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -144,7 +144,7 @@ struct if_data { #define IFF_DEBUG 0x4 /* (n) turn on debugging */ #define IFF_LOOPBACK 0x8 /* (i) is a loopback net */ #define IFF_POINTOPOINT 0x10 /* (i) is a point-to-point link */ -#define IFF_NEEDSEPOCH 0x20 /* (i) calls if_input w/o epoch */ +#define IFF_KNOWSEPOCH 0x20 /* (i) calls if_input in net epoch */ #define IFF_DRV_RUNNING 0x40 /* (d) resources allocated */ #define IFF_NOARP 0x80 /* (n) no address resolution protocol */ #define IFF_PROMISC 0x100 /* (n) receive all packets */ @@ -178,7 +178,7 @@ struct if_data { #define IFF_CANTCHANGE \ (IFF_BROADCAST|IFF_POINTOPOINT|IFF_DRV_RUNNING|IFF_DRV_OACTIVE|\ IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI|IFF_PROMISC|\ - IFF_DYING|IFF_CANTCONFIG) + IFF_DYING|IFF_CANTCONFIG|IFF_KNOWSEPOCH) /* * Values for if_link_state. diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index 7d918216b300..6d33173462cb 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -802,6 +802,9 @@ ether_input(struct ifnet *ifp, struct mbuf *m) { struct epoch_tracker et; struct mbuf *mn; + bool needs_epoch; + + needs_epoch = !(ifp->if_flags & IFF_KNOWSEPOCH); /* * The drivers are allowed to pass in a chain of packets linked with @@ -809,7 +812,7 @@ ether_input(struct ifnet *ifp, struct mbuf *m) * them up. This allows the drivers to amortize the receive lock. */ CURVNET_SET_QUIET(ifp->if_vnet); - if (__predict_false(ifp->if_flags & IFF_NEEDSEPOCH)) + if (__predict_false(needs_epoch)) NET_EPOCH_ENTER(et); while (m) { mn = m->m_nextpkt; @@ -825,7 +828,7 @@ ether_input(struct ifnet *ifp, struct mbuf *m) netisr_dispatch(NETISR_ETHER, m); m = mn; } - if (__predict_false(ifp->if_flags & IFF_NEEDSEPOCH)) + if (__predict_false(needs_epoch)) NET_EPOCH_EXIT(et); CURVNET_RESTORE(); } diff --git a/sys/net/iflib.c b/sys/net/iflib.c index d06fbf6ec01b..95fbdbf7c446 100644 --- a/sys/net/iflib.c +++ b/sys/net/iflib.c @@ -5400,7 +5400,8 @@ iflib_register(if_ctx_t ctx) if_settransmitfn(ifp, iflib_if_transmit); #endif if_setqflushfn(ifp, iflib_if_qflush); - if_setflags(ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST); + if_setflags(ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | + IFF_KNOWSEPOCH); ctx->ifc_vlan_attach_event = EVENTHANDLER_REGISTER(vlan_config, iflib_vlan_register, ctx,