src/dpdk/lib/librte_mbuf/rte_mbuf.c
struct rte_mempool *
rte_pktmbuf_pool_create_extbuf(const char *name, unsigned int n,
	unsigned int cache_size, uint16_t priv_size,
	uint16_t data_room_size, int socket_id,
	const struct rte_pktmbuf_extmem *ext_mem,
	unsigned int ext_num)
{
	struct rte_mempool *mp;
	struct rte_pktmbuf_pool_private mbp_priv;
	struct rte_pktmbuf_extmem_init_ctx init_ctx;
	const char *mp_ops_name;
	unsigned int elt_size;
	unsigned int i, n_elts = 0;
	int ret;

	if (RTE_ALIGN(priv_size, RTE_MBUF_PRIV_ALIGN) != priv_size) {
		RTE_LOG(ERR, MBUF, "mbuf priv_size=%u is not aligned\n",
			priv_size);
		rte_errno = EINVAL;
		return NULL;
	}
	/* Check the external memory descriptors. */
	for (i = 0; i < ext_num; i++) {
		const struct rte_pktmbuf_extmem *extm = ext_mem + i;

		if (!extm->elt_size || !extm->buf_len || !extm->buf_ptr) {
			RTE_LOG(ERR, MBUF, "invalid extmem descriptor\n");
			rte_errno = EINVAL;
			return NULL;
		}
		if (data_room_size > extm->elt_size) {
			RTE_LOG(ERR, MBUF, "ext elt_size=%u is too small\n",
				priv_size);
			rte_errno = EINVAL;
			return NULL;
		}
		n_elts += extm->buf_len / extm->elt_size;
	}
	/* Check whether enough external memory provided. */
	if (n_elts < n) {
		RTE_LOG(ERR, MBUF, "not enough extmem\n");
		rte_errno = ENOMEM;
		return NULL;
	}
	elt_size = sizeof(struct rte_mbuf) +
		   (unsigned int)priv_size +
		   sizeof(struct rte_mbuf_ext_shared_info);

	memset(&mbp_priv, 0, sizeof(mbp_priv));
	mbp_priv.mbuf_data_room_size = data_room_size;
	mbp_priv.mbuf_priv_size = priv_size;
	mbp_priv.flags = RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF;

	mp = rte_mempool_create_empty(name, n, elt_size, cache_size,
		 sizeof(struct rte_pktmbuf_pool_private), socket_id, 0);
	if (mp == NULL)
		return NULL;

	mp_ops_name = rte_mbuf_best_mempool_ops();
	ret = rte_mempool_set_ops_byname(mp, mp_ops_name, NULL);
	if (ret != 0) {
		RTE_LOG(ERR, MBUF, "error setting mempool handler\n");
		rte_mempool_free(mp);
		rte_errno = -ret;
		return NULL;
	}
	rte_pktmbuf_pool_init(mp, &mbp_priv);

	ret = rte_mempool_populate_default(mp);
	if (ret < 0) {
		rte_mempool_free(mp);
		rte_errno = -ret;
		return NULL;
	}

	init_ctx = (struct rte_pktmbuf_extmem_init_ctx){
		.ext_mem = ext_mem,
		.ext_num = ext_num,
		.ext = 0,
		.off = 0,
	};
	rte_mempool_obj_iter(mp, __rte_pktmbuf_init_extmem, &init_ctx);

	return mp;
}
/* Helper to create a mbuf pool with pinned external data buffers. */
Helper to create a mbuf pool with pinned external data buffers.
Helper to create a mbuf pool with pinned external data buffers .
struct rte_mempool *
rte_pktmbuf_pool_create_extbuf(const char *name, unsigned int n,
	unsigned int cache_size, uint16_t priv_size,
	uint16_t data_room_size, int socket_id,
	const struct rte_pktmbuf_extmem *ext_mem,
	unsigned int ext_num)
{
	struct rte_mempool *mp;
	struct rte_pktmbuf_pool_private mbp_priv;
	struct rte_pktmbuf_extmem_init_ctx init_ctx;
	const char *mp_ops_name;
	unsigned int elt_size;
	unsigned int i, n_elts = 0;
	int ret;
	if (RTE_ALIGN(priv_size, RTE_MBUF_PRIV_ALIGN) != priv_size) {
		RTE_LOG(ERR, MBUF, "mbuf priv_size=%u is not aligned\n",
			priv_size);
		rte_errno = EINVAL;
		return NULL;
	}
	for (i = 0; i < ext_num; i++) {
		const struct rte_pktmbuf_extmem *extm = ext_mem + i;
		if (!extm->elt_size || !extm->buf_len || !extm->buf_ptr) {
			RTE_LOG(ERR, MBUF, "invalid extmem descriptor\n");
			rte_errno = EINVAL;
			return NULL;
		}
		if (data_room_size > extm->elt_size) {
			RTE_LOG(ERR, MBUF, "ext elt_size=%u is too small\n",
				priv_size);
			rte_errno = EINVAL;
			return NULL;
		}
		n_elts += extm->buf_len / extm->elt_size;
	}
	if (n_elts < n) {
		RTE_LOG(ERR, MBUF, "not enough extmem\n");
		rte_errno = ENOMEM;
		return NULL;
	}
	elt_size = sizeof(struct rte_mbuf) +
		   (unsigned int)priv_size +
		   sizeof(struct rte_mbuf_ext_shared_info);
	memset(&mbp_priv, 0, sizeof(mbp_priv));
	mbp_priv.mbuf_data_room_size = data_room_size;
	mbp_priv.mbuf_priv_size = priv_size;
	mbp_priv.flags = RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF;
	mp = rte_mempool_create_empty(name, n, elt_size, cache_size,
		 sizeof(struct rte_pktmbuf_pool_private), socket_id, 0);
	if (mp == NULL)
		return NULL;
	mp_ops_name = rte_mbuf_best_mempool_ops();
	ret = rte_mempool_set_ops_byname(mp, mp_ops_name, NULL);
	if (ret != 0) {
		RTE_LOG(ERR, MBUF, "error setting mempool handler\n");
		rte_mempool_free(mp);
		rte_errno = -ret;
		return NULL;
	}
	rte_pktmbuf_pool_init(mp, &mbp_priv);
	ret = rte_mempool_populate_default(mp);
	if (ret < 0) {
		rte_mempool_free(mp);
		rte_errno = -ret;
		return NULL;
	}
	init_ctx = (struct rte_pktmbuf_extmem_init_ctx){
		.ext_mem = ext_mem,
		.ext_num = ext_num,
		.ext = 0,
		.off = 0,
	};
	rte_mempool_obj_iter(mp, __rte_pktmbuf_init_extmem, &init_ctx);
	return mp;
}
struct rte_mempool * rte_pktmbuf_pool_create_extbuf ( const char * name , unsigned int n , unsigned int cache_size , uint16_t priv_size , uint16_t data_room_size , int socket_id , const struct rte_pktmbuf_extmem * ext_mem , unsigned int ext_num ) { struct rte_mempool * mp ; struct rte_pktmbuf_pool_private mbp_priv ; struct rte_pktmbuf_extmem_init_ctx init_ctx ; const char * mp_ops_name ; unsigned int elt_size ; unsigned int i , n_elts = 0 ; int ret ; if ( RTE_ALIGN ( priv_size , RTE_MBUF_PRIV_ALIGN ) != priv_size ) { RTE_LOG ( ERR , MBUF , " \n " , priv_size ) ; rte_errno = EINVAL ; return NULL ; } for ( i = 0 ; i < ext_num ; i ++ ) { const struct rte_pktmbuf_extmem * extm = ext_mem + i ; if ( ! extm -> elt_size || ! extm -> buf_len || ! extm -> buf_ptr ) { RTE_LOG ( ERR , MBUF , " \n " ) ; rte_errno = EINVAL ; return NULL ; } if ( data_room_size > extm -> elt_size ) { RTE_LOG ( ERR , MBUF , " \n " , priv_size ) ; rte_errno = EINVAL ; return NULL ; } n_elts += extm -> buf_len / extm -> elt_size ; } if ( n_elts < n ) { RTE_LOG ( ERR , MBUF , " \n " ) ; rte_errno = ENOMEM ; return NULL ; } elt_size = sizeof ( struct rte_mbuf ) + ( unsigned int ) priv_size + sizeof ( struct rte_mbuf_ext_shared_info ) ; memset ( & mbp_priv , 0 , sizeof ( mbp_priv ) ) ; mbp_priv . mbuf_data_room_size = data_room_size ; mbp_priv . mbuf_priv_size = priv_size ; mbp_priv . flags = RTE_PKTMBUF_POOL_F_PINNED_EXT_BUF ; mp = rte_mempool_create_empty ( name , n , elt_size , cache_size , sizeof ( struct rte_pktmbuf_pool_private ) , socket_id , 0 ) ; if ( mp == NULL ) return NULL ; mp_ops_name = rte_mbuf_best_mempool_ops ( ) ; ret = rte_mempool_set_ops_byname ( mp , mp_ops_name , NULL ) ; if ( ret != 0 ) { RTE_LOG ( ERR , MBUF , " \n " ) ; rte_mempool_free ( mp ) ; rte_errno = - ret ; return NULL ; } rte_pktmbuf_pool_init ( mp , & mbp_priv ) ; ret = rte_mempool_populate_default ( mp ) ; if ( ret < 0 ) { rte_mempool_free ( mp ) ; rte_errno = - ret ; return NULL ; } init_ctx = ( struct rte_pktmbuf_extmem_init_ctx ) { . ext_mem = ext_mem , . ext_num = ext_num , . ext = 0 , . off = 0 , } ; rte_mempool_obj_iter ( mp , __rte_pktmbuf_init_extmem , & init_ctx ) ; return mp ; }
Helper to create a mbuf pool with pinned external data buffers.
Helper to create a mbuf pool with pinned external data buffers .
/* Check the external memory descriptors. */ /* Check whether enough external memory provided. */