From owner-svn-src-all@FreeBSD.ORG Wed Jan 23 03:51:48 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 525555CE; Wed, 23 Jan 2013 03:51:48 +0000 (UTC) (envelope-from luigi@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 4475B7EA; Wed, 23 Jan 2013 03:51:48 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r0N3pmSH038464; Wed, 23 Jan 2013 03:51:48 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r0N3pl7I038461; Wed, 23 Jan 2013 03:51:47 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201301230351.r0N3pl7I038461@svn.freebsd.org> From: Luigi Rizzo Date: Wed, 23 Jan 2013 03:51:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r245835 - head/sys/dev/netmap X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 23 Jan 2013 03:51:48 -0000 Author: luigi Date: Wed Jan 23 03:51:47 2013 New Revision: 245835 URL: http://svnweb.freebsd.org/changeset/base/245835 Log: control some debugging messages with dev.netmap.verbose add infrastracture to adapt to changes in number of queues and buffers at runtime Modified: head/sys/dev/netmap/netmap.c head/sys/dev/netmap/netmap_kern.h head/sys/dev/netmap/netmap_mem2.c Modified: head/sys/dev/netmap/netmap.c ============================================================================== --- head/sys/dev/netmap/netmap.c Wed Jan 23 03:49:48 2013 (r245834) +++ head/sys/dev/netmap/netmap.c Wed Jan 23 03:51:47 2013 (r245835) @@ -275,6 +275,51 @@ nm_find_bridge(const char *name) } #endif /* NM_BRIDGE */ + +/* + * Fetch configuration from the device, to cope with dynamic + * reconfigurations after loading the module. + */ +static int +netmap_update_config(struct netmap_adapter *na) +{ + struct ifnet *ifp = na->ifp; + u_int txr, txd, rxr, rxd; + + txr = txd = rxr = rxd = 0; + if (na->nm_config) { + na->nm_config(ifp, &txr, &txd, &rxr, &rxd); + } else { + /* take whatever we had at init time */ + txr = na->num_tx_rings; + txd = na->num_tx_desc; + rxr = na->num_rx_rings; + rxd = na->num_rx_desc; + } + + if (na->num_tx_rings == txr && na->num_tx_desc == txd && + na->num_rx_rings == rxr && na->num_rx_desc == rxd) + return 0; /* nothing changed */ + if (netmap_verbose || na->refcount > 0) { + D("stored config %s: txring %d x %d, rxring %d x %d", + ifp->if_xname, + na->num_tx_rings, na->num_tx_desc, + na->num_rx_rings, na->num_rx_desc); + D("new config %s: txring %d x %d, rxring %d x %d", + ifp->if_xname, txr, txd, rxr, rxd); + } + if (na->refcount == 0) { + D("configuration changed (but fine)"); + na->num_tx_rings = txr; + na->num_tx_desc = txd; + na->num_rx_rings = rxr; + na->num_rx_desc = rxd; + return 0; + } + D("configuration changed while active, this is bad..."); + return 1; +} + /*------------- memory allocator -----------------*/ #ifdef NETMAP_MEM2 #include "netmap_mem2.c" @@ -351,7 +396,8 @@ netmap_dtor_locked(void *data) if (na->refcount <= 0) { /* last instance */ u_int i, j, lim; - D("deleting last netmap instance for %s", ifp->if_xname); + if (netmap_verbose) + D("deleting last instance for %s", ifp->if_xname); /* * there is a race here with *_netmap_task() and * netmap_poll(), which don't run under NETMAP_REG_LOCK. @@ -482,7 +528,8 @@ static int netmap_dev_pager_ctor(void *handle, vm_ooffset_t size, vm_prot_t prot, vm_ooffset_t foff, struct ucred *cred, u_short *color) { - D("first mmap for %p", handle); + if (netmap_verbose) + D("first mmap for %p", handle); return saved_cdev_pager_ops.cdev_pg_ctor(handle, size, prot, foff, cred, color); } @@ -491,7 +538,7 @@ static void netmap_dev_pager_dtor(void *handle) { saved_cdev_pager_ops.cdev_pg_dtor(handle); - D("ready to release memory for %p", handle); + ND("ready to release memory for %p", handle); } @@ -507,7 +554,7 @@ netmap_mmap_single(struct cdev *cdev, vm { vm_object_t obj; - D("cdev %p foff %jd size %jd objp %p prot %d", cdev, + ND("cdev %p foff %jd size %jd objp %p prot %d", cdev, (intmax_t )*foff, (intmax_t )objsize, objp, prot); obj = vm_pager_allocate(OBJT_DEVICE, cdev, objsize, prot, *foff, curthread->td_ucred); @@ -515,7 +562,7 @@ netmap_mmap_single(struct cdev *cdev, vm if (obj == NULL) return EINVAL; if (saved_cdev_pager_ops.cdev_pg_fault == NULL) { - D("initialize cdev_pager_ops"); + ND("initialize cdev_pager_ops"); saved_cdev_pager_ops = *(obj->un_pager.devp.ops); netmap_cdev_pager_ops.cdev_pg_fault = saved_cdev_pager_ops.cdev_pg_fault; @@ -572,7 +619,9 @@ netmap_mmap(__unused struct cdev *dev, static int netmap_close(struct cdev *dev, int fflag, int devtype, struct thread *td) { - D("dev %p fflag 0x%x devtype %d td %p", dev, fflag, devtype, td); + if (netmap_verbose) + D("dev %p fflag 0x%x devtype %d td %p", + dev, fflag, devtype, td); return 0; } @@ -877,6 +926,7 @@ netmap_set_ringid(struct netmap_priv_d * priv->np_txpoll = (ringid & NETMAP_NO_TX_POLL) ? 0 : 1; if (need_lock) na->nm_lock(ifp, NETMAP_CORE_UNLOCK, 0); + if (netmap_verbose) { if (ringid & NETMAP_SW_RING) D("ringid %s set to SW RING", ifp->if_xname); else if (ringid & NETMAP_HW_RING) @@ -884,6 +934,7 @@ netmap_set_ringid(struct netmap_priv_d * priv->np_qfirst); else D("ringid %s set to all %d HW RINGS", ifp->if_xname, lim); + } return 0; } @@ -965,6 +1016,7 @@ netmap_ioctl(struct cdev *dev, u_long cm if (error) break; na = NA(ifp); /* retrieve netmap_adapter */ + netmap_update_config(na); nmr->nr_rx_rings = na->num_rx_rings; nmr->nr_tx_rings = na->num_tx_rings; nmr->nr_rx_slots = na->num_rx_desc; @@ -1014,6 +1066,8 @@ netmap_ioctl(struct cdev *dev, u_long cm break; } + /* ring configuration may have changed, fetch from the card */ + netmap_update_config(na); priv->np_ifp = ifp; /* store the reference */ error = netmap_set_ringid(priv, nmr->nr_ringid); if (error) @@ -1444,46 +1498,28 @@ netmap_lock_wrapper(struct ifnet *dev, i * setups. */ int -netmap_attach(struct netmap_adapter *na, int num_queues) +netmap_attach(struct netmap_adapter *arg, int num_queues) { - int n, size; - void *buf; - struct ifnet *ifp = na->ifp; + struct netmap_adapter *na = NULL; + struct ifnet *ifp = arg ? arg->ifp : NULL; - if (ifp == NULL) { - D("ifp not set, giving up"); - return EINVAL; - } - /* clear other fields ? */ - na->refcount = 0; + if (arg == NULL || ifp == NULL) + goto fail; + na = malloc(sizeof(*na), M_DEVBUF, M_NOWAIT | M_ZERO); + if (na == NULL) + goto fail; + WNA(ifp) = na; + *na = *arg; /* copy everything, trust the driver to not pass junk */ + NETMAP_SET_CAPABLE(ifp); if (na->num_tx_rings == 0) na->num_tx_rings = num_queues; na->num_rx_rings = num_queues; - /* on each direction we have N+1 resources - * 0..n-1 are the hardware rings - * n is the ring attached to the stack. - */ - n = na->num_rx_rings + na->num_tx_rings + 2; - size = sizeof(*na) + n * sizeof(struct netmap_kring); - - buf = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO); - if (buf) { - WNA(ifp) = buf; - na->tx_rings = (void *)((char *)buf + sizeof(*na)); - na->rx_rings = na->tx_rings + na->num_tx_rings + 1; - bcopy(na, buf, sizeof(*na)); - NETMAP_SET_CAPABLE(ifp); - - na = buf; - /* Core lock initialized here. Others are initialized after - * netmap_if_new. - */ - mtx_init(&na->core_lock, "netmap core lock", MTX_NETWORK_LOCK, - MTX_DEF); - if (na->nm_lock == NULL) { - ND("using default locks for %s", ifp->if_xname); - na->nm_lock = netmap_lock_wrapper; - } + na->refcount = na->na_single = na->na_multi = 0; + /* Core lock initialized here, others after netmap_if_new. */ + mtx_init(&na->core_lock, "netmap core lock", MTX_NETWORK_LOCK, MTX_DEF); + if (na->nm_lock == NULL) { + ND("using default locks for %s", ifp->if_xname); + na->nm_lock = netmap_lock_wrapper; } #ifdef linux if (ifp->netdev_ops) { @@ -1493,9 +1529,12 @@ netmap_attach(struct netmap_adapter *na, } na->nm_ndo.ndo_start_xmit = linux_netmap_start; #endif - D("%s for %s", buf ? "ok" : "failed", ifp->if_xname); + D("success for %s", ifp->if_xname); + return 0; - return (buf ? 0 : ENOMEM); +fail: + D("fail, arg %p ifp %p na %p", arg, ifp, na); + return (na ? EINVAL : ENOMEM); } @@ -1513,6 +1552,10 @@ netmap_detach(struct ifnet *ifp) mtx_destroy(&na->core_lock); + if (na->tx_rings) { /* XXX should not happen */ + D("freeing leftover tx_rings"); + free(na->tx_rings, M_DEVBUF); + } bzero(na, sizeof(*na)); WNA(ifp) = NULL; free(na, M_DEVBUF); Modified: head/sys/dev/netmap/netmap_kern.h ============================================================================== --- head/sys/dev/netmap/netmap_kern.h Wed Jan 23 03:49:48 2013 (r245834) +++ head/sys/dev/netmap/netmap_kern.h Wed Jan 23 03:51:47 2013 (r245835) @@ -203,6 +203,9 @@ struct netmap_adapter { void (*nm_lock)(struct ifnet *, int what, u_int ringid); int (*nm_txsync)(struct ifnet *, u_int ring, int lock); int (*nm_rxsync)(struct ifnet *, u_int ring, int lock); + /* return configuration information */ + int (*nm_config)(struct ifnet *, u_int *txr, u_int *txd, + u_int *rxr, u_int *rxd); int bdg_port; #ifdef linux Modified: head/sys/dev/netmap/netmap_mem2.c ============================================================================== --- head/sys/dev/netmap/netmap_mem2.c Wed Jan 23 03:49:48 2013 (r245834) +++ head/sys/dev/netmap/netmap_mem2.c Wed Jan 23 03:51:47 2013 (r245835) @@ -388,7 +388,7 @@ netmap_obj_free_va(struct netmap_obj_poo netmap_obj_free(p, j); return; } - ND("address %p is not contained inside any cluster (%s)", + D("address %p is not contained inside any cluster (%s)", vaddr, p->name); } @@ -559,8 +559,9 @@ netmap_config_obj_allocator(struct netma i = (clustsize & (PAGE_SIZE - 1)); if (i) clustsize += PAGE_SIZE - i; - D("objsize %d clustsize %d objects %d", - objsize, clustsize, clustentries); + if (netmap_verbose) + D("objsize %d clustsize %d objects %d", + objsize, clustsize, clustentries); /* * The number of clusters is n = ceil(objtotal/clustentries) @@ -649,9 +650,10 @@ netmap_finalize_obj_allocator(struct net } } p->bitmap[0] = ~3; /* objs 0 and 1 is always busy */ - D("Pre-allocated %d clusters (%d/%dKB) for '%s'", - p->_numclusters, p->_clustsize >> 10, - p->_memtotal >> 10, p->name); + if (netmap_verbose) + D("Pre-allocated %d clusters (%d/%dKB) for '%s'", + p->_numclusters, p->_clustsize >> 10, + p->_memtotal >> 10, p->name); return 0; @@ -721,7 +723,7 @@ netmap_memory_finalize(void) nm_mem.refcount++; if (nm_mem.refcount > 1) { - D("busy (refcount %d)", nm_mem.refcount); + ND("busy (refcount %d)", nm_mem.refcount); goto out; } @@ -796,6 +798,8 @@ static void netmap_free_rings(struct netmap_adapter *na) { int i; + if (!na->tx_rings) + return; for (i = 0; i < na->num_tx_rings + 1; i++) { netmap_ring_free(na->tx_rings[i].ring); na->tx_rings[i].ring = NULL; @@ -804,22 +808,32 @@ netmap_free_rings(struct netmap_adapter netmap_ring_free(na->rx_rings[i].ring); na->rx_rings[i].ring = NULL; } + free(na->tx_rings, M_DEVBUF); + na->tx_rings = na->rx_rings = NULL; } /* call with NMA_LOCK held */ +/* + * Allocate the per-fd structure netmap_if. + * If this is the first instance, also allocate the krings, rings etc. + */ static void * netmap_if_new(const char *ifname, struct netmap_adapter *na) { struct netmap_if *nifp; struct netmap_ring *ring; ssize_t base; /* handy for relative offsets between rings and nifp */ - u_int i, len, ndesc; - u_int ntx = na->num_tx_rings + 1; /* shorthand, include stack ring */ - u_int nrx = na->num_rx_rings + 1; /* shorthand, include stack ring */ + u_int i, len, ndesc, ntx, nrx; struct netmap_kring *kring; + if (netmap_update_config(na)) { + /* configuration mismatch, report and fail */ + return NULL; + } + ntx = na->num_tx_rings + 1; /* shorthand, include stack ring */ + nrx = na->num_rx_rings + 1; /* shorthand, include stack ring */ /* * the descriptor is followed inline by an array of offsets * to the tx and rx rings in the shared memory region. @@ -840,6 +854,14 @@ netmap_if_new(const char *ifname, struct goto final; } + len = (ntx + nrx) * sizeof(struct netmap_kring); + na->tx_rings = malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO); + if (na->tx_rings == NULL) { + D("Cannot allocate krings for %s", ifname); + goto cleanup; + } + na->rx_rings = na->tx_rings + ntx; + /* * First instance, allocate netmap rings and buffers for this card * The rings are contiguous, but have variable size. @@ -947,5 +969,6 @@ static void netmap_memory_deref(void) { nm_mem.refcount--; - D("refcount = %d", nm_mem.refcount); + if (netmap_verbose) + D("refcount = %d", nm_mem.refcount); }