xref: /f-stack/dpdk/lib/librte_stack/rte_stack.c (revision 2d9fd380)
14418919fSjohnjiang /* SPDX-License-Identifier: BSD-3-Clause
24418919fSjohnjiang  * Copyright(c) 2019 Intel Corporation
34418919fSjohnjiang  */
44418919fSjohnjiang 
54418919fSjohnjiang #include <string.h>
64418919fSjohnjiang 
74418919fSjohnjiang #include <rte_string_fns.h>
84418919fSjohnjiang #include <rte_atomic.h>
94418919fSjohnjiang #include <rte_eal.h>
104418919fSjohnjiang #include <rte_eal_memconfig.h>
114418919fSjohnjiang #include <rte_errno.h>
124418919fSjohnjiang #include <rte_malloc.h>
134418919fSjohnjiang #include <rte_memzone.h>
144418919fSjohnjiang #include <rte_rwlock.h>
154418919fSjohnjiang #include <rte_tailq.h>
164418919fSjohnjiang 
174418919fSjohnjiang #include "rte_stack.h"
184418919fSjohnjiang #include "stack_pvt.h"
194418919fSjohnjiang 
204418919fSjohnjiang TAILQ_HEAD(rte_stack_list, rte_tailq_entry);
214418919fSjohnjiang 
224418919fSjohnjiang static struct rte_tailq_elem rte_stack_tailq = {
234418919fSjohnjiang 	.name = RTE_TAILQ_STACK_NAME,
244418919fSjohnjiang };
EAL_REGISTER_TAILQ(rte_stack_tailq)254418919fSjohnjiang EAL_REGISTER_TAILQ(rte_stack_tailq)
264418919fSjohnjiang 
274418919fSjohnjiang 
284418919fSjohnjiang static void
294418919fSjohnjiang rte_stack_init(struct rte_stack *s, unsigned int count, uint32_t flags)
304418919fSjohnjiang {
314418919fSjohnjiang 	memset(s, 0, sizeof(*s));
324418919fSjohnjiang 
334418919fSjohnjiang 	if (flags & RTE_STACK_F_LF)
344418919fSjohnjiang 		rte_stack_lf_init(s, count);
354418919fSjohnjiang 	else
364418919fSjohnjiang 		rte_stack_std_init(s);
374418919fSjohnjiang }
384418919fSjohnjiang 
394418919fSjohnjiang static ssize_t
rte_stack_get_memsize(unsigned int count,uint32_t flags)404418919fSjohnjiang rte_stack_get_memsize(unsigned int count, uint32_t flags)
414418919fSjohnjiang {
424418919fSjohnjiang 	if (flags & RTE_STACK_F_LF)
434418919fSjohnjiang 		return rte_stack_lf_get_memsize(count);
444418919fSjohnjiang 	else
454418919fSjohnjiang 		return rte_stack_std_get_memsize(count);
464418919fSjohnjiang }
474418919fSjohnjiang 
484418919fSjohnjiang struct rte_stack *
rte_stack_create(const char * name,unsigned int count,int socket_id,uint32_t flags)494418919fSjohnjiang rte_stack_create(const char *name, unsigned int count, int socket_id,
504418919fSjohnjiang 		 uint32_t flags)
514418919fSjohnjiang {
524418919fSjohnjiang 	char mz_name[RTE_MEMZONE_NAMESIZE];
534418919fSjohnjiang 	struct rte_stack_list *stack_list;
544418919fSjohnjiang 	const struct rte_memzone *mz;
554418919fSjohnjiang 	struct rte_tailq_entry *te;
564418919fSjohnjiang 	struct rte_stack *s;
574418919fSjohnjiang 	unsigned int sz;
584418919fSjohnjiang 	int ret;
594418919fSjohnjiang 
60*2d9fd380Sjfb8856606 	if (flags & ~(RTE_STACK_F_LF)) {
61*2d9fd380Sjfb8856606 		STACK_LOG_ERR("Unsupported stack flags %#x\n", flags);
62*2d9fd380Sjfb8856606 		return NULL;
63*2d9fd380Sjfb8856606 	}
64*2d9fd380Sjfb8856606 
654418919fSjohnjiang #ifdef RTE_ARCH_64
664418919fSjohnjiang 	RTE_BUILD_BUG_ON(sizeof(struct rte_stack_lf_head) != 16);
674418919fSjohnjiang #else
684418919fSjohnjiang 	if (flags & RTE_STACK_F_LF) {
694418919fSjohnjiang 		STACK_LOG_ERR("Lock-free stack is not supported on your platform\n");
704418919fSjohnjiang 		return NULL;
714418919fSjohnjiang 	}
724418919fSjohnjiang #endif
734418919fSjohnjiang 
744418919fSjohnjiang 	sz = rte_stack_get_memsize(count, flags);
754418919fSjohnjiang 
764418919fSjohnjiang 	ret = snprintf(mz_name, sizeof(mz_name), "%s%s",
774418919fSjohnjiang 		       RTE_STACK_MZ_PREFIX, name);
784418919fSjohnjiang 	if (ret < 0 || ret >= (int)sizeof(mz_name)) {
794418919fSjohnjiang 		rte_errno = ENAMETOOLONG;
804418919fSjohnjiang 		return NULL;
814418919fSjohnjiang 	}
824418919fSjohnjiang 
834418919fSjohnjiang 	te = rte_zmalloc("STACK_TAILQ_ENTRY", sizeof(*te), 0);
844418919fSjohnjiang 	if (te == NULL) {
854418919fSjohnjiang 		STACK_LOG_ERR("Cannot reserve memory for tailq\n");
864418919fSjohnjiang 		rte_errno = ENOMEM;
874418919fSjohnjiang 		return NULL;
884418919fSjohnjiang 	}
894418919fSjohnjiang 
904418919fSjohnjiang 	rte_mcfg_tailq_write_lock();
914418919fSjohnjiang 
924418919fSjohnjiang 	mz = rte_memzone_reserve_aligned(mz_name, sz, socket_id,
934418919fSjohnjiang 					 0, __alignof__(*s));
944418919fSjohnjiang 	if (mz == NULL) {
954418919fSjohnjiang 		STACK_LOG_ERR("Cannot reserve stack memzone!\n");
964418919fSjohnjiang 		rte_mcfg_tailq_write_unlock();
974418919fSjohnjiang 		rte_free(te);
984418919fSjohnjiang 		return NULL;
994418919fSjohnjiang 	}
1004418919fSjohnjiang 
1014418919fSjohnjiang 	s = mz->addr;
1024418919fSjohnjiang 
1034418919fSjohnjiang 	rte_stack_init(s, count, flags);
1044418919fSjohnjiang 
1054418919fSjohnjiang 	/* Store the name for later lookups */
1064418919fSjohnjiang 	ret = strlcpy(s->name, name, sizeof(s->name));
1074418919fSjohnjiang 	if (ret < 0 || ret >= (int)sizeof(s->name)) {
1084418919fSjohnjiang 		rte_mcfg_tailq_write_unlock();
1094418919fSjohnjiang 
1104418919fSjohnjiang 		rte_errno = ENAMETOOLONG;
1114418919fSjohnjiang 		rte_free(te);
1124418919fSjohnjiang 		rte_memzone_free(mz);
1134418919fSjohnjiang 		return NULL;
1144418919fSjohnjiang 	}
1154418919fSjohnjiang 
1164418919fSjohnjiang 	s->memzone = mz;
1174418919fSjohnjiang 	s->capacity = count;
1184418919fSjohnjiang 	s->flags = flags;
1194418919fSjohnjiang 
1204418919fSjohnjiang 	te->data = s;
1214418919fSjohnjiang 
1224418919fSjohnjiang 	stack_list = RTE_TAILQ_CAST(rte_stack_tailq.head, rte_stack_list);
1234418919fSjohnjiang 
1244418919fSjohnjiang 	TAILQ_INSERT_TAIL(stack_list, te, next);
1254418919fSjohnjiang 
1264418919fSjohnjiang 	rte_mcfg_tailq_write_unlock();
1274418919fSjohnjiang 
1284418919fSjohnjiang 	return s;
1294418919fSjohnjiang }
1304418919fSjohnjiang 
1314418919fSjohnjiang void
rte_stack_free(struct rte_stack * s)1324418919fSjohnjiang rte_stack_free(struct rte_stack *s)
1334418919fSjohnjiang {
1344418919fSjohnjiang 	struct rte_stack_list *stack_list;
1354418919fSjohnjiang 	struct rte_tailq_entry *te;
1364418919fSjohnjiang 
1374418919fSjohnjiang 	if (s == NULL)
1384418919fSjohnjiang 		return;
1394418919fSjohnjiang 
1404418919fSjohnjiang 	stack_list = RTE_TAILQ_CAST(rte_stack_tailq.head, rte_stack_list);
1414418919fSjohnjiang 	rte_mcfg_tailq_write_lock();
1424418919fSjohnjiang 
1434418919fSjohnjiang 	/* find out tailq entry */
1444418919fSjohnjiang 	TAILQ_FOREACH(te, stack_list, next) {
1454418919fSjohnjiang 		if (te->data == s)
1464418919fSjohnjiang 			break;
1474418919fSjohnjiang 	}
1484418919fSjohnjiang 
1494418919fSjohnjiang 	if (te == NULL) {
1504418919fSjohnjiang 		rte_mcfg_tailq_write_unlock();
1514418919fSjohnjiang 		return;
1524418919fSjohnjiang 	}
1534418919fSjohnjiang 
1544418919fSjohnjiang 	TAILQ_REMOVE(stack_list, te, next);
1554418919fSjohnjiang 
1564418919fSjohnjiang 	rte_mcfg_tailq_write_unlock();
1574418919fSjohnjiang 
1584418919fSjohnjiang 	rte_free(te);
1594418919fSjohnjiang 
1604418919fSjohnjiang 	rte_memzone_free(s->memzone);
1614418919fSjohnjiang }
1624418919fSjohnjiang 
1634418919fSjohnjiang struct rte_stack *
rte_stack_lookup(const char * name)1644418919fSjohnjiang rte_stack_lookup(const char *name)
1654418919fSjohnjiang {
1664418919fSjohnjiang 	struct rte_stack_list *stack_list;
1674418919fSjohnjiang 	struct rte_tailq_entry *te;
1684418919fSjohnjiang 	struct rte_stack *r = NULL;
1694418919fSjohnjiang 
1704418919fSjohnjiang 	if (name == NULL) {
1714418919fSjohnjiang 		rte_errno = EINVAL;
1724418919fSjohnjiang 		return NULL;
1734418919fSjohnjiang 	}
1744418919fSjohnjiang 
1754418919fSjohnjiang 	stack_list = RTE_TAILQ_CAST(rte_stack_tailq.head, rte_stack_list);
1764418919fSjohnjiang 
1774418919fSjohnjiang 	rte_mcfg_tailq_read_lock();
1784418919fSjohnjiang 
1794418919fSjohnjiang 	TAILQ_FOREACH(te, stack_list, next) {
1804418919fSjohnjiang 		r = (struct rte_stack *) te->data;
1814418919fSjohnjiang 		if (strncmp(name, r->name, RTE_STACK_NAMESIZE) == 0)
1824418919fSjohnjiang 			break;
1834418919fSjohnjiang 	}
1844418919fSjohnjiang 
1854418919fSjohnjiang 	rte_mcfg_tailq_read_unlock();
1864418919fSjohnjiang 
1874418919fSjohnjiang 	if (te == NULL) {
1884418919fSjohnjiang 		rte_errno = ENOENT;
1894418919fSjohnjiang 		return NULL;
1904418919fSjohnjiang 	}
1914418919fSjohnjiang 
1924418919fSjohnjiang 	return r;
1934418919fSjohnjiang }
1944418919fSjohnjiang 
195*2d9fd380Sjfb8856606 RTE_LOG_REGISTER(stack_logtype, lib.stack, NOTICE);
196