199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson * Copyright(c) 2010-2014 Intel Corporation
399a2dd95SBruce Richardson */
499a2dd95SBruce Richardson
599a2dd95SBruce Richardson #include <sys/queue.h>
699a2dd95SBruce Richardson #include <stdio.h>
799a2dd95SBruce Richardson #include <string.h>
899a2dd95SBruce Richardson
999a2dd95SBruce Richardson #include <rte_eal.h>
1099a2dd95SBruce Richardson #include <rte_eal_memconfig.h>
1199a2dd95SBruce Richardson #include <rte_log.h>
1299a2dd95SBruce Richardson #include <rte_string_fns.h>
1399a2dd95SBruce Richardson
1499a2dd95SBruce Richardson #include "eal_private.h"
1599a2dd95SBruce Richardson #include "eal_memcfg.h"
1699a2dd95SBruce Richardson
1799a2dd95SBruce Richardson TAILQ_HEAD(rte_tailq_elem_head, rte_tailq_elem);
1899a2dd95SBruce Richardson /* local tailq list */
1999a2dd95SBruce Richardson static struct rte_tailq_elem_head rte_tailq_elem_head =
2099a2dd95SBruce Richardson TAILQ_HEAD_INITIALIZER(rte_tailq_elem_head);
2199a2dd95SBruce Richardson
2299a2dd95SBruce Richardson /* number of tailqs registered, -1 before call to rte_eal_tailqs_init */
2399a2dd95SBruce Richardson static int rte_tailqs_count = -1;
2499a2dd95SBruce Richardson
2599a2dd95SBruce Richardson struct rte_tailq_head *
rte_eal_tailq_lookup(const char * name)2699a2dd95SBruce Richardson rte_eal_tailq_lookup(const char *name)
2799a2dd95SBruce Richardson {
2899a2dd95SBruce Richardson unsigned i;
2999a2dd95SBruce Richardson struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
3099a2dd95SBruce Richardson
3199a2dd95SBruce Richardson if (name == NULL)
3299a2dd95SBruce Richardson return NULL;
3399a2dd95SBruce Richardson
3499a2dd95SBruce Richardson for (i = 0; i < RTE_MAX_TAILQ; i++) {
3599a2dd95SBruce Richardson if (!strncmp(name, mcfg->tailq_head[i].name,
3699a2dd95SBruce Richardson RTE_TAILQ_NAMESIZE-1))
3799a2dd95SBruce Richardson return &mcfg->tailq_head[i];
3899a2dd95SBruce Richardson }
3999a2dd95SBruce Richardson
4099a2dd95SBruce Richardson return NULL;
4199a2dd95SBruce Richardson }
4299a2dd95SBruce Richardson
4399a2dd95SBruce Richardson void
rte_dump_tailq(FILE * f)4499a2dd95SBruce Richardson rte_dump_tailq(FILE *f)
4599a2dd95SBruce Richardson {
4699a2dd95SBruce Richardson struct rte_mem_config *mcfg;
4799a2dd95SBruce Richardson unsigned i = 0;
4899a2dd95SBruce Richardson
4999a2dd95SBruce Richardson mcfg = rte_eal_get_configuration()->mem_config;
5099a2dd95SBruce Richardson
5199a2dd95SBruce Richardson rte_mcfg_tailq_read_lock();
5299a2dd95SBruce Richardson for (i = 0; i < RTE_MAX_TAILQ; i++) {
5399a2dd95SBruce Richardson const struct rte_tailq_head *tailq = &mcfg->tailq_head[i];
5499a2dd95SBruce Richardson const struct rte_tailq_entry_head *head = &tailq->tailq_head;
5599a2dd95SBruce Richardson
5699a2dd95SBruce Richardson fprintf(f, "Tailq %u: qname:<%s>, tqh_first:%p, tqh_last:%p\n",
5799a2dd95SBruce Richardson i, tailq->name, head->tqh_first, head->tqh_last);
5899a2dd95SBruce Richardson }
5999a2dd95SBruce Richardson rte_mcfg_tailq_read_unlock();
6099a2dd95SBruce Richardson }
6199a2dd95SBruce Richardson
6299a2dd95SBruce Richardson static struct rte_tailq_head *
rte_eal_tailq_create(const char * name)6399a2dd95SBruce Richardson rte_eal_tailq_create(const char *name)
6499a2dd95SBruce Richardson {
6599a2dd95SBruce Richardson struct rte_tailq_head *head = NULL;
6699a2dd95SBruce Richardson
6799a2dd95SBruce Richardson if (!rte_eal_tailq_lookup(name) &&
6899a2dd95SBruce Richardson (rte_tailqs_count + 1 < RTE_MAX_TAILQ)) {
6999a2dd95SBruce Richardson struct rte_mem_config *mcfg;
7099a2dd95SBruce Richardson
7199a2dd95SBruce Richardson mcfg = rte_eal_get_configuration()->mem_config;
7299a2dd95SBruce Richardson head = &mcfg->tailq_head[rte_tailqs_count];
7399a2dd95SBruce Richardson strlcpy(head->name, name, sizeof(head->name) - 1);
7499a2dd95SBruce Richardson TAILQ_INIT(&head->tailq_head);
7599a2dd95SBruce Richardson rte_tailqs_count++;
7699a2dd95SBruce Richardson }
7799a2dd95SBruce Richardson
7899a2dd95SBruce Richardson return head;
7999a2dd95SBruce Richardson }
8099a2dd95SBruce Richardson
8199a2dd95SBruce Richardson /* local register, used to store "early" tailqs before rte_eal_init() and to
8299a2dd95SBruce Richardson * ensure secondary process only registers tailqs once. */
8399a2dd95SBruce Richardson static int
rte_eal_tailq_local_register(struct rte_tailq_elem * t)8499a2dd95SBruce Richardson rte_eal_tailq_local_register(struct rte_tailq_elem *t)
8599a2dd95SBruce Richardson {
8699a2dd95SBruce Richardson struct rte_tailq_elem *temp;
8799a2dd95SBruce Richardson
8899a2dd95SBruce Richardson TAILQ_FOREACH(temp, &rte_tailq_elem_head, next) {
8999a2dd95SBruce Richardson if (!strncmp(t->name, temp->name, sizeof(temp->name)))
9099a2dd95SBruce Richardson return -1;
9199a2dd95SBruce Richardson }
9299a2dd95SBruce Richardson
9399a2dd95SBruce Richardson TAILQ_INSERT_TAIL(&rte_tailq_elem_head, t, next);
9499a2dd95SBruce Richardson return 0;
9599a2dd95SBruce Richardson }
9699a2dd95SBruce Richardson
9799a2dd95SBruce Richardson static void
rte_eal_tailq_update(struct rte_tailq_elem * t)9899a2dd95SBruce Richardson rte_eal_tailq_update(struct rte_tailq_elem *t)
9999a2dd95SBruce Richardson {
10099a2dd95SBruce Richardson if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
10199a2dd95SBruce Richardson /* primary process is the only one that creates */
10299a2dd95SBruce Richardson t->head = rte_eal_tailq_create(t->name);
10399a2dd95SBruce Richardson } else {
10499a2dd95SBruce Richardson t->head = rte_eal_tailq_lookup(t->name);
10599a2dd95SBruce Richardson }
10699a2dd95SBruce Richardson }
10799a2dd95SBruce Richardson
10899a2dd95SBruce Richardson int
rte_eal_tailq_register(struct rte_tailq_elem * t)10999a2dd95SBruce Richardson rte_eal_tailq_register(struct rte_tailq_elem *t)
11099a2dd95SBruce Richardson {
11199a2dd95SBruce Richardson if (rte_eal_tailq_local_register(t) < 0) {
112*ae67895bSDavid Marchand EAL_LOG(ERR,
113*ae67895bSDavid Marchand "%s tailq is already registered", t->name);
11499a2dd95SBruce Richardson goto error;
11599a2dd95SBruce Richardson }
11699a2dd95SBruce Richardson
11799a2dd95SBruce Richardson /* if a register happens after rte_eal_tailqs_init(), then we can update
11899a2dd95SBruce Richardson * tailq head */
11999a2dd95SBruce Richardson if (rte_tailqs_count >= 0) {
12099a2dd95SBruce Richardson rte_eal_tailq_update(t);
12199a2dd95SBruce Richardson if (t->head == NULL) {
122*ae67895bSDavid Marchand EAL_LOG(ERR,
123*ae67895bSDavid Marchand "Cannot initialize tailq: %s", t->name);
12499a2dd95SBruce Richardson TAILQ_REMOVE(&rte_tailq_elem_head, t, next);
12599a2dd95SBruce Richardson goto error;
12699a2dd95SBruce Richardson }
12799a2dd95SBruce Richardson }
12899a2dd95SBruce Richardson
12999a2dd95SBruce Richardson return 0;
13099a2dd95SBruce Richardson
13199a2dd95SBruce Richardson error:
13299a2dd95SBruce Richardson t->head = NULL;
13399a2dd95SBruce Richardson return -1;
13499a2dd95SBruce Richardson }
13599a2dd95SBruce Richardson
13699a2dd95SBruce Richardson int
rte_eal_tailqs_init(void)13799a2dd95SBruce Richardson rte_eal_tailqs_init(void)
13899a2dd95SBruce Richardson {
13999a2dd95SBruce Richardson struct rte_tailq_elem *t;
14099a2dd95SBruce Richardson
14199a2dd95SBruce Richardson rte_tailqs_count = 0;
14299a2dd95SBruce Richardson
14399a2dd95SBruce Richardson TAILQ_FOREACH(t, &rte_tailq_elem_head, next) {
14499a2dd95SBruce Richardson /* second part of register job for "early" tailqs, see
14599a2dd95SBruce Richardson * rte_eal_tailq_register and EAL_REGISTER_TAILQ */
14699a2dd95SBruce Richardson rte_eal_tailq_update(t);
14799a2dd95SBruce Richardson if (t->head == NULL) {
148*ae67895bSDavid Marchand EAL_LOG(ERR,
149*ae67895bSDavid Marchand "Cannot initialize tailq: %s", t->name);
15099a2dd95SBruce Richardson /* TAILQ_REMOVE not needed, error is already fatal */
15199a2dd95SBruce Richardson goto fail;
15299a2dd95SBruce Richardson }
15399a2dd95SBruce Richardson }
15499a2dd95SBruce Richardson
15599a2dd95SBruce Richardson return 0;
15699a2dd95SBruce Richardson
15799a2dd95SBruce Richardson fail:
15899a2dd95SBruce Richardson rte_dump_tailq(stderr);
15999a2dd95SBruce Richardson return -1;
16099a2dd95SBruce Richardson }
161