Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright(c) 2010-2014 Intel Corporation 3 : : */ 4 : : 5 : : #include <sys/queue.h> 6 : : #include <stdio.h> 7 : : #include <string.h> 8 : : 9 : : #include <rte_eal.h> 10 : : #include <rte_eal_memconfig.h> 11 : : #include <rte_log.h> 12 : : #include <rte_string_fns.h> 13 : : 14 : : #include <eal_export.h> 15 : : #include "eal_private.h" 16 : : #include "eal_memcfg.h" 17 : : 18 : : TAILQ_HEAD(rte_tailq_elem_head, rte_tailq_elem); 19 : : /* local tailq list */ 20 : : static struct rte_tailq_elem_head rte_tailq_elem_head = 21 : : TAILQ_HEAD_INITIALIZER(rte_tailq_elem_head); 22 : : 23 : : /* number of tailqs registered, -1 before call to rte_eal_tailqs_init */ 24 : : static int rte_tailqs_count = -1; 25 : : 26 : : RTE_EXPORT_SYMBOL(rte_eal_tailq_lookup) 27 : : struct rte_tailq_head * 28 : 5224 : rte_eal_tailq_lookup(const char *name) 29 : : { 30 : : unsigned i; 31 : 5224 : struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; 32 : : 33 [ + - ]: 5224 : if (name == NULL) 34 : : return NULL; 35 : : 36 [ + + ]: 159307 : for (i = 0; i < RTE_MAX_TAILQ; i++) { 37 [ + + ]: 154810 : if (!strncmp(name, mcfg->tailq_head[i].name, 38 : : RTE_TAILQ_NAMESIZE-1)) 39 : 727 : return &mcfg->tailq_head[i]; 40 : : } 41 : : 42 : : return NULL; 43 : : } 44 : : 45 : : RTE_EXPORT_SYMBOL(rte_dump_tailq) 46 : : void 47 : 0 : rte_dump_tailq(FILE *f) 48 : : { 49 : : struct rte_mem_config *mcfg; 50 : : unsigned i = 0; 51 : : 52 : 0 : mcfg = rte_eal_get_configuration()->mem_config; 53 : : 54 : 0 : rte_mcfg_tailq_read_lock(); 55 [ # # ]: 0 : for (i = 0; i < RTE_MAX_TAILQ; i++) { 56 : : const struct rte_tailq_head *tailq = &mcfg->tailq_head[i]; 57 : : const struct rte_tailq_entry_head *head = &tailq->tailq_head; 58 : : 59 : : fprintf(f, "Tailq %u: qname:<%s>, tqh_first:%p, tqh_last:%p\n", 60 : 0 : i, tailq->name, head->tqh_first, head->tqh_last); 61 : : } 62 : 0 : rte_mcfg_tailq_read_unlock(); 63 : 0 : } 64 : : 65 : : static struct rte_tailq_head * 66 : 4496 : rte_eal_tailq_create(const char *name) 67 : : { 68 : : struct rte_tailq_head *head = NULL; 69 : : 70 [ + - ]: 4496 : if (!rte_eal_tailq_lookup(name) && 71 [ + - ]: 4496 : (rte_tailqs_count + 1 < RTE_MAX_TAILQ)) { 72 : : struct rte_mem_config *mcfg; 73 : : 74 : 4496 : mcfg = rte_eal_get_configuration()->mem_config; 75 : 4496 : head = &mcfg->tailq_head[rte_tailqs_count]; 76 : 4496 : strlcpy(head->name, name, sizeof(head->name) - 1); 77 : 4496 : TAILQ_INIT(&head->tailq_head); 78 : 4496 : rte_tailqs_count++; 79 : : } 80 : : 81 : 4496 : return head; 82 : : } 83 : : 84 : : /* local register, used to store "early" tailqs before rte_eal_init() and to 85 : : * ensure secondary process only registers tailqs once. */ 86 : : static int 87 : 7310 : rte_eal_tailq_local_register(struct rte_tailq_elem *t) 88 : : { 89 : : struct rte_tailq_elem *temp; 90 : : 91 [ + + ]: 109680 : TAILQ_FOREACH(temp, &rte_tailq_elem_head, next) { 92 [ + + ]: 102371 : if (!strncmp(t->name, temp->name, sizeof(temp->name))) 93 : : return -1; 94 : : } 95 : : 96 : 7309 : TAILQ_INSERT_TAIL(&rte_tailq_elem_head, t, next); 97 : 7309 : return 0; 98 : : } 99 : : 100 : : static void 101 : 5221 : rte_eal_tailq_update(struct rte_tailq_elem *t) 102 : : { 103 [ + + ]: 5221 : if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 104 : : /* primary process is the only one that creates */ 105 : 4496 : t->head = rte_eal_tailq_create(t->name); 106 : : } else { 107 : 725 : t->head = rte_eal_tailq_lookup(t->name); 108 : : } 109 : 5221 : } 110 : : 111 : : RTE_EXPORT_SYMBOL(rte_eal_tailq_register) 112 : : int 113 : 7310 : rte_eal_tailq_register(struct rte_tailq_elem *t) 114 : : { 115 [ + + ]: 7310 : if (rte_eal_tailq_local_register(t) < 0) { 116 : 1 : EAL_LOG(ERR, 117 : : "%s tailq is already registered", t->name); 118 : 1 : goto error; 119 : : } 120 : : 121 : : /* if a register happens after rte_eal_tailqs_init(), then we can update 122 : : * tailq head */ 123 [ + + ]: 7309 : if (rte_tailqs_count >= 0) { 124 : 1 : rte_eal_tailq_update(t); 125 [ - + ]: 1 : if (t->head == NULL) { 126 : 0 : EAL_LOG(ERR, 127 : : "Cannot initialize tailq: %s", t->name); 128 [ # # ]: 0 : TAILQ_REMOVE(&rte_tailq_elem_head, t, next); 129 : 0 : goto error; 130 : : } 131 : : } 132 : : 133 : : return 0; 134 : : 135 : 1 : error: 136 : 1 : t->head = NULL; 137 : 1 : return -1; 138 : : } 139 : : 140 : : int 141 : 180 : rte_eal_tailqs_init(void) 142 : : { 143 : : struct rte_tailq_elem *t; 144 : : 145 : 180 : rte_tailqs_count = 0; 146 : : 147 [ + + ]: 5400 : TAILQ_FOREACH(t, &rte_tailq_elem_head, next) { 148 : : /* second part of register job for "early" tailqs, see 149 : : * rte_eal_tailq_register and EAL_REGISTER_TAILQ */ 150 : 5220 : rte_eal_tailq_update(t); 151 [ - + ]: 5220 : if (t->head == NULL) { 152 : 0 : EAL_LOG(ERR, 153 : : "Cannot initialize tailq: %s", t->name); 154 : : /* TAILQ_REMOVE not needed, error is already fatal */ 155 : 0 : goto fail; 156 : : } 157 : : } 158 : : 159 : : return 0; 160 : : 161 : : fail: 162 : 0 : rte_dump_tailq(stderr); 163 : 0 : return -1; 164 : : }