1
2
3
4
5#include <string.h>
6
7#include <rte_string_fns.h>
8#include <rte_atomic.h>
9#include <rte_eal.h>
10#include <rte_eal_memconfig.h>
11#include <rte_errno.h>
12#include <rte_malloc.h>
13#include <rte_memzone.h>
14#include <rte_rwlock.h>
15#include <rte_tailq.h>
16
17#include "rte_stack.h"
18#include "stack_pvt.h"
19
20TAILQ_HEAD(rte_stack_list, rte_tailq_entry);
21
22static struct rte_tailq_elem rte_stack_tailq = {
23 .name = RTE_TAILQ_STACK_NAME,
24};
25EAL_REGISTER_TAILQ(rte_stack_tailq)
26
27
28static void
29rte_stack_init(struct rte_stack *s, unsigned int count, uint32_t flags)
30{
31 memset(s, 0, sizeof(*s));
32
33 if (flags & RTE_STACK_F_LF)
34 rte_stack_lf_init(s, count);
35 else
36 rte_stack_std_init(s);
37}
38
39static ssize_t
40rte_stack_get_memsize(unsigned int count, uint32_t flags)
41{
42 if (flags & RTE_STACK_F_LF)
43 return rte_stack_lf_get_memsize(count);
44 else
45 return rte_stack_std_get_memsize(count);
46}
47
48struct rte_stack *
49rte_stack_create(const char *name, unsigned int count, int socket_id,
50 uint32_t flags)
51{
52 char mz_name[RTE_MEMZONE_NAMESIZE];
53 struct rte_stack_list *stack_list;
54 const struct rte_memzone *mz;
55 struct rte_tailq_entry *te;
56 struct rte_stack *s;
57 unsigned int sz;
58 int ret;
59
60 if (flags & ~(RTE_STACK_F_LF)) {
61 STACK_LOG_ERR("Unsupported stack flags %#x\n", flags);
62 return NULL;
63 }
64
65#ifdef RTE_ARCH_64
66 RTE_BUILD_BUG_ON(sizeof(struct rte_stack_lf_head) != 16);
67#else
68 if (flags & RTE_STACK_F_LF) {
69 STACK_LOG_ERR("Lock-free stack is not supported on your platform\n");
70 return NULL;
71 }
72#endif
73
74 sz = rte_stack_get_memsize(count, flags);
75
76 ret = snprintf(mz_name, sizeof(mz_name), "%s%s",
77 RTE_STACK_MZ_PREFIX, name);
78 if (ret < 0 || ret >= (int)sizeof(mz_name)) {
79 rte_errno = ENAMETOOLONG;
80 return NULL;
81 }
82
83 te = rte_zmalloc("STACK_TAILQ_ENTRY", sizeof(*te), 0);
84 if (te == NULL) {
85 STACK_LOG_ERR("Cannot reserve memory for tailq\n");
86 rte_errno = ENOMEM;
87 return NULL;
88 }
89
90 rte_mcfg_tailq_write_lock();
91
92 mz = rte_memzone_reserve_aligned(mz_name, sz, socket_id,
93 0, __alignof__(*s));
94 if (mz == NULL) {
95 STACK_LOG_ERR("Cannot reserve stack memzone!\n");
96 rte_mcfg_tailq_write_unlock();
97 rte_free(te);
98 return NULL;
99 }
100
101 s = mz->addr;
102
103 rte_stack_init(s, count, flags);
104
105
106 ret = strlcpy(s->name, name, sizeof(s->name));
107 if (ret < 0 || ret >= (int)sizeof(s->name)) {
108 rte_mcfg_tailq_write_unlock();
109
110 rte_errno = ENAMETOOLONG;
111 rte_free(te);
112 rte_memzone_free(mz);
113 return NULL;
114 }
115
116 s->memzone = mz;
117 s->capacity = count;
118 s->flags = flags;
119
120 te->data = s;
121
122 stack_list = RTE_TAILQ_CAST(rte_stack_tailq.head, rte_stack_list);
123
124 TAILQ_INSERT_TAIL(stack_list, te, next);
125
126 rte_mcfg_tailq_write_unlock();
127
128 return s;
129}
130
131void
132rte_stack_free(struct rte_stack *s)
133{
134 struct rte_stack_list *stack_list;
135 struct rte_tailq_entry *te;
136
137 if (s == NULL)
138 return;
139
140 stack_list = RTE_TAILQ_CAST(rte_stack_tailq.head, rte_stack_list);
141 rte_mcfg_tailq_write_lock();
142
143
144 TAILQ_FOREACH(te, stack_list, next) {
145 if (te->data == s)
146 break;
147 }
148
149 if (te == NULL) {
150 rte_mcfg_tailq_write_unlock();
151 return;
152 }
153
154 TAILQ_REMOVE(stack_list, te, next);
155
156 rte_mcfg_tailq_write_unlock();
157
158 rte_free(te);
159
160 rte_memzone_free(s->memzone);
161}
162
163struct rte_stack *
164rte_stack_lookup(const char *name)
165{
166 struct rte_stack_list *stack_list;
167 struct rte_tailq_entry *te;
168 struct rte_stack *r = NULL;
169
170 if (name == NULL) {
171 rte_errno = EINVAL;
172 return NULL;
173 }
174
175 stack_list = RTE_TAILQ_CAST(rte_stack_tailq.head, rte_stack_list);
176
177 rte_mcfg_tailq_read_lock();
178
179 TAILQ_FOREACH(te, stack_list, next) {
180 r = (struct rte_stack *) te->data;
181 if (strncmp(name, r->name, RTE_STACK_NAMESIZE) == 0)
182 break;
183 }
184
185 rte_mcfg_tailq_read_unlock();
186
187 if (te == NULL) {
188 rte_errno = ENOENT;
189 return NULL;
190 }
191
192 return r;
193}
194
195RTE_LOG_REGISTER(stack_logtype, lib.stack, NOTICE);
196