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);
 }
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to