Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/netmap/netmap_freebsd.c
Show First 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | if (err) { | ||||
taskqueue_free(si->ntfytq); | taskqueue_free(si->ntfytq); | ||||
si->ntfytq = NULL; | si->ntfytq = NULL; | ||||
return err; | return err; | ||||
} | } | ||||
snprintf(si->mtxname, sizeof(si->mtxname), "nmkl%s", name); | snprintf(si->mtxname, sizeof(si->mtxname), "nmkl%s", name); | ||||
mtx_init(&si->m, si->mtxname, NULL, MTX_DEF); | mtx_init(&si->m, si->mtxname, NULL, MTX_DEF); | ||||
knlist_init_mtx(&si->si.si_note, &si->m); | knlist_init_mtx(&si->si.si_note, &si->m); | ||||
si->kqueue_users = 0; | |||||
return (0); | return (0); | ||||
} | } | ||||
void | void | ||||
nm_os_selinfo_uninit(NM_SELINFO_T *si) | nm_os_selinfo_uninit(NM_SELINFO_T *si) | ||||
{ | { | ||||
if (si->ntfytq == NULL) { | if (si->ntfytq == NULL) { | ||||
▲ Show 20 Lines • Show All 1,230 Lines • ▼ Show 20 Lines | |||||
* (if necessary), and skips the nm_os_selrecord() calls. | * (if necessary), and skips the nm_os_selrecord() calls. | ||||
*/ | */ | ||||
void | void | ||||
nm_os_selwakeup(struct nm_selinfo *si) | nm_os_selwakeup(struct nm_selinfo *si) | ||||
{ | { | ||||
selwakeuppri(&si->si, PI_NET); | selwakeuppri(&si->si, PI_NET); | ||||
if (si->kqueue_users > 0) { | |||||
taskqueue_enqueue(si->ntfytq, &si->ntfytask); | taskqueue_enqueue(si->ntfytq, &si->ntfytask); | ||||
} | } | ||||
} | |||||
void | void | ||||
nm_os_selrecord(struct thread *td, struct nm_selinfo *si) | nm_os_selrecord(struct thread *td, struct nm_selinfo *si) | ||||
{ | { | ||||
selrecord(td, &si->si); | selrecord(td, &si->si); | ||||
} | } | ||||
static void | static void | ||||
netmap_knrdetach(struct knote *kn) | netmap_knrdetach(struct knote *kn) | ||||
{ | { | ||||
struct netmap_priv_d *priv = (struct netmap_priv_d *)kn->kn_hook; | struct netmap_priv_d *priv = (struct netmap_priv_d *)kn->kn_hook; | ||||
struct selinfo *si = &priv->np_si[NR_RX]->si; | struct nm_selinfo *si = priv->np_si[NR_RX]; | ||||
nm_prinf("remove selinfo %p", si); | knlist_remove(&si->si.si_note, kn, /*islocked=*/0); | ||||
knlist_remove(&si->si_note, kn, /*islocked=*/0); | NMG_LOCK(); | ||||
KASSERT(si->kqueue_users > 0, ("kqueue_user underflow on %s", | |||||
si->mtxname)); | |||||
si->kqueue_users--; | |||||
nm_prinf("kqueue users for %s: %d", si->mtxname, si->kqueue_users); | |||||
NMG_UNLOCK(); | |||||
} | } | ||||
static void | static void | ||||
netmap_knwdetach(struct knote *kn) | netmap_knwdetach(struct knote *kn) | ||||
{ | { | ||||
struct netmap_priv_d *priv = (struct netmap_priv_d *)kn->kn_hook; | struct netmap_priv_d *priv = (struct netmap_priv_d *)kn->kn_hook; | ||||
struct selinfo *si = &priv->np_si[NR_TX]->si; | struct nm_selinfo *si = priv->np_si[NR_TX]; | ||||
nm_prinf("remove selinfo %p", si); | knlist_remove(&si->si.si_note, kn, /*islocked=*/0); | ||||
knlist_remove(&si->si_note, kn, /*islocked=*/0); | NMG_LOCK(); | ||||
si->kqueue_users--; | |||||
nm_prinf("kqueue users for %s: %d", si->mtxname, si->kqueue_users); | |||||
NMG_UNLOCK(); | |||||
} | } | ||||
/* | /* | ||||
* Callback triggered by netmap notifications (see netmap_notify()), | * Callback triggered by netmap notifications (see netmap_notify()), | ||||
* and by the application calling kevent(). In the former case we | * and by the application calling kevent(). In the former case we | ||||
* just return 1 (events ready), since we are not able to do better. | * just return 1 (events ready), since we are not able to do better. | ||||
* In the latter case we use netmap_poll() to see which events are | * In the latter case we use netmap_poll() to see which events are | ||||
* ready. | * ready. | ||||
▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | if (na == NULL) { | ||||
nm_prerr("no netmap adapter for this file descriptor"); | nm_prerr("no netmap adapter for this file descriptor"); | ||||
return 1; | return 1; | ||||
} | } | ||||
/* the si is indicated in the priv */ | /* the si is indicated in the priv */ | ||||
si = priv->np_si[(ev == EVFILT_WRITE) ? NR_TX : NR_RX]; | si = priv->np_si[(ev == EVFILT_WRITE) ? NR_TX : NR_RX]; | ||||
kn->kn_fop = (ev == EVFILT_WRITE) ? | kn->kn_fop = (ev == EVFILT_WRITE) ? | ||||
&netmap_wfiltops : &netmap_rfiltops; | &netmap_wfiltops : &netmap_rfiltops; | ||||
kn->kn_hook = priv; | kn->kn_hook = priv; | ||||
NMG_LOCK(); | |||||
si->kqueue_users++; | |||||
nm_prinf("kqueue users for %s: %d", si->mtxname, si->kqueue_users); | |||||
NMG_UNLOCK(); | |||||
knlist_add(&si->si.si_note, kn, /*islocked=*/0); | knlist_add(&si->si.si_note, kn, /*islocked=*/0); | ||||
return 0; | return 0; | ||||
} | } | ||||
static int | static int | ||||
freebsd_netmap_poll(struct cdev *cdevi __unused, int events, struct thread *td) | freebsd_netmap_poll(struct cdev *cdevi __unused, int events, struct thread *td) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 128 Lines • Show Last 20 Lines |