Author: luigi
Date: Sat Feb 14 19:41:26 2015
New Revision: 278779
URL: https://svnweb.freebsd.org/changeset/base/278779

Log:
  sync the code with the version in head. which the exception of
  svn 275358 (M_FLOWID deprecation, only a couple of lines)
  which cannot be merged.
  
  if_lem_netmap.h, if_re_netmap.h:
  - use the same (commented out) function to update the stat counters
    as in HEAD. This is a no-op here
  
  netmap.c
  - merge 274459 (support for private knote lock)
    and minor changes on nm_config and comments
  
  netmap_freebsd.c
  - merge 274459 (support for private knote lock)
  - merge 274354 (initialize color if passed as argument)
  
  netmap_generic.c
  - fix a comment
  
  netmap_kern.h
  - revise the lock macros, using sx locks;
    merge 274459 (private knote lock)
  
  netmap_monitor.c
  - use full memory barriers
  
  netmap_pipe.c
  - use full memory barriers, use length from the correct queue
    (mostly cosmetic, since the queues typically have the same size)

Modified:
  stable/10/sys/dev/netmap/if_lem_netmap.h
  stable/10/sys/dev/netmap/if_re_netmap.h
  stable/10/sys/dev/netmap/netmap.c
  stable/10/sys/dev/netmap/netmap_freebsd.c
  stable/10/sys/dev/netmap/netmap_generic.c
  stable/10/sys/dev/netmap/netmap_kern.h
  stable/10/sys/dev/netmap/netmap_monitor.c
  stable/10/sys/dev/netmap/netmap_pipe.c

Modified: stable/10/sys/dev/netmap/if_lem_netmap.h
==============================================================================
--- stable/10/sys/dev/netmap/if_lem_netmap.h    Sat Feb 14 19:28:26 2015        
(r278778)
+++ stable/10/sys/dev/netmap/if_lem_netmap.h    Sat Feb 14 19:41:26 2015        
(r278779)
@@ -410,7 +410,7 @@ lem_netmap_rxsync(struct netmap_kring *k
                                netmap_idx_n2k(kring, 
adapter->next_rx_desc_to_check),
                                kring->nr_hwtail);
                        adapter->next_rx_desc_to_check = nic_i;
-                       // ifp->if_ipackets += n;
+                       // if_inc_counter(ifp, IFCOUNTER_IPACKETS, n);
                        kring->nr_hwtail = nm_i;
                }
                kring->nr_kflags &= ~NKR_PENDINTR;

Modified: stable/10/sys/dev/netmap/if_re_netmap.h
==============================================================================
--- stable/10/sys/dev/netmap/if_re_netmap.h     Sat Feb 14 19:28:26 2015        
(r278778)
+++ stable/10/sys/dev/netmap/if_re_netmap.h     Sat Feb 14 19:41:26 2015        
(r278779)
@@ -222,7 +222,7 @@ re_netmap_rxsync(struct netmap_kring *kr
                        /*  sync was in re_newbuf() */
                        bus_dmamap_sync(sc->rl_ldata.rl_rx_mtag,
                            rxd[nic_i].rx_dmamap, BUS_DMASYNC_POSTREAD);
-                       // sc->rl_ifp->if_ipackets++;
+                       // if_inc_counter(sc->rl_ifp, IFCOUNTER_IPACKETS, 1);
                        nm_i = nm_next(nm_i, lim);
                        nic_i = nm_next(nic_i, lim);
                }

Modified: stable/10/sys/dev/netmap/netmap.c
==============================================================================
--- stable/10/sys/dev/netmap/netmap.c   Sat Feb 14 19:28:26 2015        
(r278778)
+++ stable/10/sys/dev/netmap/netmap.c   Sat Feb 14 19:41:26 2015        
(r278779)
@@ -375,9 +375,14 @@ ports attached to the switch)
 
 /* reduce conditional code */
 // linux API, use for the knlist in FreeBSD
-#define init_waitqueue_head(x) knlist_init_mtx(&(x)->si_note, NULL)
+/* use a private mutex for the knlist */
+#define init_waitqueue_head(x) do {                    \
+       struct mtx *m = &(x)->m;                        \
+       mtx_init(m, "nm_kn_lock", NULL, MTX_DEF);       \
+       knlist_init_mtx(&(x)->si.si_note, m);           \
+    } while (0)
 
-void freebsd_selwakeup(struct selinfo *si, int pri);
+#define OS_selrecord(a, b)     selrecord(a, &((b)->si))
 #define OS_selwakeup(a, b)     freebsd_selwakeup(a, b)
 
 #elif defined(linux)
@@ -651,9 +656,8 @@ netmap_update_config(struct netmap_adapt
        u_int txr, txd, rxr, rxd;
 
        txr = txd = rxr = rxd = 0;
-       if (na->nm_config) {
-               na->nm_config(na, &txr, &txd, &rxr, &rxd);
-       } else {
+       if (na->nm_config == NULL ||
+           na->nm_config(na, &txr, &txd, &rxr, &rxd)) {
                /* take whatever we had at init time */
                txr = na->num_tx_rings;
                txd = na->num_tx_desc;
@@ -806,6 +810,19 @@ netmap_krings_create(struct netmap_adapt
 }
 
 
+#ifdef __FreeBSD__
+static void
+netmap_knlist_destroy(NM_SELINFO_T *si)
+{
+       /* XXX kqueue(9) needed; these will mirror knlist_init. */
+       knlist_delete(&si->si.si_note, curthread, 0 /* not locked */ );
+       knlist_destroy(&si->si.si_note);
+       /* now we don't need the mutex anymore */
+       mtx_destroy(&si->m);
+}
+#endif /* __FreeBSD__ */
+
+
 /* undo the actions performed by netmap_krings_create */
 /* call with NMG_LOCK held */
 void
@@ -816,6 +833,7 @@ netmap_krings_delete(struct netmap_adapt
        /* we rely on the krings layout described above */
        for ( ; kring != na->tailroom; kring++) {
                mtx_destroy(&kring->q_lock);
+               netmap_knlist_destroy(&kring->si);
        }
        free(na->tx_rings, M_DEVBUF);
        na->tx_rings = na->rx_rings = na->tailroom = NULL;
@@ -996,9 +1014,8 @@ netmap_do_unregif(struct netmap_priv_d *
                 * XXX The wake up now must happen during *_down(), when
                 * we order all activities to stop. -gl
                 */
-               /* XXX kqueue(9) needed; these will mirror knlist_init. */
-               /* knlist_destroy(&na->tx_si.si_note); */
-               /* knlist_destroy(&na->rx_si.si_note); */
+               netmap_knlist_destroy(&na->tx_si);
+               netmap_knlist_destroy(&na->rx_si);
 
                /* delete rings and buffers */
                netmap_mem_rings_delete(na);
@@ -1310,7 +1327,7 @@ netmap_rxsync_from_host(struct netmap_ad
 
        /* access copies of cur,tail in the kring */
        if (kring->rcur == kring->rtail && td) /* no bufs available */
-               selrecord(td, &kring->si);
+               OS_selrecord(td, &kring->si);
 
        mbq_unlock(q);
        return ret;
@@ -2150,7 +2167,7 @@ netmap_ioctl(struct cdev *dev, u_long cm
                        error = ENXIO;
                        break;
                }
-               rmb(); /* make sure following reads are not from cache */
+               mb(); /* make sure following reads are not from cache */
 
                na = priv->np_na;      /* we have a reference */
 
@@ -2410,7 +2427,7 @@ flush_tx:
                        }
                }
                if (want_tx && retry_tx && !is_kevent) {
-                       selrecord(td, check_all_tx ?
+                       OS_selrecord(td, check_all_tx ?
                            &na->tx_si : &na->tx_rings[priv->np_txqfirst].si);
                        retry_tx = 0;
                        goto flush_tx;
@@ -2479,7 +2496,7 @@ do_retry_rx:
                }
 
                if (retry_rx && !is_kevent)
-                       selrecord(td, check_all_rx ?
+                       OS_selrecord(td, check_all_rx ?
                            &na->rx_si : &na->rx_rings[priv->np_rxqfirst].si);
                if (send_down > 0 || retry_rx) {
                        retry_rx = 0;
@@ -3053,8 +3070,13 @@ netmap_init(void)
        error = netmap_mem_init();
        if (error != 0)
                goto fail;
-       /* XXX could use make_dev_credv() to get error number */
-       netmap_dev = make_dev(&netmap_cdevsw, 0, UID_ROOT, GID_WHEEL, 0660,
+       /*
+        * MAKEDEV_ETERNAL_KLD avoids an expensive check on syscalls
+        * when the module is compiled in.
+        * XXX could use make_dev_credv() to get error number
+        */
+       netmap_dev = make_dev_credf(MAKEDEV_ETERNAL_KLD,
+               &netmap_cdevsw, 0, NULL, UID_ROOT, GID_WHEEL, 0600,
                              "netmap");
        if (!netmap_dev)
                goto fail;

Modified: stable/10/sys/dev/netmap/netmap_freebsd.c
==============================================================================
--- stable/10/sys/dev/netmap/netmap_freebsd.c   Sat Feb 14 19:28:26 2015        
(r278778)
+++ stable/10/sys/dev/netmap/netmap_freebsd.c   Sat Feb 14 19:41:26 2015        
(r278779)
@@ -466,6 +466,8 @@ netmap_dev_pager_ctor(void *handle, vm_o
        if (netmap_verbose)
                D("handle %p size %jd prot %d foff %jd",
                        handle, (intmax_t)size, prot, (intmax_t)foff);
+       if (color)
+               *color = 0;
        dev_ref(vmh->dev);
        return 0;
 }
@@ -654,25 +656,24 @@ netmap_open(struct cdev *dev, int oflags
  * and do not need the selrecord().
  */
 
-void freebsd_selwakeup(struct selinfo *si, int pri);
 
 void
-freebsd_selwakeup(struct selinfo *si, int pri)
+freebsd_selwakeup(struct nm_selinfo *si, int pri)
 {
        if (netmap_verbose)
-               D("on knote %p", &si->si_note);
-       selwakeuppri(si, pri);
+               D("on knote %p", &si->si.si_note);
+       selwakeuppri(&si->si, pri);
        /* use a non-zero hint to tell the notification from the
         * call done in kqueue_scan() which uses 0
         */
-       KNOTE_UNLOCKED(&si->si_note, 0x100 /* notification */);
+       KNOTE_UNLOCKED(&si->si.si_note, 0x100 /* notification */);
 }
 
 static void
 netmap_knrdetach(struct knote *kn)
 {
        struct netmap_priv_d *priv = (struct netmap_priv_d *)kn->kn_hook;
-       struct selinfo *si = priv->np_rxsi;
+       struct selinfo *si = &priv->np_rxsi->si;
 
        D("remove selinfo %p", si);
        knlist_remove(&si->si_note, kn, 0);
@@ -682,7 +683,7 @@ static void
 netmap_knwdetach(struct knote *kn)
 {
        struct netmap_priv_d *priv = (struct netmap_priv_d *)kn->kn_hook;
-       struct selinfo *si = priv->np_txsi;
+       struct selinfo *si = &priv->np_txsi->si;
 
        D("remove selinfo %p", si);
        knlist_remove(&si->si_note, kn, 0);
@@ -754,7 +755,7 @@ netmap_kqfilter(struct cdev *dev, struct
        struct netmap_priv_d *priv;
        int error;
        struct netmap_adapter *na;
-       struct selinfo *si;
+       struct nm_selinfo *si;
        int ev = kn->kn_filter;
 
        if (ev != EVFILT_READ && ev != EVFILT_WRITE) {
@@ -777,7 +778,7 @@ netmap_kqfilter(struct cdev *dev, struct
        kn->kn_fop = (ev == EVFILT_WRITE) ?
                &netmap_wfiltops : &netmap_rfiltops;
        kn->kn_hook = priv;
-       knlist_add(&si->si_note, kn, 1);
+       knlist_add(&si->si.si_note, kn, 1);
        // XXX unlock(priv)
        ND("register %p %s td %p priv %p kn %p np_nifp %p kn_fp/fpop %s",
                na, na->ifp->if_xname, curthread, priv, kn,

Modified: stable/10/sys/dev/netmap/netmap_generic.c
==============================================================================
--- stable/10/sys/dev/netmap/netmap_generic.c   Sat Feb 14 19:28:26 2015        
(r278778)
+++ stable/10/sys/dev/netmap/netmap_generic.c   Sat Feb 14 19:41:26 2015        
(r278779)
@@ -821,7 +821,7 @@ generic_netmap_attach(struct ifnet *ifp)
 
        num_tx_desc = num_rx_desc = netmap_generic_ringsize; /* starting point 
*/
 
-       generic_find_num_desc(ifp, &num_tx_desc, &num_rx_desc);
+       generic_find_num_desc(ifp, &num_tx_desc, &num_rx_desc); /* ignore 
errors */
        ND("Netmap ring size: TX = %d, RX = %d", num_tx_desc, num_rx_desc);
        if (num_tx_desc == 0 || num_rx_desc == 0) {
                D("Device has no hw slots (tx %u, rx %u)", num_tx_desc, 
num_rx_desc);

Modified: stable/10/sys/dev/netmap/netmap_kern.h
==============================================================================
--- stable/10/sys/dev/netmap/netmap_kern.h      Sat Feb 14 19:28:26 2015        
(r278778)
+++ stable/10/sys/dev/netmap/netmap_kern.h      Sat Feb 14 19:41:26 2015        
(r278779)
@@ -37,6 +37,7 @@
 #define WITH_VALE      // comment out to disable VALE support
 #define WITH_PIPES
 #define WITH_MONITOR
+#define WITH_GENERIC
 
 #if defined(__FreeBSD__)
 
@@ -44,6 +45,8 @@
 #define unlikely(x)    __builtin_expect((long)!!(x), 0L)
 
 #define        NM_LOCK_T       struct mtx
+
+/* netmap global lock */
 #define        NMG_LOCK_T      struct sx
 #define NMG_LOCK_INIT()        sx_init(&netmap_global_lock, \
                                "netmap global lock")
@@ -52,7 +55,7 @@
 #define NMG_UNLOCK()   sx_xunlock(&netmap_global_lock)
 #define NMG_LOCK_ASSERT()      sx_assert(&netmap_global_lock, SA_XLOCKED)
 
-#define        NM_SELINFO_T    struct selinfo
+#define        NM_SELINFO_T    struct nm_selinfo
 #define        MBUF_LEN(m)     ((m)->m_pkthdr.len)
 #define        MBUF_IFP(m)     ((m)->m_pkthdr.rcvif)
 #define        NM_SEND_UP(ifp, m)      ((NA(ifp))->if_input)(ifp, m)
@@ -63,6 +66,12 @@
 #define NM_ATOMIC_TEST_AND_SET(p)       (!atomic_cmpset_acq_int((p), 0, 1))
 #define NM_ATOMIC_CLEAR(p)              atomic_store_rel_int((p), 0)
 
+#if __FreeBSD_version >= 1100030
+#define        WNA(_ifp)       (_ifp)->if_netmap
+#else /* older FreeBSD */
+#define        WNA(_ifp)       (_ifp)->if_pspare[0]
+#endif /* older FreeBSD */
+
 #if __FreeBSD_version >= 1100005
 struct netmap_adapter *netmap_getna(if_t ifp);
 #endif
@@ -79,6 +88,13 @@ struct netmap_adapter *netmap_getna(if_t
 
 MALLOC_DECLARE(M_NETMAP);
 
+struct nm_selinfo {
+       struct selinfo si;
+       struct mtx m;
+};
+
+void freebsd_selwakeup(struct nm_selinfo *si, int pri);
+
 // XXX linux struct, not used in FreeBSD
 struct net_device_ops {
 };
@@ -101,13 +117,20 @@ struct hrtimer {
 
 #define NM_ATOMIC_T    volatile long unsigned int
 
-// XXX a mtx would suffice here too 20130404 gl
-#define NMG_LOCK_T             struct semaphore
-#define NMG_LOCK_INIT()                sema_init(&netmap_global_lock, 1)
-#define NMG_LOCK_DESTROY()
-#define NMG_LOCK()             down(&netmap_global_lock)
-#define NMG_UNLOCK()           up(&netmap_global_lock)
-#define NMG_LOCK_ASSERT()      //      XXX to be completed
+#define NM_MTX_T               struct mutex
+#define NM_MTX_INIT(m, s)      do { (void)s; mutex_init(&(m)); } while (0)
+#define NM_MTX_DESTROY(m)      do { (void)m; } while (0)
+#define NM_MTX_LOCK(m)         mutex_lock(&(m))
+#define NM_MTX_UNLOCK(m)       mutex_unlock(&(m))
+#define NM_MTX_LOCK_ASSERT(m)  mutex_is_locked(&(m))
+
+#define        NMG_LOCK_T              NM_MTX_T
+#define        NMG_LOCK_INIT()         NM_MTX_INIT(netmap_global_lock, \
+                                       "netmap_global_lock")
+#define        NMG_LOCK_DESTROY()      NM_MTX_DESTROY(netmap_global_lock)
+#define        NMG_LOCK()              NM_MTX_LOCK(netmap_global_lock)
+#define        NMG_UNLOCK()            NM_MTX_UNLOCK(netmap_global_lock)
+#define        NMG_LOCK_ASSERT()       NM_MTX_LOCK_ASSERT(netmap_global_lock)
 
 #ifndef DEV_NETMAP
 #define DEV_NETMAP
@@ -260,7 +283,7 @@ struct netmap_kring {
 
        struct netmap_adapter *na;
 
-       /* The folloiwing fields are for VALE switch support */
+       /* The following fields are for VALE switch support */
        struct nm_bdg_fwd *nkr_ft;
        uint32_t        *nkr_leases;
 #define NR_NOSLOT      ((uint32_t)~0)  /* used in nkr_*lease* */
@@ -635,6 +658,7 @@ struct netmap_hw_adapter {  /* physical d
        int (*nm_hw_register)(struct netmap_adapter *, int onoff);
 };
 
+#ifdef WITH_GENERIC
 /* Mitigation support. */
 struct nm_generic_mit {
        struct hrtimer mit_timer;
@@ -662,6 +686,7 @@ struct netmap_generic_adapter {     /* emula
         netdev_tx_t (*save_start_xmit)(struct mbuf *, struct ifnet *);
 #endif
 };
+#endif  /* WITH_GENERIC */
 
 static __inline int
 netmap_real_tx_rings(struct netmap_adapter *na)
@@ -1186,9 +1211,6 @@ extern int netmap_generic_rings;
  * NA returns a pointer to the struct netmap adapter from the ifp,
  * WNA is used to write it.
  */
-#ifndef WNA
-#define        WNA(_ifp)       (_ifp)->if_pspare[0]
-#endif
 #define        NA(_ifp)        ((struct netmap_adapter *)WNA(_ifp))
 
 /*
@@ -1478,6 +1500,7 @@ struct netmap_monitor_adapter {
 #endif /* WITH_MONITOR */
 
 
+#ifdef WITH_GENERIC
 /*
  * generic netmap emulation for devices that do not have
  * native netmap support.
@@ -1509,6 +1532,7 @@ void netmap_mitigation_start(struct nm_g
 void netmap_mitigation_restart(struct nm_generic_mit *mit);
 int netmap_mitigation_active(struct nm_generic_mit *mit);
 void netmap_mitigation_cleanup(struct nm_generic_mit *mit);
+#endif /* WITH_GENERIC */
 
 
 

Modified: stable/10/sys/dev/netmap/netmap_monitor.c
==============================================================================
--- stable/10/sys/dev/netmap/netmap_monitor.c   Sat Feb 14 19:28:26 2015        
(r278778)
+++ stable/10/sys/dev/netmap/netmap_monitor.c   Sat Feb 14 19:41:26 2015        
(r278779)
@@ -179,7 +179,7 @@ netmap_monitor_parent_sync(struct netmap
                i = nm_next(i, mlim);
 
        }
-       wmb();
+       mb();
        mkring->nr_hwtail = i;
 
        mtx_unlock(&mkring->q_lock);
@@ -225,7 +225,7 @@ netmap_monitor_rxsync(struct netmap_krin
 {
         ND("%s %x", kring->name, flags);
        kring->nr_hwcur = kring->rcur;
-       rmb();
+       mb();
        nm_rxsync_finalize(kring);
         return 0;
 }

Modified: stable/10/sys/dev/netmap/netmap_pipe.c
==============================================================================
--- stable/10/sys/dev/netmap/netmap_pipe.c      Sat Feb 14 19:28:26 2015        
(r278778)
+++ stable/10/sys/dev/netmap/netmap_pipe.c      Sat Feb 14 19:41:26 2015        
(r278779)
@@ -197,10 +197,10 @@ netmap_pipe_txsync(struct netmap_kring *
         if (m < 0)
                 m += txkring->nkr_num_slots;
         limit = m;
-        m = rxkring->nkr_num_slots - 1; /* max avail space on destination */
+        m = lim_rx; /* max avail space on destination */
         busy = j - rxkring->nr_hwcur; /* busy slots */
        if (busy < 0)
-               busy += txkring->nkr_num_slots;
+               busy += rxkring->nkr_num_slots;
        m -= busy; /* subtract busy slots */
         ND(2, "m %d limit %d", m, limit);
         if (m < limit)
@@ -228,7 +228,7 @@ netmap_pipe_txsync(struct netmap_kring *
                 k = nm_next(k, lim_tx);
         }
 
-        wmb(); /* make sure the slots are updated before publishing them */
+        mb(); /* make sure the slots are updated before publishing them */
         rxkring->nr_hwtail = j;
         txkring->nr_hwcur = k;
         txkring->nr_hwtail = nm_prev(k, lim_tx);
@@ -237,7 +237,7 @@ netmap_pipe_txsync(struct netmap_kring *
         ND(2, "after: hwcur %d hwtail %d cur %d head %d tail %d j %d", 
txkring->nr_hwcur, txkring->nr_hwtail,
                 txkring->rcur, txkring->rhead, txkring->rtail, j);
 
-        wmb(); /* make sure rxkring->nr_hwtail is updated before notifying */
+        mb(); /* make sure rxkring->nr_hwtail is updated before notifying */
         rxkring->na->nm_notify(rxkring->na, rxkring->ring_id, NR_RX, 0);
 
        return 0;
@@ -253,12 +253,12 @@ netmap_pipe_rxsync(struct netmap_kring *
         rxkring->nr_hwcur = rxkring->rhead; /* recover user-relased slots */
         ND(5, "hwcur %d hwtail %d cur %d head %d tail %d", rxkring->nr_hwcur, 
rxkring->nr_hwtail,
                 rxkring->rcur, rxkring->rhead, rxkring->rtail);
-        rmb(); /* paired with the first wmb() in txsync */
+        mb(); /* paired with the first mb() in txsync */
         nm_rxsync_finalize(rxkring);
 
        if (oldhwcur != rxkring->nr_hwcur) {
                /* we have released some slots, notify the other end */
-               wmb(); /* make sure nr_hwcur is updated before notifying */
+               mb(); /* make sure nr_hwcur is updated before notifying */
                txkring->na->nm_notify(txkring->na, txkring->ring_id, NR_TX, 0);
        }
         return 0;
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "[email protected]"

Reply via email to