- char mz_name[RTE_MEMZONE_NAMESIZE];
- struct rte_event_ring *r;
- struct rte_tailq_entry *te;
- const struct rte_memzone *mz;
- ssize_t ring_size;
- int mz_flags = 0;
- struct rte_event_ring_list *ring_list = NULL;
- const unsigned int requested_count = count;
- int ret;
-
- ring_list = RTE_TAILQ_CAST(rte_event_ring_tailq.head,
- rte_event_ring_list);
-
- /* for an exact size ring, round up from count to a power of two */
- if (flags & RING_F_EXACT_SZ)
- count = rte_align32pow2(count + 1);
- else if (!rte_is_power_of_2(count)) {
- rte_errno = EINVAL;
- return NULL;
- }
-
- ring_size = sizeof(*r) + (count * sizeof(struct rte_event));
-
- ret = snprintf(mz_name, sizeof(mz_name), "%s%s",
- RTE_RING_MZ_PREFIX, name);
- if (ret < 0 || ret >= (int)sizeof(mz_name)) {
- rte_errno = ENAMETOOLONG;
- return NULL;
- }
-
- te = rte_zmalloc("RING_TAILQ_ENTRY", sizeof(*te), 0);
- if (te == NULL) {
- RTE_LOG(ERR, RING, "Cannot reserve memory for tailq\n");
- rte_errno = ENOMEM;
- return NULL;
- }
-
- rte_mcfg_tailq_write_lock();
-
- /*
- * reserve a memory zone for this ring. If we can't get rte_config or
- * we are secondary process, the memzone_reserve function will set
- * rte_errno for us appropriately - hence no check in this this function
- */
- mz = rte_memzone_reserve(mz_name, ring_size, socket_id, mz_flags);
- if (mz != NULL) {
- r = mz->addr;
- /* Check return value in case rte_ring_init() fails on size */
- int err = rte_event_ring_init(r, name, requested_count, flags);
- if (err) {
- RTE_LOG(ERR, RING, "Ring init failed\n");
- if (rte_memzone_free(mz) != 0)
- RTE_LOG(ERR, RING, "Cannot free memzone\n");
- rte_free(te);
- rte_mcfg_tailq_write_unlock();
- return NULL;
- }
-
- te->data = (void *) r;
- r->r.memzone = mz;
-
- TAILQ_INSERT_TAIL(ring_list, te, next);
- } else {
- r = NULL;
- RTE_LOG(ERR, RING, "Cannot reserve memory\n");
- rte_free(te);
- }
- rte_mcfg_tailq_write_unlock();
-
- return r;