Index: sys/dev/netmap/netmap.c =================================================================== --- sys/dev/netmap/netmap.c (revision 278739) +++ sys/dev/netmap/netmap.c (working copy) @@ -375,9 +375,14 @@ /* 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) @@ -806,6 +811,19 @@ } +#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 +834,7 @@ /* 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 +1015,8 @@ * 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 +1328,7 @@ /* 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; @@ -2410,7 +2428,7 @@ } } 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 +2497,7 @@ } 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; @@ -3054,8 +3072,15 @@ 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, +#ifdef __FreeBSD__ + /* support for the 'eternal' flag */ + netmap_dev = make_dev_credf(MAKEDEV_ETERNAL_KLD, + &netmap_cdevsw, 0, NULL, UID_ROOT, GID_WHEEL, 0600, "netmap"); +#else + netmap_dev = make_dev(&netmap_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, + "netmap"); +#endif if (!netmap_dev) goto fail; Index: sys/dev/netmap/netmap_freebsd.c =================================================================== --- sys/dev/netmap/netmap_freebsd.c (revision 278739) +++ sys/dev/netmap/netmap_freebsd.c (working copy) @@ -466,6 +466,8 @@ 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,18 +656,17 @@ * 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 @@ -672,7 +673,7 @@ 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 @@ 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 @@ 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 @@ 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, Index: sys/dev/netmap/netmap_generic.c =================================================================== --- sys/dev/netmap/netmap_generic.c (revision 278739) +++ sys/dev/netmap/netmap_generic.c (working copy) @@ -821,7 +821,7 @@ 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); Index: sys/dev/netmap/netmap_kern.h =================================================================== --- sys/dev/netmap/netmap_kern.h (revision 278739) +++ sys/dev/netmap/netmap_kern.h (working copy) @@ -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) @@ -79,6 +82,13 @@ 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,14 +111,21 @@ #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 #endif /* DEV_NETMAP */ @@ -260,7 +277,7 @@ 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 +652,7 @@ int (*nm_hw_register)(struct netmap_adapter *, int onoff); }; +#ifdef WITH_GENERIC /* Mitigation support. */ struct nm_generic_mit { struct hrtimer mit_timer; @@ -662,6 +680,7 @@ 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) @@ -1478,6 +1497,7 @@ #endif /* WITH_MONITOR */ +#ifdef WITH_GENERIC /* * generic netmap emulation for devices that do not have * native netmap support. @@ -1509,6 +1529,7 @@ 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 */ Index: sys/dev/netmap/netmap_monitor.c =================================================================== --- sys/dev/netmap/netmap_monitor.c (revision 278739) +++ sys/dev/netmap/netmap_monitor.c (working copy) @@ -179,7 +179,7 @@ i = nm_next(i, mlim); } - wmb(); + mb(); mkring->nr_hwtail = i; mtx_unlock(&mkring->q_lock); @@ -225,7 +225,7 @@ { ND("%s %x", kring->name, flags); kring->nr_hwcur = kring->rcur; - rmb(); + mb(); nm_rxsync_finalize(kring); return 0; } Index: sys/dev/netmap/netmap_pipe.c =================================================================== --- sys/dev/netmap/netmap_pipe.c (revision 278739) +++ sys/dev/netmap/netmap_pipe.c (working copy) @@ -197,10 +197,10 @@ 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 @@ 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 @@ 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 @@ 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; Index: . =================================================================== --- . (revision 278739) +++ . (working copy) Property changes on: . ___________________________________________________________________ Modified: svn:mergeinfo Merged /head:r274353-274355,274361-274362,274457,274459,277653