socsvn commit: r306420 - in soc2016/vincenzo/head/sys: dev/netmap modules/netmap
vincenzo at FreeBSD.org
vincenzo at FreeBSD.org
Mon Jul 18 09:09:19 UTC 2016
Author: vincenzo
Date: Mon Jul 18 09:09:17 2016
New Revision: 306420
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=306420
Log:
freebsd: ptnet: add control path support for DEVICE_POLLING
Modified:
soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c
soc2016/vincenzo/head/sys/modules/netmap/Makefile
Modified: soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c
==============================================================================
--- soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c Mon Jul 18 09:09:05 2016 (r306419)
+++ soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c Mon Jul 18 09:09:17 2016 (r306420)
@@ -199,6 +199,10 @@
static void ptnet_rx_eof(struct ptnet_queue *pq);
static void ptnet_rx_task(void *context, int pending);
+#ifdef DEVICE_POLLING
+static poll_handler_t ptnet_poll;
+#endif
+
static device_method_t ptnet_methods[] = {
DEVMETHOD(device_probe, ptnet_probe),
DEVMETHOD(device_attach, ptnet_attach),
@@ -406,7 +410,10 @@
}
ifp->if_capenable = ifp->if_capabilities;
-
+#ifdef DEVICE_POLLING
+ /* Don't enable polling by default. */
+ ifp->if_capabilities |= IFCAP_POLLING;
+#endif
snprintf(sc->lock_name, sizeof(sc->lock_name),
"%s", device_get_nameunit(dev));
mtx_init(&sc->lock, sc->lock_name, "ptnet core lock", MTX_DEF);
@@ -467,6 +474,11 @@
struct ptnet_softc *sc = device_get_softc(dev);
int i;
+#ifdef DEVICE_POLLING
+ if (sc->ifp->if_capenable & IFCAP_POLLING) {
+ ether_poll_deregister(sc->ifp);
+ }
+#endif
if (sc->queues) {
/* Drain taskqueues before calling if_detach. */
for (i = 0; i < sc->num_rings; i++) {
@@ -713,7 +725,7 @@
struct ptnet_softc *sc = ifp->if_softc;
device_t dev = sc->dev;
struct ifreq *ifr = (struct ifreq *)data;
- int err = 0;
+ int mask, err = 0;
switch (cmd) {
case SIOCSIFFLAGS:
@@ -734,9 +746,45 @@
case SIOCSIFCAP:
device_printf(dev, "SIOCSIFCAP %x %x\n",
ifr->ifr_reqcap, ifp->if_capenable);
- PTNET_CORE_LOCK(sc);
+ mask = ifr->ifr_reqcap ^ ifp->if_capenable;
+#ifdef DEVICE_POLLING
+ if (mask & IFCAP_POLLING) {
+ struct ptnet_queue *pq;
+ int i;
+
+ if (ifr->ifr_reqcap & IFCAP_POLLING) {
+ err = ether_poll_register(ptnet_poll, ifp);
+ if (err) {
+ break;
+ }
+ /* Stop queues and sync with taskqueues. */
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ for (i = 0; i < sc->num_rings; i++) {
+ pq = sc-> queues + i;
+ /* Make sure the worker sees the
+ * IFF_DRV_RUNNING down. */
+ PTNET_Q_LOCK(pq);
+ pq->ptring->guest_need_kick = 0;
+ PTNET_Q_UNLOCK(pq);
+ /* Wait for rescheduling to finish. */
+ if (pq->taskq) {
+ taskqueue_drain(pq->taskq,
+ &pq->task);
+ }
+ }
+ ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ } else {
+ err = ether_poll_deregister(ifp);
+ for (i = 0; i < sc->num_rings; i++) {
+ pq = sc-> queues + i;
+ PTNET_Q_LOCK(pq);
+ pq->ptring->guest_need_kick = 1;
+ PTNET_Q_UNLOCK(pq);
+ }
+ }
+ }
+#endif /* DEVICE_POLLING */
ifp->if_capenable = ifr->ifr_reqcap;
- PTNET_CORE_UNLOCK(sc);
break;
case SIOCSIFMTU:
@@ -1045,16 +1093,6 @@
}
}
-#define csb_notification_enable_all(_x, _na, _t, _fld, _v) \
- do { \
- struct ptnet_queue *queues = (_x)->queues; \
- int i; \
- if (_t == NR_RX) queues = (_x)->rxqueues; \
- for (i=0; i<nma_get_nrings(_na, _t); i++) { \
- queues[i].ptring->_fld = _v; \
- } \
- } while (0) \
-
static void
ptnet_update_vnet_hdr(struct ptnet_softc *sc)
{
@@ -1070,6 +1108,7 @@
struct ifnet *ifp = na->ifp;
struct ptnet_softc *sc = ifp->if_softc;
int native = (na == &sc->ptna_nm->hwup.up);
+ struct ptnet_queue *pq;
enum txrx t;
int ret = 0;
int i;
@@ -1086,17 +1125,22 @@
* until these will be processed. */
if (native && !onoff && na->active_fds == 0) {
D("Exit netmap mode, re-enable interrupts");
- csb_notification_enable_all(sc, na, NR_TX, guest_need_kick, 1);
- csb_notification_enable_all(sc, na, NR_RX, guest_need_kick, 1);
+ for (i = 0; i < sc->num_rings; i++) {
+ pq = sc->queues + i;
+ pq->ptring->guest_need_kick = 1;
+ }
}
if (onoff) {
if (sc->backend_regifs == 0) {
/* Initialize notification enable fields in the CSB. */
- csb_notification_enable_all(sc, na, NR_TX, host_need_kick, 1);
- csb_notification_enable_all(sc, na, NR_TX, guest_need_kick, 0);
- csb_notification_enable_all(sc, na, NR_RX, host_need_kick, 1);
- csb_notification_enable_all(sc, na, NR_RX, guest_need_kick, 1);
+ for (i = 0; i < sc->num_rings; i++) {
+ pq = sc->queues + i;
+ pq->ptring->host_need_kick = 1;
+ pq->ptring->guest_need_kick =
+ (!(ifp->if_capenable & IFCAP_POLLING)
+ && i >= sc->num_tx_rings);
+ }
/* Set the virtio-net header length. */
ptnet_update_vnet_hdr(sc);
@@ -2078,3 +2122,19 @@
ptnet_drain_transmit_queue(pq);
}
+#ifdef DEVICE_POLLING
+static int
+ptnet_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
+{
+ struct ptnet_softc *sc = ifp->if_softc;
+
+ /* We don't need to handle differently POLL_AND_CHECK_STATUS and
+ * POLL_ONLY, since we don't have an Interrupt Status Register. */
+
+ //rx_done = ptnet_rx_eof(pq)
+ // ptnet_drain_transmit_queue(pq);
+ (void)sc;
+
+ return 0; //(rx_done);
+}
+#endif /* DEVICE_POLLING */
Modified: soc2016/vincenzo/head/sys/modules/netmap/Makefile
==============================================================================
--- soc2016/vincenzo/head/sys/modules/netmap/Makefile Mon Jul 18 09:09:05 2016 (r306419)
+++ soc2016/vincenzo/head/sys/modules/netmap/Makefile Mon Jul 18 09:09:17 2016 (r306420)
@@ -8,7 +8,7 @@
.PATH: ${.CURDIR}/../../dev/netmap
.PATH.h: ${.CURDIR}/../../net
-CFLAGS += -I${.CURDIR}/../../ -D INET
+CFLAGS += -I${.CURDIR}/../../ -D INET -D DEVICE_POLLING
KMOD = netmap
SRCS = device_if.h bus_if.h pci_if.h opt_netmap.h
SRCS += netmap.c netmap.h netmap_kern.h
More information about the svn-soc-all
mailing list