LCOV - code coverage report
Current view: top level - lib/eal/common - eal_common_tailqs.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 40 54 74.1 %
Date: 2025-03-01 20:23:48 Functions: 6 7 85.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 21 30 70.0 %

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

Generated by: LCOV version 1.14