FreeBSD/sys/dev/netmap/netmap_monitor.c
/*
 * Common function for both zero-copy tx and rx nm_sync()
 * callbacks
 */
Common function for both zero-copy tx and rx nm_sync()
callbacks
Common function for both zero - copy tx and rx nm_sync () callbacks
static int
netmap_zmon_parent_sync(struct netmap_kring *kring, int flags, enum txrx tx)
{
	struct netmap_kring *mkring = kring->monitors[0];
	struct netmap_ring *ring = kring->ring, *mring;
	int error = 0;
	int rel_slots, free_slots, busy, sent = 0;
	u_int beg, end, i;
	u_int lim = kring->nkr_num_slots - 1,
	      mlim; 
	if (mkring == NULL) {
		RD(5, "NULL monitor on %s", kring->name);
		return 0;
	}
	mring = mkring->ring;
	mlim = mkring->nkr_num_slots - 1;
	if (tx == NR_TX) {
		beg = kring->nr_hwtail;
		error = kring->mon_sync(kring, flags);
		if (error)
			return error;
		end = kring->nr_hwtail;
	} else { 
		beg = kring->nr_hwcur;
		end = kring->rhead;
	}
	rel_slots = end - beg;
	if (rel_slots < 0)
		rel_slots += kring->nkr_num_slots;
	if (!rel_slots) {
		goto out_rxsync;
	}
	mtx_lock(&mkring->q_lock);
	i = mkring->nr_hwtail;
	busy = i - mkring->nr_hwcur;
	if (busy < 0)
		busy += mkring->nkr_num_slots;
	free_slots = mlim - busy;
	if (!free_slots)
		goto out;
	if (free_slots < rel_slots) {
		beg += (rel_slots - free_slots);
		if (beg >= kring->nkr_num_slots)
			beg -= kring->nkr_num_slots;
		rel_slots = free_slots;
	}
	sent = rel_slots;
	for ( ; rel_slots; rel_slots--) {
		struct netmap_slot *s = &ring->slot[beg];
		struct netmap_slot *ms = &mring->slot[i];
		uint32_t tmp;
		tmp = ms->buf_idx;
		ms->buf_idx = s->buf_idx;
		s->buf_idx = tmp;
		ND(5, "beg %d buf_idx %d", beg, tmp);
		tmp = ms->len;
		ms->len = s->len;
		s->len = tmp;
		s->flags |= NS_BUF_CHANGED;
		beg = nm_next(beg, lim);
		i = nm_next(i, mlim);
	}
	mb();
	mkring->nr_hwtail = i;
out:
	mtx_unlock(&mkring->q_lock);
	if (sent) {
		mkring->nm_notify(mkring, 0);
	}
out_rxsync:
	if (tx == NR_RX)
		error = kring->mon_sync(kring, flags);
	return error;
}
static int netmap_zmon_parent_sync ( struct netmap_kring * kring , int flags , enum txrx tx ) { struct netmap_kring * mkring = kring -> monitors [ 0 ] ; struct netmap_ring * ring = kring -> ring , * mring ; int error = 0 ; int rel_slots , free_slots , busy , sent = 0 ; u_int beg , end , i ; u_int lim = kring -> nkr_num_slots - 1 , mlim ; if ( mkring == NULL ) { RD ( 5 , " " , kring -> name ) ; return 0 ; } mring = mkring -> ring ; mlim = mkring -> nkr_num_slots - 1 ; if ( tx == NR_TX ) { beg = kring -> nr_hwtail ; error = kring -> mon_sync ( kring , flags ) ; if ( error ) return error ; end = kring -> nr_hwtail ; } else { beg = kring -> nr_hwcur ; end = kring -> rhead ; } rel_slots = end - beg ; if ( rel_slots < 0 ) rel_slots += kring -> nkr_num_slots ; if ( ! rel_slots ) { goto out_rxsync ; } mtx_lock ( & mkring -> q_lock ) ; i = mkring -> nr_hwtail ; busy = i - mkring -> nr_hwcur ; if ( busy < 0 ) busy += mkring -> nkr_num_slots ; free_slots = mlim - busy ; if ( ! free_slots ) goto out ; if ( free_slots < rel_slots ) { beg += ( rel_slots - free_slots ) ; if ( beg >= kring -> nkr_num_slots ) beg -= kring -> nkr_num_slots ; rel_slots = free_slots ; } sent = rel_slots ; for ( ; rel_slots ; rel_slots -- ) { struct netmap_slot * s = & ring -> slot [ beg ] ; struct netmap_slot * ms = & mring -> slot [ i ] ; uint32_t tmp ; tmp = ms -> buf_idx ; ms -> buf_idx = s -> buf_idx ; s -> buf_idx = tmp ; ND ( 5 , " " , beg , tmp ) ; tmp = ms -> len ; ms -> len = s -> len ; s -> len = tmp ; s -> flags |= NS_BUF_CHANGED ; beg = nm_next ( beg , lim ) ; i = nm_next ( i , mlim ) ; } mb ( ) ; mkring -> nr_hwtail = i ; out : mtx_unlock ( & mkring -> q_lock ) ; if ( sent ) { mkring -> nm_notify ( mkring , 0 ) ; } out_rxsync : if ( tx == NR_RX ) error = kring -> mon_sync ( kring , flags ) ; return error ; }
Common function for both zero-copy tx and rx nm_sync()
 callbacks
Common function for both zero - copy tx and rx nm_sync () callbacks
// = mkring->nkr_num_slots - 1; /* get the relased slots (rel_slots) */ /* NR_RX */ /* no released slots, but we still need
		 * to call rxsync if this is a rx ring
		 */ /* we need to lock the monitor receive ring, since it
	 * is the target of bot tx and rx traffic from the monitored
	 * adapter
	 */ /* get the free slots available on the monitor ring */ /* swap min(free_slots, rel_slots) slots */ /* notify the new frames to the monitor */