From owner-svn-src-head@freebsd.org Mon Dec 12 05:18:05 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 328A7C73B41; Mon, 12 Dec 2016 05:18:05 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E774C299; Mon, 12 Dec 2016 05:18:04 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id uBC5I4mY039786; Mon, 12 Dec 2016 05:18:04 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uBC5I447039784; Mon, 12 Dec 2016 05:18:04 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201612120518.uBC5I447039784@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Mon, 12 Dec 2016 05:18:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r309875 - head/sys/dev/hyperv/netvsc X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 12 Dec 2016 05:18:05 -0000 Author: sephe Date: Mon Dec 12 05:18:03 2016 New Revision: 309875 URL: https://svnweb.freebsd.org/changeset/base/309875 Log: hyperv/hn: Add polling support MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8739 Modified: head/sys/dev/hyperv/netvsc/if_hn.c head/sys/dev/hyperv/netvsc/if_hnvar.h Modified: head/sys/dev/hyperv/netvsc/if_hn.c ============================================================================== --- head/sys/dev/hyperv/netvsc/if_hn.c Mon Dec 12 05:04:55 2016 (r309874) +++ head/sys/dev/hyperv/netvsc/if_hn.c Mon Dec 12 05:18:03 2016 (r309875) @@ -293,6 +293,7 @@ static int hn_txagg_size_sysctl(SYSCTL static int hn_txagg_pkts_sysctl(SYSCTL_HANDLER_ARGS); static int hn_txagg_pktmax_sysctl(SYSCTL_HANDLER_ARGS); static int hn_txagg_align_sysctl(SYSCTL_HANDLER_ARGS); +static int hn_polling_sysctl(SYSCTL_HANDLER_ARGS); static void hn_stop(struct hn_softc *); static void hn_init_locked(struct hn_softc *); @@ -319,6 +320,8 @@ static void hn_resume_mgmt(struct hn_s static void hn_suspend_mgmt_taskfunc(void *, int); static void hn_chan_drain(struct hn_softc *, struct vmbus_channel *); +static void hn_polling(struct hn_softc *, u_int); +static void hn_chan_polling(struct vmbus_channel *, u_int); static void hn_update_link_status(struct hn_softc *); static void hn_change_network(struct hn_softc *); @@ -1117,6 +1120,10 @@ hn_attach(device_t dev) hn_txagg_pkts_sysctl, "I", "Packet transmission aggregation packets, " "0 -- disable, -1 -- auto"); + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "polling", + CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0, + hn_polling_sysctl, "I", + "Polling frequency: [100,1000000], 0 disable polling"); /* * Setup the ifmedia, which has been initialized earlier. @@ -2360,6 +2367,9 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, break; } + /* Disable polling. */ + hn_polling(sc, 0); + /* * Suspend this interface before the synthetic parts * are ripped. @@ -2405,6 +2415,13 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, */ hn_resume(sc); + /* + * Re-enable polling if this interface is running and + * the polling is requested. + */ + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && sc->hn_pollhz > 0) + hn_polling(sc, sc->hn_pollhz); + HN_UNLOCK(sc); break; @@ -2531,6 +2548,9 @@ hn_stop(struct hn_softc *sc) KASSERT(sc->hn_flags & HN_FLAG_SYNTH_ATTACHED, ("synthetic parts were not attached")); + /* Disable polling. */ + hn_polling(sc, 0); + /* Clear RUNNING bit _before_ hn_suspend_data() */ atomic_clear_int(&ifp->if_drv_flags, IFF_DRV_RUNNING); hn_suspend_data(sc); @@ -2568,6 +2588,10 @@ hn_init_locked(struct hn_softc *sc) /* Everything is ready; unleash! */ atomic_set_int(&ifp->if_drv_flags, IFF_DRV_RUNNING); + + /* Re-enable polling if requested. */ + if (sc->hn_pollhz > 0) + hn_polling(sc, sc->hn_pollhz); } static void @@ -2875,6 +2899,61 @@ hn_txagg_align_sysctl(SYSCTL_HANDLER_ARG return (sysctl_handle_int(oidp, &align, 0, req)); } +static void +hn_chan_polling(struct vmbus_channel *chan, u_int pollhz) +{ + if (pollhz == 0) + vmbus_chan_poll_disable(chan); + else + vmbus_chan_poll_enable(chan, pollhz); +} + +static void +hn_polling(struct hn_softc *sc, u_int pollhz) +{ + int nsubch = sc->hn_rx_ring_inuse - 1; + + HN_LOCK_ASSERT(sc); + + if (nsubch > 0) { + struct vmbus_channel **subch; + int i; + + subch = vmbus_subchan_get(sc->hn_prichan, nsubch); + for (i = 0; i < nsubch; ++i) + hn_chan_polling(subch[i], pollhz); + vmbus_subchan_rel(subch, nsubch); + } + hn_chan_polling(sc->hn_prichan, pollhz); +} + +static int +hn_polling_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct hn_softc *sc = arg1; + int pollhz, error; + + pollhz = sc->hn_pollhz; + error = sysctl_handle_int(oidp, &pollhz, 0, req); + if (error || req->newptr == NULL) + return (error); + + if (pollhz != 0 && + (pollhz < VMBUS_CHAN_POLLHZ_MIN || pollhz > VMBUS_CHAN_POLLHZ_MAX)) + return (EINVAL); + + HN_LOCK(sc); + if (sc->hn_pollhz != pollhz) { + sc->hn_pollhz = pollhz; + if ((sc->hn_ifp->if_drv_flags & IFF_DRV_RUNNING) && + (sc->hn_flags & HN_FLAG_SYNTH_ATTACHED)) + hn_polling(sc, sc->hn_pollhz); + } + HN_UNLOCK(sc); + + return (0); +} + static int hn_ndis_version_sysctl(SYSCTL_HANDLER_ARGS) { Modified: head/sys/dev/hyperv/netvsc/if_hnvar.h ============================================================================== --- head/sys/dev/hyperv/netvsc/if_hnvar.h Mon Dec 12 05:04:55 2016 (r309874) +++ head/sys/dev/hyperv/netvsc/if_hnvar.h Mon Dec 12 05:18:03 2016 (r309875) @@ -212,6 +212,8 @@ struct hn_softc { uint32_t hn_caps; /* HN_CAP_ */ uint32_t hn_flags; /* HN_FLAG_ */ + u_int hn_pollhz; + void *hn_rxbuf; uint32_t hn_rxbuf_gpadl; struct hyperv_dma hn_rxbuf_dma;