create the ring for a given element size */
| 237 | |
| 238 | /* create the ring for a given element size */ |
| 239 | struct rte_ring * |
| 240 | rte_ring_create_elem(const char *name, unsigned int esize, unsigned int count, |
| 241 | int socket_id, unsigned int flags) |
| 242 | { |
| 243 | char mz_name[RTE_MEMZONE_NAMESIZE]; |
| 244 | struct rte_ring *r; |
| 245 | struct rte_tailq_entry *te; |
| 246 | const struct rte_memzone *mz; |
| 247 | ssize_t ring_size; |
| 248 | int mz_flags = 0; |
| 249 | struct rte_ring_list* ring_list = NULL; |
| 250 | const unsigned int requested_count = count; |
| 251 | int ret; |
| 252 | |
| 253 | ring_list = RTE_TAILQ_CAST(rte_ring_tailq.head, rte_ring_list); |
| 254 | |
| 255 | /* for an exact size ring, round up from count to a power of two */ |
| 256 | if (flags & RING_F_EXACT_SZ) |
| 257 | count = rte_align32pow2(count + 1); |
| 258 | |
| 259 | ring_size = rte_ring_get_memsize_elem(esize, count); |
| 260 | if (ring_size < 0) { |
| 261 | rte_errno = -ring_size; |
| 262 | return NULL; |
| 263 | } |
| 264 | |
| 265 | ret = snprintf(mz_name, sizeof(mz_name), "%s%s", |
| 266 | RTE_RING_MZ_PREFIX, name); |
| 267 | if (ret < 0 || ret >= (int)sizeof(mz_name)) { |
| 268 | rte_errno = ENAMETOOLONG; |
| 269 | return NULL; |
| 270 | } |
| 271 | |
| 272 | te = rte_zmalloc("RING_TAILQ_ENTRY", sizeof(*te), 0); |
| 273 | if (te == NULL) { |
| 274 | RTE_LOG(ERR, RING, "Cannot reserve memory for tailq\n"); |
| 275 | rte_errno = ENOMEM; |
| 276 | return NULL; |
| 277 | } |
| 278 | |
| 279 | rte_mcfg_tailq_write_lock(); |
| 280 | |
| 281 | /* reserve a memory zone for this ring. If we can't get rte_config or |
| 282 | * we are secondary process, the memzone_reserve function will set |
| 283 | * rte_errno for us appropriately - hence no check in this function |
| 284 | */ |
| 285 | mz = rte_memzone_reserve_aligned(mz_name, ring_size, socket_id, |
| 286 | mz_flags, __alignof__(*r)); |
| 287 | if (mz != NULL) { |
| 288 | r = mz->addr; |
| 289 | /* no need to check return value here, we already checked the |
| 290 | * arguments above */ |
| 291 | rte_ring_init(r, name, requested_count, flags); |
| 292 | |
| 293 | te->data = (void *) r; |
| 294 | r->memzone = mz; |
| 295 | |
| 296 | TAILQ_INSERT_TAIL(ring_list, te, next); |