From owner-freebsd-net@FreeBSD.ORG Thu Sep 20 08:48:06 2012 Return-Path: Delivered-To: net@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9BE4B1065672; Thu, 20 Sep 2012 08:48:06 +0000 (UTC) (envelope-from glebius@FreeBSD.org) Received: from cell.glebius.int.ru (glebius.int.ru [81.19.64.117]) by mx1.freebsd.org (Postfix) with ESMTP id 134398FC15; Thu, 20 Sep 2012 08:48:05 +0000 (UTC) Received: from cell.glebius.int.ru (localhost [127.0.0.1]) by cell.glebius.int.ru (8.14.5/8.14.5) with ESMTP id q8K8m48f046568; Thu, 20 Sep 2012 12:48:04 +0400 (MSK) (envelope-from glebius@FreeBSD.org) Received: (from glebius@localhost) by cell.glebius.int.ru (8.14.5/8.14.5/Submit) id q8K8m4Yh046567; Thu, 20 Sep 2012 12:48:04 +0400 (MSK) (envelope-from glebius@FreeBSD.org) X-Authentication-Warning: cell.glebius.int.ru: glebius set sender to glebius@FreeBSD.org using -f Date: Thu, 20 Sep 2012 12:48:04 +0400 From: Gleb Smirnoff To: Andrew Thompson Message-ID: <20120920084804.GY85604@glebius.int.ru> References: <20120920074730.GS85604@FreeBSD.org> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="poJSiGMzRSvrLGLs" Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) Cc: net@FreeBSD.org Subject: Re: [CFT] if_transmit method for lagg(4) X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 20 Sep 2012 08:48:06 -0000 --poJSiGMzRSvrLGLs Content-Type: text/plain; charset=koi8-r Content-Disposition: inline Hi! On Thu, Sep 20, 2012 at 08:37:19PM +1200, Andrew Thompson wrote: A> > Yet another patch to test. Was suprising to me that lagg(4), which A> > aims at high-performance, still utilizes if_start. A> > A> > Attached is patch that converts lagg(4) to use if_transmit. I'd A> > appreciate if someone who do use lagg(4) tests the patch. If anyone A> > benchmarks lagg(4) with and w/o patch that will be most appreciated. A> A> Sean Bruno has already tested this patch at Yahoo, I have just been A> delayed in committing it. There are just a few small differences so we A> can commit one or merge. Also fabient@ replied to me in private with this patch :) Hmm, I've missed stats update. I have merge statistics updates from your patch to mine and here it is attached. -- Totus tuus, Glebius. --poJSiGMzRSvrLGLs Content-Type: text/x-diff; charset=koi8-r Content-Disposition: attachment; filename="if_lagg.c.diff" Index: if_lagg.c =================================================================== --- if_lagg.c (revision 240735) +++ if_lagg.c (working copy) @@ -110,7 +110,8 @@ static int lagg_setflag(struct lagg_port *, int, int, int (*func)(struct ifnet *, int)); static int lagg_setflags(struct lagg_port *, int status); -static void lagg_start(struct ifnet *); +static int lagg_transmit(struct ifnet *i, struct mbuf *); +static void lagg_qflush(struct ifnet *); static int lagg_media_change(struct ifnet *); static void lagg_media_status(struct ifnet *, struct ifmediareq *); static struct lagg_port *lagg_link_active(struct lagg_softc *, @@ -312,15 +313,12 @@ if_initname(ifp, ifc->ifc_name, unit); ifp->if_softc = sc; - ifp->if_start = lagg_start; + ifp->if_transmit = lagg_transmit; + ifp->if_qflush = lagg_qflush; ifp->if_init = lagg_init; ifp->if_ioctl = lagg_ioctl; ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - /* * Attach as an ordinary ethernet device, children will be attached * as special device IFT_IEEE8023ADLAG. @@ -1222,37 +1220,47 @@ return (0); } -static void -lagg_start(struct ifnet *ifp) +static int +lagg_transmit(struct ifnet *ifp, struct mbuf *m) { struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc; - struct mbuf *m; - int error = 0; + int error, len, mcast; + len = m->m_pkthdr.len; + mcast = (m->m_flags & (M_MCAST | M_BCAST)) ? 1 : 0; + LAGG_RLOCK(sc); /* We need a Tx algorithm and at least one port */ if (sc->sc_proto == LAGG_PROTO_NONE || sc->sc_count == 0) { - IF_DRAIN(&ifp->if_snd); LAGG_RUNLOCK(sc); - return; + m_freem(m); + ifp->if_oerrors++; + return (ENXIO); } - for (;; error = 0) { - IFQ_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; + ETHER_BPF_MTAP(ifp, m); - ETHER_BPF_MTAP(ifp, m); + error = (*sc->sc_start)(sc, m); + LAGG_RUNLOCK(sc); - error = (*sc->sc_start)(sc, m); - if (error == 0) - ifp->if_opackets++; - else - ifp->if_oerrors++; - } - LAGG_RUNLOCK(sc); + if (error == 0) { + ifp->if_opackets++; + ifp->if_omcasts += mcast; + ifp->if_obytes += len; + } else + ifp->if_oerrors++; + + return (error); } +/* + * The ifp->if_qflush entry point for lagg(4) is no-op. + */ +static void +lagg_qflush(struct ifnet *ifp __unused) +{ +} + static struct mbuf * lagg_input(struct ifnet *ifp, struct mbuf *m) { --poJSiGMzRSvrLGLs--