A-A+

Netmap分析(五)

2018年12月17日 netmap 暂无评论

实际设置netmap配置的函数

/*
 * possibly move the interface to netmap-mode.
 * If success it returns a pointer to netmap_if, otherwise NULL.
 * This must be called with NMG_LOCK held.
 *
 * The following na callbacks are called in the process:
 *
 * na->nm_config()			[by netmap_update_config]
 * (get current number and size of rings)
 *
 *  	We have a generic one for linux (netmap_linux_config).
 *  	The bwrap has to override this, since it has to forward
 *  	the request to the wrapped adapter (netmap_bwrap_config).
 *
 *
 * na->nm_krings_create()
 * (create and init the krings array)
 *
 * 	One of the following:
 *
 *	* netmap_hw_krings_create, 			(hw ports)
 *		creates the standard layout for the krings
 * 		and adds the mbq (used for the host rings).
 *
 * 	* netmap_vp_krings_create			(VALE ports)
 * 		add leases and scratchpads
 *
 * 	* netmap_pipe_krings_create			(pipes)
 * 		create the krings and rings of both ends and
 * 		cross-link them
 *
 *      * netmap_monitor_krings_create 			(monitors)
 *      	avoid allocating the mbq
 *
 *      * netmap_bwrap_krings_create			(bwraps)
 *      	create both the brap krings array,
 *      	the krings array of the wrapped adapter, and
 *      	(if needed) the fake array for the host adapter
 *
 * na->nm_register(, 1)
 * (put the adapter in netmap mode)
 *
 * 	This may be one of the following:
 *
 * 	* netmap_hw_reg				        (hw ports)
 * 		checks that the ifp is still there, then calls
 * 		the hardware specific callback;
 *
 * 	* netmap_vp_reg					(VALE ports)
 *		If the port is connected to a bridge,
 *		set the NAF_NETMAP_ON flag under the
 *		bridge write lock.
 *
 *	* netmap_pipe_reg				(pipes)
 *		inform the other pipe end that it is no
 *		longer responsibile for the lifetime of this
 *		pipe end
 *
 *	* netmap_monitor_reg				(monitors)
 *		intercept the sync callbacks of the monitored
 *		rings
 *
 *	* netmap_bwrap_reg				(bwraps)
 *		cross-link the bwrap and hwna rings,
 *		forward the request to the hwna, override
 *		the hwna notify callback (to get the frames
 *		coming from outside go through the bridge).
 *
 *
 */
int
netmap_do_regif(struct netmap_priv_d *priv, struct netmap_adapter *na,
	uint16_t ringid, uint32_t flags)
{
	struct netmap_if *nifp = NULL;
	int error;
 
	NMG_LOCK_ASSERT();
	/* ring configuration may have changed, fetch from the card */
	netmap_update_config(na);
	priv->np_na = na;     /* store the reference */
	error = netmap_set_ringid(priv, ringid, flags);
	if (error)
		goto err;
	error = netmap_mem_finalize(na->nm_mem, na);
	if (error)
		goto err;
 
	if (na->active_fds == 0) {
		/*
		 * If this is the first registration of the adapter,
		 * also create the netmap rings and their in-kernel view,
		 * the netmap krings.
		 */
 
		/*
		 * Depending on the adapter, this may also create
		 * the netmap rings themselves
		 */
		error = na->nm_krings_create(na);
		if (error)
			goto err_drop_mem;
 
		/* create all missing netmap rings */
		error = netmap_mem_rings_create(na);
		if (error)
			goto err_del_krings;
	}
 
	/* now the kring must exist and we can check whether some
	 * previous bind has exclusive ownership on them, and set
	 * nr_pending_mode
	 */
	error = netmap_krings_get(priv);
	if (error)
		goto err_del_rings;
 
	/* in all cases, create a new netmap if */
	nifp = netmap_mem_if_new(na);
	if (nifp == NULL) {
		error = ENOMEM;
		goto err_rel_excl;
	}
 
	if (na->active_fds == 0) {
		/* cache the allocator info in the na */
		error = netmap_mem_get_lut(na->nm_mem, &na->na_lut);
		if (error)
			goto err_del_if;
		D("lut %p bufs %u size %u", na->na_lut.lut, na->na_lut.objtotal,
					    na->na_lut.objsize);
	}
 
	if (nm_kring_pending(priv)) {
		/* Some kring is switching mode, tell the adapter to
		 * react on this. */
		error = na->nm_register(na, 1);
		if (error) 
			goto err_put_lut;
	}
 
	/* Commit the reference. */
	na->active_fds++;
 
	/*
	 * advertise that the interface is ready by setting np_nifp.
	 * The barrier is needed because readers (poll, *SYNC and mmap)
	 * check for priv->np_nifp != NULL without locking
	 */
	mb(); /* make sure previous writes are visible to all CPUs */
	priv->np_nifp = nifp;
 
	return 0;
 
err_put_lut:
	if (na->active_fds == 0)
		memset(&na->na_lut, 0, sizeof(na->na_lut));
err_del_if:
	netmap_mem_if_delete(na, nifp);
err_rel_excl:
	netmap_krings_put(priv);
err_del_rings:
	if (na->active_fds == 0)
		netmap_mem_rings_delete(na);
err_del_krings:
	if (na->active_fds == 0)
		na->nm_krings_delete(na);
err_drop_mem:
	netmap_mem_deref(na->nm_mem, na);
err:
	priv->np_na = NULL;
	return error;
}

 

标签:

给我留言

Copyright © 九毛的官方博客 保留所有权利.   Theme  Ality

用户登录