Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 Sep 2014 08:42:33 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r272161 - head/sys/net
Message-ID:  <201409260842.s8Q8gXWZ031807@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Fri Sep 26 08:42:32 2014
New Revision: 272161
URL: http://svnweb.freebsd.org/changeset/base/272161

Log:
  - When reconfiguring protocol on a lagg, first set it to LAGG_PROTO_NONE,
    then drop lock, run the attach routines, and then set it to specific
    proto. This removes tons of WITNESS warnings.
  - Make lagg protocol attach handlers not failing and allocate memory
    with M_WAITOK.
  
  Sponsored by:	Netflix
  Sponsored by:	Nginx, Inc.

Modified:
  head/sys/net/ieee8023ad_lacp.c
  head/sys/net/ieee8023ad_lacp.h
  head/sys/net/if_lagg.c

Modified: head/sys/net/ieee8023ad_lacp.c
==============================================================================
--- head/sys/net/ieee8023ad_lacp.c	Fri Sep 26 08:16:26 2014	(r272160)
+++ head/sys/net/ieee8023ad_lacp.c	Fri Sep 26 08:42:32 2014	(r272161)
@@ -783,16 +783,13 @@ lacp_attach_sysctl_debug(struct lacp_sof
 	    "Bitmap of if_dunit entries to drop TX frames for");
 }
 
-int
+void
 lacp_attach(struct lagg_softc *sc)
 {
 	struct lacp_softc *lsc;
 	struct sysctl_oid *oid;
 
-	lsc = malloc(sizeof(struct lacp_softc),
-	    M_DEVBUF, M_NOWAIT|M_ZERO);
-	if (lsc == NULL)
-		return (ENOMEM);
+	lsc = malloc(sizeof(struct lacp_softc), M_DEVBUF, M_WAITOK | M_ZERO);
 
 	sc->sc_psc = (caddr_t)lsc;
 	lsc->lsc_softc = sc;
@@ -818,21 +815,18 @@ lacp_attach(struct lagg_softc *sc)
 	/* if the lagg is already up then do the same */
 	if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
 		lacp_init(sc);
-
-	return (0);
 }
 
 void
-lacp_detach(struct lagg_softc *sc)
+lacp_detach(void *psc)
 {
-	struct lacp_softc *lsc = LACP_SOFTC(sc);
+	struct lacp_softc *lsc = (struct lacp_softc *)psc;
 
 	KASSERT(TAILQ_EMPTY(&lsc->lsc_aggregators),
 	    ("aggregators still active"));
 	KASSERT(lsc->lsc_active_aggregator == NULL,
 	    ("aggregator still attached"));
 
-	sc->sc_psc = NULL;
 	callout_drain(&lsc->lsc_transit_callout);
 	callout_drain(&lsc->lsc_callout);
 

Modified: head/sys/net/ieee8023ad_lacp.h
==============================================================================
--- head/sys/net/ieee8023ad_lacp.h	Fri Sep 26 08:16:26 2014	(r272160)
+++ head/sys/net/ieee8023ad_lacp.h	Fri Sep 26 08:42:32 2014	(r272161)
@@ -282,8 +282,8 @@ struct lacp_softc {
 
 struct mbuf	*lacp_input(struct lagg_port *, struct mbuf *);
 struct lagg_port *lacp_select_tx_port(struct lagg_softc *, struct mbuf *);
-int		lacp_attach(struct lagg_softc *);
-void		lacp_detach(struct lagg_softc *);
+void		lacp_attach(struct lagg_softc *);
+void		lacp_detach(void *);
 void		lacp_init(struct lagg_softc *);
 void		lacp_stop(struct lagg_softc *);
 int		lacp_port_create(struct lagg_port *);

Modified: head/sys/net/if_lagg.c
==============================================================================
--- head/sys/net/if_lagg.c	Fri Sep 26 08:16:26 2014	(r272160)
+++ head/sys/net/if_lagg.c	Fri Sep 26 08:42:32 2014	(r272161)
@@ -125,19 +125,19 @@ static const void *lagg_gethdr(struct mb
 static int	lagg_sysctl_active(SYSCTL_HANDLER_ARGS);
 
 /* Simple round robin */
-static int	lagg_rr_attach(struct lagg_softc *);
+static void	lagg_rr_attach(struct lagg_softc *);
 static int	lagg_rr_start(struct lagg_softc *, struct mbuf *);
 static struct mbuf *lagg_rr_input(struct lagg_softc *, struct lagg_port *,
 		    struct mbuf *);
 
 /* Active failover */
-static int	lagg_fail_attach(struct lagg_softc *);
+static void	lagg_fail_attach(struct lagg_softc *);
 static int	lagg_fail_start(struct lagg_softc *, struct mbuf *);
 static struct mbuf *lagg_fail_input(struct lagg_softc *, struct lagg_port *,
 		    struct mbuf *);
 
 /* Loadbalancing */
-static int	lagg_lb_attach(struct lagg_softc *);
+static void	lagg_lb_attach(struct lagg_softc *);
 static void	lagg_lb_detach(struct lagg_softc *);
 static int	lagg_lb_port_create(struct lagg_port *);
 static void	lagg_lb_port_destroy(struct lagg_port *);
@@ -147,13 +147,13 @@ static struct mbuf *lagg_lb_input(struct
 static int	lagg_lb_porttable(struct lagg_softc *, struct lagg_port *);
 
 /* Broadcast */
-static int    lagg_bcast_attach(struct lagg_softc *);
+static void	lagg_bcast_attach(struct lagg_softc *);
 static int    lagg_bcast_start(struct lagg_softc *, struct mbuf *);
 static struct mbuf *lagg_bcast_input(struct lagg_softc *, struct lagg_port *,
                   struct mbuf *);
 
 /* 802.3ad LACP */
-static int	lagg_lacp_attach(struct lagg_softc *);
+static void	lagg_lacp_attach(struct lagg_softc *);
 static void	lagg_lacp_detach(struct lagg_softc *);
 static int	lagg_lacp_start(struct lagg_softc *, struct mbuf *);
 static struct mbuf *lagg_lacp_input(struct lagg_softc *, struct lagg_port *,
@@ -163,16 +163,16 @@ static void	lagg_lacp_lladdr(struct lagg
 static void	lagg_callout(void *);
 
 /* lagg protocol table */
-static const struct {
-	int			ti_proto;
-	int			(*ti_attach)(struct lagg_softc *);
+static const struct lagg_proto {
+	lagg_proto	ti_proto;
+	void		(*ti_attach)(struct lagg_softc *);
 } lagg_protos[] = {
 	{ LAGG_PROTO_ROUNDROBIN,	lagg_rr_attach },
-	{ LAGG_PROTO_FAILOVER,	lagg_fail_attach },
+	{ LAGG_PROTO_FAILOVER,		lagg_fail_attach },
 	{ LAGG_PROTO_LOADBALANCE,	lagg_lb_attach },
 	{ LAGG_PROTO_ETHERCHANNEL,	lagg_lb_attach },
 	{ LAGG_PROTO_LACP,		lagg_lacp_attach },
-	{ LAGG_PROTO_BROADCAST,	lagg_bcast_attach },
+	{ LAGG_PROTO_BROADCAST,		lagg_bcast_attach },
 	{ LAGG_PROTO_NONE,		NULL }
 };
 
@@ -281,10 +281,10 @@ lagg_clone_create(struct if_clone *ifc, 
 {
 	struct lagg_softc *sc;
 	struct ifnet *ifp;
-	int i, error = 0;
 	static const u_char eaddr[6];	/* 00:00:00:00:00:00 */
 	struct sysctl_oid *oid;
 	char num[14];			/* sufficient for 32 bits */
+	int i;
 
 	sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
 	ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
@@ -328,11 +328,7 @@ lagg_clone_create(struct if_clone *ifc, 
 	for (i = 0; lagg_protos[i].ti_proto != LAGG_PROTO_NONE; i++) {
 		if (lagg_protos[i].ti_proto == LAGG_PROTO_DEFAULT) {
 			sc->sc_proto = lagg_protos[i].ti_proto;
-			if ((error = lagg_protos[i].ti_attach(sc)) != 0) {
-				if_free(ifp);
-				free(sc, M_DEVBUF);
-				return (error);
-			}
+			lagg_protos[i].ti_attach(sc);
 			break;
 		}
 	}
@@ -403,8 +399,8 @@ lagg_clone_destroy(struct ifnet *ifp)
 	/* Unhook the aggregation protocol */
 	if (sc->sc_detach != NULL)
 		(*sc->sc_detach)(sc);
-
-	LAGG_WUNLOCK(sc);
+	else
+		LAGG_WUNLOCK(sc);
 
 	sysctl_ctx_free(&sc->ctx);
 	ifmedia_removeall(&sc->sc_media);
@@ -984,6 +980,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd
 	struct lagg_reqflags *rf = (struct lagg_reqflags *)data;
 	struct ifreq *ifr = (struct ifreq *)data;
 	struct lagg_port *lp;
+	const struct lagg_proto *proto;
 	struct ifnet *tpif;
 	struct thread *td = curthread;
 	char *buf, *outbuf;
@@ -1031,51 +1028,32 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd
 		error = priv_check(td, PRIV_NET_LAGG);
 		if (error)
 			break;
-		if (ra->ra_proto >= LAGG_PROTO_MAX) {
+		for (proto = lagg_protos; proto->ti_proto != LAGG_PROTO_NONE;
+		    proto++) {
+			if (proto->ti_proto == ra->ra_proto) {
+				if (sc->sc_ifflags & IFF_DEBUG)
+					printf("%s: using proto %u\n",
+					    sc->sc_ifname, proto->ti_proto);
+				break;
+			}
+		}
+		if (proto->ti_proto == LAGG_PROTO_NONE) {
 			error = EPROTONOSUPPORT;
 			break;
 		}
+		/* Set to LAGG_PROTO_NONE during the attach. */
 		LAGG_WLOCK(sc);
 		if (sc->sc_proto != LAGG_PROTO_NONE) {
-			/* Reset protocol first in case detach unlocks */
 			sc->sc_proto = LAGG_PROTO_NONE;
 			if (sc->sc_detach != NULL)
 				sc->sc_detach(sc);
-			sc->sc_detach = NULL;
-			sc->sc_start = NULL;
-			sc->sc_input = NULL;
-			sc->sc_port_create = NULL;
-			sc->sc_port_destroy = NULL;
-			sc->sc_linkstate = NULL;
-			sc->sc_init = NULL;
-			sc->sc_stop = NULL;
-			sc->sc_lladdr = NULL;
-			sc->sc_req = NULL;
-			sc->sc_portreq = NULL;
-		} else if (sc->sc_input != NULL) {
-			/* Still detaching */
-			error = EBUSY;
-		}
-		if (error != 0) {
-			LAGG_WUNLOCK(sc);
-			break;
-		}
-		for (int i = 0; i < (sizeof(lagg_protos) /
-		    sizeof(lagg_protos[0])); i++) {
-			if (lagg_protos[i].ti_proto == ra->ra_proto) {
-				if (sc->sc_ifflags & IFF_DEBUG)
-					printf("%s: using proto %u\n",
-					    sc->sc_ifname,
-					    lagg_protos[i].ti_proto);
-				sc->sc_proto = lagg_protos[i].ti_proto;
-				if (sc->sc_proto != LAGG_PROTO_NONE)
-					error = lagg_protos[i].ti_attach(sc);
+			else
 				LAGG_WUNLOCK(sc);
-				return (error);
-			}
 		}
+		proto->ti_attach(sc);
+		LAGG_WLOCK(sc);
+		sc->sc_proto = proto->ti_proto;
 		LAGG_WUNLOCK(sc);
-		error = EPROTONOSUPPORT;
 		break;
 	case SIOCGLAGGFLAGS:
 		rf->rf_flags = sc->sc_flags;
@@ -1668,8 +1646,7 @@ lagg_enqueue(struct ifnet *ifp, struct m
 /*
  * Simple round robin aggregation
  */
-
-static int
+static void
 lagg_rr_attach(struct lagg_softc *sc)
 {
 	sc->sc_start = lagg_rr_start;
@@ -1678,8 +1655,6 @@ lagg_rr_attach(struct lagg_softc *sc)
 	sc->sc_port_create = NULL;
 	sc->sc_capabilities = IFCAP_LAGG_FULLDUPLEX;
 	sc->sc_seq = 0;
-
-	return (0);
 }
 
 static int
@@ -1721,8 +1696,7 @@ lagg_rr_input(struct lagg_softc *sc, str
 /*
  * Broadcast mode
  */
-
-static int
+static void
 lagg_bcast_attach(struct lagg_softc *sc)
 {
        sc->sc_start = lagg_bcast_start;
@@ -1733,8 +1707,6 @@ lagg_bcast_attach(struct lagg_softc *sc)
        sc->sc_detach = NULL;
        sc->sc_req = NULL;
        sc->sc_portreq = NULL;
-
-       return (0);
 }
 
 static int
@@ -1800,8 +1772,7 @@ lagg_bcast_input(struct lagg_softc *sc, 
 /*
  * Active failover
  */
-
-static int
+static void
 lagg_fail_attach(struct lagg_softc *sc)
 {
 	sc->sc_start = lagg_fail_start;
@@ -1809,8 +1780,6 @@ lagg_fail_attach(struct lagg_softc *sc)
 	sc->sc_port_create = NULL;
 	sc->sc_port_destroy = NULL;
 	sc->sc_detach = NULL;
-
-	return (0);
 }
 
 static int
@@ -1858,16 +1827,13 @@ lagg_fail_input(struct lagg_softc *sc, s
 /*
  * Loadbalancing
  */
-
-static int
+static void
 lagg_lb_attach(struct lagg_softc *sc)
 {
 	struct lagg_port *lp;
 	struct lagg_lb *lb;
 
-	if ((lb = (struct lagg_lb *)malloc(sizeof(struct lagg_lb),
-	    M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
-		return (ENOMEM);
+	lb = malloc(sizeof(struct lagg_lb), M_DEVBUF, M_WAITOK | M_ZERO);
 
 	sc->sc_detach = lagg_lb_detach;
 	sc->sc_start = lagg_lb_start;
@@ -1881,8 +1847,6 @@ lagg_lb_attach(struct lagg_softc *sc)
 
 	SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
 		lagg_lb_port_create(lp);
-
-	return (0);
 }
 
 static void
@@ -1891,6 +1855,7 @@ lagg_lb_detach(struct lagg_softc *sc)
 	struct lagg_lb *lb;
 
 	lb = (struct lagg_lb *)sc->sc_psc;
+	LAGG_WUNLOCK(sc);
 	if (lb != NULL)
 		free(lb, M_DEVBUF);
 }
@@ -1972,12 +1937,10 @@ lagg_lb_input(struct lagg_softc *sc, str
 /*
  * 802.3ad LACP
  */
-
-static int
+static void
 lagg_lacp_attach(struct lagg_softc *sc)
 {
 	struct lagg_port *lp;
-	int error;
 
 	sc->sc_detach = lagg_lacp_detach;
 	sc->sc_port_create = lacp_port_create;
@@ -1991,28 +1954,26 @@ lagg_lacp_attach(struct lagg_softc *sc)
 	sc->sc_req = lacp_req;
 	sc->sc_portreq = lacp_portreq;
 
-	error = lacp_attach(sc);
-	if (error)
-		return (error);
+	lacp_attach(sc);
 
 	SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
 		lacp_port_create(lp);
-
-	return (error);
 }
 
 static void
 lagg_lacp_detach(struct lagg_softc *sc)
 {
 	struct lagg_port *lp;
+	void *psc;
 
 	SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
 		lacp_port_destroy(lp);
 
-	/* unlocking is safe here */
+	psc = sc->sc_psc;
+	sc->sc_psc = NULL;
 	LAGG_WUNLOCK(sc);
-	lacp_detach(sc);
-	LAGG_WLOCK(sc);
+
+	lacp_detach(psc);
 }
 
 static void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409260842.s8Q8gXWZ031807>