LCOV - code coverage report
Current view: top level - lib/eal/common - eal_common_tailqs.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 43 62 69.4 %
Date: 2026-04-01 20:02:27 Functions: 6 7 85.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 22 32 68.8 %

           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_errno.h>
      12                 :            : #include <rte_log.h>
      13                 :            : #include <rte_string_fns.h>
      14                 :            : 
      15                 :            : #include <eal_export.h>
      16                 :            : #include "eal_private.h"
      17                 :            : #include "eal_memcfg.h"
      18                 :            : 
      19                 :            : TAILQ_HEAD(rte_tailq_elem_head, rte_tailq_elem);
      20                 :            : /* local tailq list */
      21                 :            : static struct rte_tailq_elem_head rte_tailq_elem_head =
      22                 :            :         TAILQ_HEAD_INITIALIZER(rte_tailq_elem_head);
      23                 :            : 
      24                 :            : /* number of tailqs registered, -1 before call to rte_eal_tailqs_init */
      25                 :            : static int rte_tailqs_count = -1;
      26                 :            : 
      27                 :            : RTE_EXPORT_SYMBOL(rte_eal_tailq_lookup)
      28                 :            : struct rte_tailq_head *
      29                 :       5920 : rte_eal_tailq_lookup(const char *name)
      30                 :            : {
      31                 :            :         unsigned i;
      32                 :       5920 :         struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
      33                 :            : 
      34         [ -  + ]:       5920 :         if (name == NULL) {
      35                 :          0 :                 rte_errno = EINVAL;
      36                 :          0 :                 return NULL;
      37                 :            :         }
      38                 :            : 
      39         [ +  + ]:     182275 :         for (i = 0; i < RTE_MAX_TAILQ; i++) {
      40         [ +  + ]:     177082 :                 if (!strncmp(name, mcfg->tailq_head[i].name,
      41                 :            :                              RTE_TAILQ_NAMESIZE-1))
      42                 :        727 :                         return &mcfg->tailq_head[i];
      43                 :            :         }
      44                 :            : 
      45                 :       5193 :         rte_errno = ENOENT;
      46                 :       5193 :         return NULL;
      47                 :            : }
      48                 :            : 
      49                 :            : RTE_EXPORT_SYMBOL(rte_dump_tailq)
      50                 :            : void
      51                 :          0 : rte_dump_tailq(FILE *f)
      52                 :            : {
      53                 :            :         struct rte_mem_config *mcfg;
      54                 :            :         unsigned i = 0;
      55                 :            : 
      56                 :          0 :         mcfg = rte_eal_get_configuration()->mem_config;
      57                 :            : 
      58                 :          0 :         rte_mcfg_tailq_read_lock();
      59         [ #  # ]:          0 :         for (i = 0; i < RTE_MAX_TAILQ; i++) {
      60                 :            :                 const struct rte_tailq_head *tailq = &mcfg->tailq_head[i];
      61                 :            :                 const struct rte_tailq_entry_head *head = &tailq->tailq_head;
      62                 :            : 
      63                 :            :                 fprintf(f, "Tailq %u: qname:<%s>, tqh_first:%p, tqh_last:%p\n",
      64                 :          0 :                         i, tailq->name, head->tqh_first, head->tqh_last);
      65                 :            :         }
      66                 :          0 :         rte_mcfg_tailq_read_unlock();
      67                 :          0 : }
      68                 :            : 
      69                 :            : static struct rte_tailq_head *
      70                 :       5192 : rte_eal_tailq_create(const char *name)
      71                 :            : {
      72                 :            :         struct rte_tailq_head *head = NULL;
      73                 :            : 
      74         [ -  + ]:       5192 :         if (strlen(name) >= sizeof(head->name)) {
      75                 :          0 :                 EAL_LOG(ERR, "tailq name '%s' is too long", name);
      76                 :          0 :                 rte_errno = ENAMETOOLONG;
      77                 :          0 :                 return NULL;
      78                 :            :         }
      79                 :            : 
      80         [ +  - ]:       5192 :         if (!rte_eal_tailq_lookup(name) &&
      81         [ +  - ]:       5192 :             (rte_tailqs_count + 1 < RTE_MAX_TAILQ)) {
      82                 :            :                 struct rte_mem_config *mcfg;
      83                 :            : 
      84                 :       5192 :                 mcfg = rte_eal_get_configuration()->mem_config;
      85                 :       5192 :                 head = &mcfg->tailq_head[rte_tailqs_count];
      86                 :       5192 :                 strlcpy(head->name, name, sizeof(head->name) - 1);
      87                 :       5192 :                 TAILQ_INIT(&head->tailq_head);
      88                 :       5192 :                 rte_tailqs_count++;
      89                 :            :         }
      90                 :            : 
      91                 :            :         return head;
      92                 :            : }
      93                 :            : 
      94                 :            : /* local register, used to store "early" tailqs before rte_eal_init() and to
      95                 :            :  * ensure secondary process only registers tailqs once. */
      96                 :            : static int
      97                 :       8006 : rte_eal_tailq_local_register(struct rte_tailq_elem *t)
      98                 :            : {
      99                 :            :         struct rte_tailq_elem *temp;
     100                 :            : 
     101         [ +  + ]:     120120 :         TAILQ_FOREACH(temp, &rte_tailq_elem_head, next) {
     102         [ +  + ]:     112115 :                 if (!strncmp(t->name, temp->name, sizeof(temp->name)))
     103                 :            :                         return -1;
     104                 :            :         }
     105                 :            : 
     106                 :       8005 :         TAILQ_INSERT_TAIL(&rte_tailq_elem_head, t, next);
     107                 :       8005 :         return 0;
     108                 :            : }
     109                 :            : 
     110                 :            : static void
     111                 :       5917 : rte_eal_tailq_update(struct rte_tailq_elem *t)
     112                 :            : {
     113         [ +  + ]:       5917 :         if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
     114                 :            :                 /* primary process is the only one that creates */
     115                 :       5192 :                 t->head = rte_eal_tailq_create(t->name);
     116                 :            :         } else {
     117                 :        725 :                 t->head = rte_eal_tailq_lookup(t->name);
     118                 :            :         }
     119                 :       5917 : }
     120                 :            : 
     121                 :            : RTE_EXPORT_SYMBOL(rte_eal_tailq_register)
     122                 :            : int
     123                 :       8006 : rte_eal_tailq_register(struct rte_tailq_elem *t)
     124                 :            : {
     125         [ +  + ]:       8006 :         if (rte_eal_tailq_local_register(t) < 0) {
     126                 :          1 :                 EAL_LOG(ERR,
     127                 :            :                         "%s tailq is already registered", t->name);
     128                 :          1 :                 rte_errno = EEXIST;
     129                 :          1 :                 goto error;
     130                 :            :         }
     131                 :            : 
     132                 :            :         /* if a register happens after rte_eal_tailqs_init(), then we can update
     133                 :            :          * tailq head */
     134         [ +  + ]:       8005 :         if (rte_tailqs_count >= 0) {
     135                 :          1 :                 rte_eal_tailq_update(t);
     136         [ -  + ]:          1 :                 if (t->head == NULL) {
     137                 :          0 :                         EAL_LOG(ERR,
     138                 :            :                                 "Cannot initialize tailq: %s", t->name);
     139         [ #  # ]:          0 :                         TAILQ_REMOVE(&rte_tailq_elem_head, t, next);
     140                 :          0 :                         goto error;
     141                 :            :                 }
     142                 :            :         }
     143                 :            : 
     144                 :            :         return 0;
     145                 :            : 
     146                 :          1 : error:
     147                 :          1 :         t->head = NULL;
     148                 :          1 :         return -1;
     149                 :            : }
     150                 :            : 
     151                 :            : int
     152                 :        204 : rte_eal_tailqs_init(void)
     153                 :            : {
     154                 :            :         struct rte_tailq_elem *t;
     155                 :            : 
     156                 :        204 :         rte_tailqs_count = 0;
     157                 :            : 
     158         [ +  + ]:       6120 :         TAILQ_FOREACH(t, &rte_tailq_elem_head, next) {
     159                 :            :                 /* second part of register job for "early" tailqs, see
     160                 :            :                  * rte_eal_tailq_register and EAL_REGISTER_TAILQ */
     161                 :       5916 :                 rte_eal_tailq_update(t);
     162         [ -  + ]:       5916 :                 if (t->head == NULL) {
     163                 :          0 :                         EAL_LOG(ERR,
     164                 :            :                                 "Cannot initialize tailq: %s", t->name);
     165                 :            :                         /* TAILQ_REMOVE not needed, error is already fatal */
     166                 :          0 :                         goto fail;
     167                 :            :                 }
     168                 :            :         }
     169                 :            : 
     170                 :            :         return 0;
     171                 :            : 
     172                 :            : fail:
     173                 :          0 :         rte_dump_tailq(stderr);
     174                 :          0 :         return -1;
     175                 :            : }

Generated by: LCOV version 1.14