diff options
author | John Baldwin <jhb@FreeBSD.org> | 2019-05-01 21:45:15 +0000 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2019-05-01 21:45:15 +0000 |
commit | 4903b7a19472fd3366c19d37a2747ef8e4e8fa8c (patch) | |
tree | 55d98adb159777fc0947d741935ac9e66077f94a | |
parent | acf18fcbfc61a7f27c5a1f511df4efcafa9d5d02 (diff) | |
download | src-test2-4903b7a19472fd3366c19d37a2747ef8e4e8fa8c.tar.gz src-test2-4903b7a19472fd3366c19d37a2747ef8e4e8fa8c.zip |
Notes
-rw-r--r-- | sys/net/if_lagg.c | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c index efb91e875ef3..cec12588a734 100644 --- a/sys/net/if_lagg.c +++ b/sys/net/if_lagg.c @@ -750,7 +750,6 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp) * is predictable and `ifconfig laggN create ...` command * will lead to the same result each time. */ - LAGG_RLOCK(); CK_SLIST_FOREACH(tlp, &sc->sc_ports, lp_entries) { if (tlp->lp_ifp->if_index < ifp->if_index && ( CK_SLIST_NEXT(tlp, lp_entries) == NULL || @@ -758,7 +757,6 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp) ifp->if_index)) break; } - LAGG_RUNLOCK(); if (tlp != NULL) CK_SLIST_INSERT_AFTER(tlp, lp, lp_entries); else @@ -1536,14 +1534,17 @@ lagg_snd_tag_alloc(struct ifnet *ifp, struct lagg_lb *lb; uint32_t p; + LAGG_RLOCK(); switch (sc->sc_proto) { case LAGG_PROTO_FAILOVER: lp = lagg_link_active(sc, sc->sc_primary); break; case LAGG_PROTO_LOADBALANCE: if ((sc->sc_opts & LAGG_OPT_USE_FLOWID) == 0 || - params->hdr.flowtype == M_HASHTYPE_NONE) + params->hdr.flowtype == M_HASHTYPE_NONE) { + LAGG_RUNLOCK(); return (EOPNOTSUPP); + } p = params->hdr.flowid >> sc->flowid_shift; p %= sc->sc_count; lb = (struct lagg_lb *)sc->sc_psc; @@ -1552,16 +1553,22 @@ lagg_snd_tag_alloc(struct ifnet *ifp, break; case LAGG_PROTO_LACP: if ((sc->sc_opts & LAGG_OPT_USE_FLOWID) == 0 || - params->hdr.flowtype == M_HASHTYPE_NONE) + params->hdr.flowtype == M_HASHTYPE_NONE) { + LAGG_RUNLOCK(); return (EOPNOTSUPP); + } lp = lacp_select_tx_port_by_hash(sc, params->hdr.flowid); break; default: + LAGG_RUNLOCK(); return (EOPNOTSUPP); } - if (lp == NULL) + if (lp == NULL) { + LAGG_RUNLOCK(); return (EOPNOTSUPP); + } ifp = lp->lp_ifp; + LAGG_RUNLOCK(); if (ifp == NULL || ifp->if_snd_tag_alloc == NULL || (ifp->if_capenable & IFCAP_TXRTLMT) == 0) return (EOPNOTSUPP); @@ -1845,12 +1852,18 @@ struct lagg_port * lagg_link_active(struct lagg_softc *sc, struct lagg_port *lp) { struct lagg_port *lp_next, *rval = NULL; - struct epoch_tracker net_et; /* * Search a port which reports an active link state. */ + /* + * This is called with either LAGG_RLOCK() held or + * LAGG_XLOCK(sc) held. + */ + if (!in_epoch(net_epoch_preempt)) + LAGG_XLOCK_ASSERT(sc); + if (lp == NULL) goto search; if (LAGG_PORTACTIVE(lp)) { @@ -1863,15 +1876,12 @@ lagg_link_active(struct lagg_softc *sc, struct lagg_port *lp) goto found; } - search: - epoch_enter_preempt(net_epoch_preempt, &net_et); +search: CK_SLIST_FOREACH(lp_next, &sc->sc_ports, lp_entries) { if (LAGG_PORTACTIVE(lp_next)) { - epoch_exit_preempt(net_epoch_preempt, &net_et); return (lp_next); } } - epoch_exit_preempt(net_epoch_preempt, &net_et); found: return (rval); } @@ -1953,7 +1963,7 @@ lagg_bcast_start(struct lagg_softc *sc, struct mbuf *m) struct lagg_port *lp, *last = NULL; struct mbuf *m0; - LAGG_RLOCK(); + LAGG_RLOCK_ASSERT(); CK_SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { if (!LAGG_PORTACTIVE(lp)) continue; @@ -1974,7 +1984,6 @@ lagg_bcast_start(struct lagg_softc *sc, struct mbuf *m) } last = lp; } - LAGG_RUNLOCK(); if (last == NULL) { m_freem(m); @@ -2087,7 +2096,7 @@ lagg_lb_porttable(struct lagg_softc *sc, struct lagg_port *lp) rv = 0; bzero(&lb->lb_ports, sizeof(lb->lb_ports)); - LAGG_RLOCK(); + LAGG_XLOCK_ASSERT(sc); CK_SLIST_FOREACH(lp_next, &sc->sc_ports, lp_entries) { if (lp_next == lp) continue; @@ -2100,7 +2109,6 @@ lagg_lb_porttable(struct lagg_softc *sc, struct lagg_port *lp) sc->sc_ifname, lp_next->lp_ifp->if_xname, i); lb->lb_ports[i++] = lp_next; } - LAGG_RUNLOCK(); return (rv); } |