From owner-svn-soc-all@freebsd.org Fri Jun 3 14:09:39 2016 Return-Path: Delivered-To: svn-soc-all@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 1BE3FB68132 for ; Fri, 3 Jun 2016 14:09:39 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (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 00C9F1DCD for ; Fri, 3 Jun 2016 14:09:39 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u53E9cvX060938 for ; Fri, 3 Jun 2016 14:09:38 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u53E9cVr060934 for svn-soc-all@FreeBSD.org; Fri, 3 Jun 2016 14:09:38 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 3 Jun 2016 14:09:38 GMT Message-Id: <201606031409.u53E9cVr060934@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r304518 - soc2016/vincenzo/head/sys/dev/netmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 03 Jun 2016 14:09:39 -0000 Author: vincenzo Date: Fri Jun 3 14:09:37 2016 New Revision: 304518 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=304518 Log: freebsd: ptnet: implement nm_register method Modified: soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c Modified: soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c ============================================================================== --- soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c Fri Jun 3 14:09:15 2016 (r304517) +++ soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c Fri Jun 3 14:09:37 2016 (r304518) @@ -163,6 +163,7 @@ static int ptnet_nm_krings_create(struct netmap_adapter *na); static void ptnet_nm_krings_delete(struct netmap_adapter *na); static void ptnet_nm_dtor(struct netmap_adapter *na); +static int ptnet_nm_register(struct netmap_adapter *na, int onoff); static int ptnet_nm_txsync(struct netmap_kring *kring, int flags); static int ptnet_nm_rxsync(struct netmap_kring *kring, int flags); @@ -350,6 +351,7 @@ na_arg.nm_krings_create = ptnet_nm_krings_create; na_arg.nm_krings_delete = ptnet_nm_krings_delete; na_arg.nm_dtor = ptnet_nm_dtor; + na_arg.nm_register = ptnet_nm_register; na_arg.nm_txsync = ptnet_nm_txsync; na_arg.nm_rxsync = ptnet_nm_rxsync; @@ -735,6 +737,146 @@ netmap_mem_pt_guest_ifp_del(na->nm_mem, na->ifp); } +static void +ptnet_sync_from_csb(struct ptnet_softc *sc, struct netmap_adapter *na) +{ + int i; + + /* Sync krings from the host, reading from + * CSB. */ + for (i = 0; i < sc->num_rings; i++) { + struct ptnet_ring *ptring = sc->queues[i].ptring; + struct netmap_kring *kring; + + if (i < na->num_tx_rings) { + kring = na->tx_rings + i; + } else { + kring = na->rx_rings + i - na->num_tx_rings; + } + kring->rhead = kring->ring->head = ptring->head; + kring->rcur = kring->ring->cur = ptring->cur; + kring->nr_hwcur = ptring->hwcur; + kring->nr_hwtail = kring->rtail = + kring->ring->tail = ptring->hwtail; + + ND("%d,%d: csb {hc %u h %u c %u ht %u}", t, i, + ptring->hwcur, ptring->head, ptring->cur, + ptring->hwtail); + ND("%d,%d: kring {hc %u rh %u rc %u h %u c %u ht %u rt %u t %u}", + t, i, kring->nr_hwcur, kring->rhead, kring->rcur, + kring->ring->head, kring->ring->cur, kring->nr_hwtail, + kring->rtail, kring->ring->tail); + } +} + +#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_fld = _v; \ + } \ + } while (0) \ + +static int +ptnet_nm_register(struct netmap_adapter *na, int onoff) +{ + /* device-specific */ + struct ifnet *ifp = na->ifp; + struct ptnet_softc *sc = ifp->if_softc; + int native = (na == &sc->ptna_nm->hwup.up); + enum txrx t; + int ret = 0; + int i; + + if (!onoff) { + sc->backend_regifs--; + } + + /* If this is the last netmap client, guest interrupt enable flags may + * be in arbitrary state. Since these flags are going to be used also + * by the netdevice driver, we have to make sure to start with + * notifications enabled. Also, schedule NAPI to flush pending packets + * in the RX rings, since we will not receive further interrupts + * 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); + } + + 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); + + /* Make sure the host adapter passed through is ready + * for txsync/rxsync. */ + ret = ptnet_nm_ptctl(ifp, NET_PARAVIRT_PTCTL_REGIF); + if (ret) { + return ret; + } + } + + /* Sync from CSB must be done after REGIF PTCTL. Skip this + * step only if this is a netmap client and it is not the + * first one. */ + if ((!native && sc->backend_regifs == 0) || + (native && na->active_fds == 0)) { + ptnet_sync_from_csb(sc, na); + } + + /* If not native, don't call nm_set_native_flags, since we don't want + * to replace ndo_start_xmit method, nor set NAF_NETMAP_ON */ + if (native) { + for_rx_tx(t) { + for (i=0; inr_mode = NKR_NETMAP_ON; + } + } + } + nm_set_native_flags(na); + } + + } else { + if (native) { + nm_clear_native_flags(na); + for_rx_tx(t) { + for (i=0; inr_mode = NKR_NETMAP_OFF; + } + } + } + } + + /* Sync from CSB must be done before UNREGIF PTCTL, on the last + * netmap client. */ + if (native && na->active_fds == 0) { + ptnet_sync_from_csb(sc, na); + } + + if (sc->backend_regifs == 0) { + ret = ptnet_nm_ptctl(ifp, NET_PARAVIRT_PTCTL_UNREGIF); + } + } + + if (onoff) { + sc->backend_regifs++; + } + + return ret; +} + static int ptnet_nm_txsync(struct netmap_kring *kring, int flags) {