Beispiel #1
0
/* remove the monitor mkring from the list of monitors of kring.
 * If this is the last monitor, restore the original callbacks
 */
static void
netmap_monitor_del(struct netmap_kring *mkring, struct netmap_kring *kring)
{
	/* sinchronize with concurrently running nm_sync()s */
	nm_kr_stop(kring, NM_KR_LOCKED);
	kring->n_monitors--;
	if (mkring->mon_pos != kring->n_monitors) {
		kring->monitors[mkring->mon_pos] = kring->monitors[kring->n_monitors];
		kring->monitors[mkring->mon_pos]->mon_pos = mkring->mon_pos;
	}
	kring->monitors[kring->n_monitors] = NULL;
	if (kring->n_monitors == 0) {
		/* this was the last monitor, restore callbacks  and delete monitor array */
		D("%s: restoring sync on %s: %p", mkring->name, kring->name, kring->mon_sync);
		kring->nm_sync = kring->mon_sync;
		kring->mon_sync = NULL;
		if (kring->tx == NR_RX) {
			D("%s: restoring notify on %s: %p", 
					mkring->name, kring->name, kring->mon_notify);
			kring->nm_notify = kring->mon_notify;
			kring->mon_notify = NULL;
		}
		nm_monitor_dealloc(kring);
	}
	nm_kr_start(kring);
}
Beispiel #2
0
/* remove the monitor mkring from the list of monitors of kring.
 * If this is the last monitor, restore the original callbacks
 */
static void
netmap_monitor_del(struct netmap_kring *mkring, struct netmap_kring *kring)
{
	struct netmap_zmon_list *mz = &mkring->zmon_list[kring->tx];
	int zmon = nm_is_zmon(mkring->na);


	if (zmon && mz->prev != NULL)
		kring = mz->prev;

	/* sinchronize with concurrently running nm_sync()s */
	nm_kr_stop(kring, NM_KR_LOCKED);

	if (zmon) {
		/* remove the monitor from the list */
		if (mz->prev != NULL)
			mz->prev->zmon_list[kring->tx].next = mz->next;
		else
			kring->zmon_list[kring->tx].next = mz->next;
		if (mz->next != NULL) {
			mz->next->zmon_list[kring->tx].prev = mz->prev;
		} else {
			kring->zmon_list[kring->tx].prev = mz->prev;
		}
	} else {
		/* this is a copy monitor */
		uint32_t mon_pos = mkring->mon_pos[kring->tx];
		kring->n_monitors--;
		if (mon_pos != kring->n_monitors) {
			kring->monitors[mon_pos] =
				kring->monitors[kring->n_monitors];
			kring->monitors[mon_pos]->mon_pos[kring->tx] = mon_pos;
		}
		kring->monitors[kring->n_monitors] = NULL;
		if (kring->n_monitors == 0) {
			nm_monitor_dealloc(kring);
		}
	}

	if (nm_monitor_none(kring)) {
		/* this was the last monitor, restore the callbacks */
		ND("%s: restoring sync on %s: %p", mkring->name, kring->name,
				kring->mon_sync);
		kring->nm_sync = kring->mon_sync;
		kring->mon_sync = NULL;
		if (kring->tx == NR_RX) {
			ND("%s: restoring notify on %s: %p",
					mkring->name, kring->name, kring->mon_notify);
			kring->nm_notify = kring->mon_notify;
			kring->mon_notify = NULL;
		}
	}

	nm_kr_start(kring);
}
Beispiel #3
0
/* add the monitor mkring to the list of monitors of kring.
 * If this is the first monitor, intercept the callbacks
 */
static int
netmap_monitor_add(struct netmap_kring *mkring, struct netmap_kring *kring, int zcopy)
{
	int error = 0;

	/* sinchronize with concurrently running nm_sync()s */
	nm_kr_stop(kring, NM_KR_LOCKED);
	/* make sure the monitor array exists and is big enough */
	error = nm_monitor_alloc(kring, kring->n_monitors + 1);
	if (error)
		goto out;
	kring->monitors[kring->n_monitors] = mkring;
	mkring->mon_pos = kring->n_monitors;
	kring->n_monitors++;
	if (kring->n_monitors == 1) {
		/* this is the first monitor, intercept callbacks */
		D("%s: intercept callbacks on %s", mkring->name, kring->name);
		kring->mon_sync = kring->nm_sync;
		/* zcopy monitors do not override nm_notify(), but
		 * we save the original one regardless, so that
		 * netmap_monitor_del() does not need to know the
		 * monitor type
		 */
		kring->mon_notify = kring->nm_notify;
		if (kring->tx == NR_TX) {
			kring->nm_sync = (zcopy ? netmap_zmon_parent_txsync :
						  netmap_monitor_parent_txsync);
		} else {
			kring->nm_sync = (zcopy ? netmap_zmon_parent_rxsync :
						  netmap_monitor_parent_rxsync);
			if (!zcopy) {
				/* also intercept notify */
				kring->nm_notify = netmap_monitor_parent_notify;
				kring->mon_tail = kring->nr_hwtail;
			}
		}
	}

out:
	nm_kr_start(kring);
	return error;
}
Beispiel #4
0
/* add the monitor mkring to the list of monitors of kring.
 * If this is the first monitor, intercept the callbacks
 */
static int
netmap_monitor_add(struct netmap_kring *mkring, struct netmap_kring *kring, int zmon)
{
	int error = NM_IRQ_COMPLETED;
	enum txrx t = kring->tx;
	struct netmap_zmon_list *z = &kring->zmon_list[t];
	struct netmap_zmon_list *mz = &mkring->zmon_list[t];

	/* a zero-copy monitor which is not the first in the list
	 * must monitor the previous monitor
	 */
	if (zmon && z->prev != NULL)
		kring = z->prev;

	/* sinchronize with concurrently running nm_sync()s */
	nm_kr_stop(kring, NM_KR_LOCKED);

	if (nm_monitor_none(kring)) {
		/* this is the first monitor, intercept callbacks */
		ND("intercept callbacks on %s", kring->name);
		kring->mon_sync = kring->nm_sync;
		kring->mon_notify = kring->nm_notify;
		if (kring->tx == NR_TX) {
			kring->nm_sync = netmap_monitor_parent_txsync;
		} else {
			kring->nm_sync = netmap_monitor_parent_rxsync;
			kring->nm_notify = netmap_monitor_parent_notify;
			kring->mon_tail = kring->nr_hwtail;
		}
	}

	if (zmon) {
		/* append the zmon to the list */
		struct netmap_monitor_adapter *mna =
			(struct netmap_monitor_adapter *)mkring->na;
		struct netmap_adapter *pna;

		if (z->prev != NULL)
			z->prev->zmon_list[t].next = mkring;
		mz->prev = z->prev;
		z->prev = mkring;
		if (z->next == NULL)
			z->next = mkring;

		/* grap a reference to the previous netmap adapter
		 * in the chain (this may be the monitored port
		 * or another zero-copy monitor)
		 */
		pna = kring->na;
		netmap_adapter_get(pna);
		netmap_adapter_put(mna->priv.np_na);
		mna->priv.np_na = pna;
	} else {
		/* make sure the monitor array exists and is big enough */
		error = nm_monitor_alloc(kring, kring->n_monitors + 1);
		if (error)
			goto out;
		kring->monitors[kring->n_monitors] = mkring;
		mkring->mon_pos[kring->tx] = kring->n_monitors;
		kring->n_monitors++;
	}

out:
	nm_kr_start(kring);
	return error;
}