LCOV - code coverage report
Current view: top level - drivers/event/opdl - opdl_evdev_init.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 283 0.0 %
Date: 2025-02-01 18:54:23 Functions: 0 16 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 198 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2017 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <inttypes.h>
       6                 :            : #include <string.h>
       7                 :            : 
       8                 :            : #include <bus_vdev_driver.h>
       9                 :            : #include <rte_errno.h>
      10                 :            : #include <rte_cycles.h>
      11                 :            : #include <rte_memzone.h>
      12                 :            : 
      13                 :            : #include "opdl_evdev.h"
      14                 :            : #include "opdl_ring.h"
      15                 :            : #include "opdl_log.h"
      16                 :            : 
      17                 :            : 
      18                 :            : static __rte_always_inline uint32_t
      19                 :            : enqueue_check(struct opdl_port *p,
      20                 :            :                 const struct rte_event ev[],
      21                 :            :                 uint16_t num,
      22                 :            :                 uint16_t num_events)
      23                 :            : {
      24                 :            :         uint16_t i;
      25                 :            : 
      26                 :          0 :         if (p->opdl->do_validation) {
      27                 :            : 
      28   [ #  #  #  # ]:          0 :                 for (i = 0; i < num; i++) {
      29   [ #  #  #  # ]:          0 :                         if (ev[i].queue_id != p->next_external_qid) {
      30                 :          0 :                                 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
      31                 :            :                                              "ERROR - port:[%u] - event wants"
      32                 :            :                                              " to enq to q_id[%u],"
      33                 :            :                                              " but should be [%u]",
      34                 :            :                                              opdl_pmd_dev_id(p->opdl),
      35                 :            :                                              p->id,
      36                 :            :                                              ev[i].queue_id,
      37                 :            :                                              p->next_external_qid);
      38                 :          0 :                                 rte_errno = EINVAL;
      39                 :          0 :                                 return 0;
      40                 :            :                         }
      41                 :            :                 }
      42                 :            : 
      43                 :            :                 /* Stats */
      44   [ #  #  #  # ]:          0 :                 if (p->p_type == OPDL_PURE_RX_PORT ||
      45                 :            :                                 p->p_type == OPDL_ASYNC_PORT) {
      46                 :            :                         /* Stats */
      47   [ #  #  #  # ]:          0 :                         if (num_events) {
      48                 :          0 :                                 p->port_stat[claim_pkts_requested] += num;
      49                 :          0 :                                 p->port_stat[claim_pkts_granted] += num_events;
      50                 :          0 :                                 p->port_stat[claim_non_empty]++;
      51                 :          0 :                                 p->start_cycles = rte_rdtsc();
      52                 :            :                         } else {
      53                 :          0 :                                 p->port_stat[claim_empty]++;
      54                 :          0 :                                 p->start_cycles = 0;
      55                 :            :                         }
      56                 :            :                 } else {
      57   [ #  #  #  # ]:          0 :                         if (p->start_cycles) {
      58                 :            :                                 uint64_t end_cycles = rte_rdtsc();
      59                 :          0 :                                 p->port_stat[total_cycles] +=
      60                 :          0 :                                         end_cycles - p->start_cycles;
      61                 :            :                         }
      62                 :            :                 }
      63                 :            :         } else {
      64   [ #  #  #  # ]:          0 :                 if (num > 0 &&
      65   [ #  #  #  # ]:          0 :                                 ev[0].queue_id != p->next_external_qid) {
      66                 :          0 :                         rte_errno = EINVAL;
      67                 :          0 :                         return 0;
      68                 :            :                 }
      69                 :            :         }
      70                 :            : 
      71                 :            :         return num;
      72                 :            : }
      73                 :            : 
      74                 :            : static __rte_always_inline void
      75                 :            : update_on_dequeue(struct opdl_port *p,
      76                 :            :                 struct rte_event ev[],
      77                 :            :                 uint16_t num,
      78                 :            :                 uint16_t num_events)
      79                 :            : {
      80                 :          0 :         if (p->opdl->do_validation) {
      81                 :            :                 int16_t i;
      82   [ #  #  #  #  :          0 :                 for (i = 0; i < num; i++)
                   #  # ]
      83                 :          0 :                         ev[i].queue_id =
      84                 :          0 :                                 p->opdl->queue[p->queue_id].external_qid;
      85                 :            : 
      86                 :            :                 /* Stats */
      87   [ #  #  #  #  :          0 :                 if (num_events) {
                   #  # ]
      88                 :          0 :                         p->port_stat[claim_pkts_requested] += num;
      89                 :          0 :                         p->port_stat[claim_pkts_granted] += num_events;
      90                 :          0 :                         p->port_stat[claim_non_empty]++;
      91                 :          0 :                         p->start_cycles = rte_rdtsc();
      92                 :            :                 } else {
      93                 :          0 :                         p->port_stat[claim_empty]++;
      94                 :          0 :                         p->start_cycles = 0;
      95                 :            :                 }
      96                 :            :         } else {
      97   [ #  #  #  #  :          0 :                 if (num > 0)
                   #  # ]
      98                 :          0 :                         ev[0].queue_id =
      99                 :          0 :                                 p->opdl->queue[p->queue_id].external_qid;
     100                 :            :         }
     101                 :            : }
     102                 :            : 
     103                 :            : 
     104                 :            : /*
     105                 :            :  * Error RX enqueue:
     106                 :            :  *
     107                 :            :  *
     108                 :            :  */
     109                 :            : 
     110                 :            : static uint16_t
     111                 :          0 : opdl_rx_error_enqueue(struct opdl_port *p,
     112                 :            :                 const struct rte_event ev[],
     113                 :            :                 uint16_t num)
     114                 :            : {
     115                 :            :         RTE_SET_USED(p);
     116                 :            :         RTE_SET_USED(ev);
     117                 :            :         RTE_SET_USED(num);
     118                 :            : 
     119                 :          0 :         rte_errno = ENOSPC;
     120                 :            : 
     121                 :          0 :         return 0;
     122                 :            : }
     123                 :            : 
     124                 :            : /*
     125                 :            :  * RX enqueue:
     126                 :            :  *
     127                 :            :  * This function handles enqueue for a single input stage_inst with
     128                 :            :  *      threadsafe disabled or enabled. eg 1 thread using a stage_inst or
     129                 :            :  *      multiple threads sharing a stage_inst
     130                 :            :  */
     131                 :            : 
     132                 :            : static uint16_t
     133                 :          0 : opdl_rx_enqueue(struct opdl_port *p,
     134                 :            :                 const struct rte_event ev[],
     135                 :            :                 uint16_t num)
     136                 :            : {
     137                 :            :         uint16_t enqueued = 0;
     138                 :            : 
     139         [ #  # ]:          0 :         enqueued = opdl_ring_input(opdl_stage_get_opdl_ring(p->enq_stage_inst),
     140                 :            :                                    ev,
     141                 :            :                                    num,
     142                 :            :                                    false);
     143         [ #  # ]:          0 :         if (!enqueue_check(p, ev, num, enqueued))
     144                 :          0 :                 return 0;
     145                 :            : 
     146                 :            : 
     147         [ #  # ]:          0 :         if (enqueued < num)
     148                 :          0 :                 rte_errno = ENOSPC;
     149                 :            : 
     150                 :            :         return enqueued;
     151                 :            : }
     152                 :            : 
     153                 :            : /*
     154                 :            :  * Error TX handler
     155                 :            :  *
     156                 :            :  */
     157                 :            : 
     158                 :            : static uint16_t
     159                 :          0 : opdl_tx_error_dequeue(struct opdl_port *p,
     160                 :            :                 struct rte_event ev[],
     161                 :            :                 uint16_t num)
     162                 :            : {
     163                 :            :         RTE_SET_USED(p);
     164                 :            :         RTE_SET_USED(ev);
     165                 :            :         RTE_SET_USED(num);
     166                 :            : 
     167                 :          0 :         rte_errno = ENOSPC;
     168                 :            : 
     169                 :          0 :         return 0;
     170                 :            : }
     171                 :            : 
     172                 :            : /*
     173                 :            :  * TX single threaded claim
     174                 :            :  *
     175                 :            :  * This function handles dequeue for a single worker stage_inst with
     176                 :            :  *      threadsafe disabled. eg 1 thread using an stage_inst
     177                 :            :  */
     178                 :            : 
     179                 :            : static uint16_t
     180                 :          0 : opdl_tx_dequeue_single_thread(struct opdl_port *p,
     181                 :            :                         struct rte_event ev[],
     182                 :            :                         uint16_t num)
     183                 :            : {
     184                 :            :         uint16_t returned;
     185                 :            : 
     186                 :            :         struct opdl_ring  *ring;
     187                 :            : 
     188                 :          0 :         ring = opdl_stage_get_opdl_ring(p->deq_stage_inst);
     189                 :            : 
     190                 :          0 :         returned = opdl_ring_copy_to_burst(ring,
     191                 :            :                                            p->deq_stage_inst,
     192                 :            :                                            ev,
     193                 :            :                                            num,
     194                 :            :                                            false);
     195                 :            : 
     196         [ #  # ]:          0 :         update_on_dequeue(p, ev, num, returned);
     197                 :            : 
     198                 :          0 :         return returned;
     199                 :            : }
     200                 :            : 
     201                 :            : /*
     202                 :            :  * TX multi threaded claim
     203                 :            :  *
     204                 :            :  * This function handles dequeue for multiple worker stage_inst with
     205                 :            :  *      threadsafe disabled. eg multiple stage_inst each with its own instance
     206                 :            :  */
     207                 :            : 
     208                 :            : static uint16_t
     209                 :          0 : opdl_tx_dequeue_multi_inst(struct opdl_port *p,
     210                 :            :                         struct rte_event ev[],
     211                 :            :                         uint16_t num)
     212                 :            : {
     213                 :            :         uint32_t num_events = 0;
     214                 :            : 
     215                 :          0 :         num_events = opdl_stage_claim(p->deq_stage_inst,
     216                 :            :                                     (void *)ev,
     217                 :            :                                     num,
     218                 :            :                                     NULL,
     219                 :            :                                     false,
     220                 :            :                                     false);
     221                 :            : 
     222         [ #  # ]:          0 :         update_on_dequeue(p, ev, num, num_events);
     223                 :            : 
     224                 :          0 :         return opdl_stage_disclaim(p->deq_stage_inst, num_events, false);
     225                 :            : }
     226                 :            : 
     227                 :            : 
     228                 :            : /*
     229                 :            :  * Worker thread claim
     230                 :            :  *
     231                 :            :  */
     232                 :            : 
     233                 :            : static uint16_t
     234                 :          0 : opdl_claim(struct opdl_port *p, struct rte_event ev[], uint16_t num)
     235                 :            : {
     236                 :            :         uint32_t num_events = 0;
     237                 :            : 
     238         [ #  # ]:          0 :         if (unlikely(num > MAX_OPDL_CONS_Q_DEPTH)) {
     239                 :          0 :                 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
     240                 :            :                              "Attempt to dequeue num of events larger than port (%d) max",
     241                 :            :                              opdl_pmd_dev_id(p->opdl),
     242                 :            :                              p->id);
     243                 :          0 :                 rte_errno = EINVAL;
     244                 :          0 :                 return 0;
     245                 :            :         }
     246                 :            : 
     247                 :            : 
     248                 :          0 :         num_events = opdl_stage_claim(p->deq_stage_inst,
     249                 :            :                         (void *)ev,
     250                 :            :                         num,
     251                 :            :                         NULL,
     252                 :            :                         false,
     253                 :          0 :                         p->atomic_claim);
     254                 :            : 
     255                 :            : 
     256         [ #  # ]:          0 :         update_on_dequeue(p, ev, num, num_events);
     257                 :            : 
     258                 :            :         return num_events;
     259                 :            : }
     260                 :            : 
     261                 :            : /*
     262                 :            :  * Worker thread disclaim
     263                 :            :  */
     264                 :            : 
     265                 :            : static uint16_t
     266                 :          0 : opdl_disclaim(struct opdl_port *p, const struct rte_event ev[], uint16_t num)
     267                 :            : {
     268                 :            :         uint16_t enqueued = 0;
     269                 :            : 
     270                 :            :         uint32_t i = 0;
     271                 :            : 
     272         [ #  # ]:          0 :         for (i = 0; i < num; i++)
     273                 :          0 :                 opdl_ring_cas_slot(p->enq_stage_inst, &ev[i],
     274                 :          0 :                                 i, p->atomic_claim);
     275                 :            : 
     276         [ #  # ]:          0 :         enqueued = opdl_stage_disclaim(p->enq_stage_inst,
     277                 :            :                                        num,
     278                 :            :                                        false);
     279                 :            : 
     280                 :          0 :         return enqueue_check(p, ev, num, enqueued);
     281                 :            : }
     282                 :            : 
     283                 :            : static __rte_always_inline struct opdl_stage *
     284                 :            : stage_for_port(struct opdl_queue *q, unsigned int i)
     285                 :            : {
     286   [ #  #  #  #  :          0 :         if (q->q_pos == OPDL_Q_POS_START || q->q_pos == OPDL_Q_POS_MIDDLE)
             #  #  #  # ]
     287                 :          0 :                 return q->ports[i]->enq_stage_inst;
     288                 :            :         else
     289                 :          0 :                 return q->ports[i]->deq_stage_inst;
     290                 :            : }
     291                 :            : 
     292                 :          0 : static int opdl_add_deps(struct opdl_evdev *device,
     293                 :            :                          int q_id,
     294                 :            :                          int deps_q_id)
     295                 :            : {
     296                 :            :         unsigned int i, j;
     297                 :            :         int status;
     298                 :            :         struct opdl_ring  *ring;
     299                 :            :         struct opdl_queue *queue = &device->queue[q_id];
     300                 :            :         struct opdl_queue *queue_deps = &device->queue[deps_q_id];
     301                 :            :         struct opdl_stage *dep_stages[OPDL_PORTS_MAX];
     302                 :            : 
     303                 :            :         /* sanity check that all stages are for same opdl ring */
     304         [ #  # ]:          0 :         for (i = 0; i < queue->nb_ports; i++) {
     305                 :            :                 struct opdl_ring *r =
     306                 :          0 :                         opdl_stage_get_opdl_ring(stage_for_port(queue, i));
     307         [ #  # ]:          0 :                 for (j = 0; j < queue_deps->nb_ports; j++) {
     308                 :            :                         struct opdl_ring *rj =
     309                 :          0 :                                 opdl_stage_get_opdl_ring(
     310                 :            :                                                 stage_for_port(queue_deps, j));
     311         [ #  # ]:          0 :                         if (r != rj) {
     312                 :          0 :                                 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
     313                 :            :                                              "Stages and dependents"
     314                 :            :                                              " are not for same opdl ring",
     315                 :            :                                              opdl_pmd_dev_id(device));
     316                 :            :                                 uint32_t k;
     317         [ #  # ]:          0 :                                 for (k = 0; k < device->nb_opdls; k++) {
     318                 :          0 :                                         opdl_ring_dump(device->opdl[k],
     319                 :            :                                                         stdout);
     320                 :            :                                 }
     321                 :            :                                 return -EINVAL;
     322                 :            :                         }
     323                 :            :                 }
     324                 :            :         }
     325                 :            : 
     326                 :            :         /* Gather all stages instance in deps */
     327         [ #  # ]:          0 :         for (i = 0; i < queue_deps->nb_ports; i++)
     328                 :          0 :                 dep_stages[i] = stage_for_port(queue_deps, i);
     329                 :            : 
     330                 :            : 
     331                 :            :         /* Add all deps for each port->stage_inst in this queue */
     332         [ #  # ]:          0 :         for (i = 0; i < queue->nb_ports; i++) {
     333                 :            : 
     334                 :          0 :                 ring = opdl_stage_get_opdl_ring(stage_for_port(queue, i));
     335                 :            : 
     336                 :          0 :                 status = opdl_stage_deps_add(ring,
     337                 :            :                                 stage_for_port(queue, i),
     338                 :            :                                 queue->ports[i]->num_instance,
     339         [ #  # ]:          0 :                                 queue->ports[i]->instance_id,
     340                 :            :                                 dep_stages,
     341                 :            :                                 queue_deps->nb_ports);
     342         [ #  # ]:          0 :                 if (status < 0)
     343                 :            :                         return -EINVAL;
     344                 :            :         }
     345                 :            : 
     346                 :            :         return 0;
     347                 :            : }
     348                 :            : 
     349                 :            : int
     350                 :          0 : opdl_add_event_handlers(struct rte_eventdev *dev)
     351                 :            : {
     352                 :            :         int err = 0;
     353                 :            : 
     354                 :            :         struct opdl_evdev *device = opdl_pmd_priv(dev);
     355                 :            :         unsigned int i;
     356                 :            : 
     357         [ #  # ]:          0 :         for (i = 0; i < device->max_port_nb; i++) {
     358                 :            : 
     359                 :            :                 struct opdl_port *port = &device->ports[i];
     360                 :            : 
     361         [ #  # ]:          0 :                 if (port->configured) {
     362         [ #  # ]:          0 :                         if (port->p_type == OPDL_PURE_RX_PORT) {
     363                 :          0 :                                 port->enq = opdl_rx_enqueue;
     364                 :          0 :                                 port->deq = opdl_tx_error_dequeue;
     365                 :            : 
     366         [ #  # ]:          0 :                         } else if (port->p_type == OPDL_PURE_TX_PORT) {
     367                 :            : 
     368                 :          0 :                                 port->enq = opdl_rx_error_enqueue;
     369                 :            : 
     370         [ #  # ]:          0 :                                 if (port->num_instance == 1)
     371                 :          0 :                                         port->deq =
     372                 :            :                                                 opdl_tx_dequeue_single_thread;
     373                 :            :                                 else
     374                 :          0 :                                         port->deq = opdl_tx_dequeue_multi_inst;
     375                 :            : 
     376         [ #  # ]:          0 :                         } else if (port->p_type == OPDL_REGULAR_PORT) {
     377                 :            : 
     378                 :          0 :                                 port->enq = opdl_disclaim;
     379                 :          0 :                                 port->deq = opdl_claim;
     380                 :            : 
     381         [ #  # ]:          0 :                         } else if (port->p_type == OPDL_ASYNC_PORT) {
     382                 :            : 
     383                 :          0 :                                 port->enq = opdl_rx_enqueue;
     384                 :            : 
     385                 :            :                                 /* Always single instance */
     386                 :          0 :                                 port->deq = opdl_tx_dequeue_single_thread;
     387                 :            :                         } else {
     388                 :          0 :                                 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
     389                 :            :                                              "port:[%u] has invalid port type - ",
     390                 :            :                                              opdl_pmd_dev_id(port->opdl),
     391                 :            :                                              port->id);
     392                 :            :                                 err = -EINVAL;
     393                 :            :                                 break;
     394                 :            :                         }
     395                 :          0 :                         port->initialized = 1;
     396                 :            :                 }
     397                 :            :         }
     398                 :            : 
     399                 :            :         if (!err)
     400                 :          0 :                 fprintf(stdout, "Success - enqueue/dequeue handler(s) added\n");
     401                 :          0 :         return err;
     402                 :            : }
     403                 :            : 
     404                 :            : int
     405                 :          0 : build_all_dependencies(struct rte_eventdev *dev)
     406                 :            : {
     407                 :            : 
     408                 :            :         int err = 0;
     409                 :            :         unsigned int i;
     410                 :            :         struct opdl_evdev *device = opdl_pmd_priv(dev);
     411                 :            : 
     412                 :            :         uint8_t start_qid = 0;
     413                 :            : 
     414         [ #  # ]:          0 :         for (i = 0; i < RTE_EVENT_MAX_QUEUES_PER_DEV; i++) {
     415                 :            :                 struct opdl_queue *queue = &device->queue[i];
     416         [ #  # ]:          0 :                 if (!queue->initialized)
     417                 :            :                         break;
     418                 :            : 
     419         [ #  # ]:          0 :                 if (queue->q_pos == OPDL_Q_POS_START) {
     420                 :          0 :                         start_qid = i;
     421                 :          0 :                         continue;
     422                 :            :                 }
     423                 :            : 
     424         [ #  # ]:          0 :                 if (queue->q_pos == OPDL_Q_POS_MIDDLE) {
     425                 :          0 :                         err = opdl_add_deps(device, i, i-1);
     426         [ #  # ]:          0 :                         if (err < 0) {
     427                 :          0 :                                 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
     428                 :            :                                              "dependency addition for queue:[%u] - FAILED",
     429                 :            :                                              dev->data->dev_id,
     430                 :            :                                              queue->external_qid);
     431                 :          0 :                                 break;
     432                 :            :                         }
     433                 :            :                 }
     434                 :            : 
     435         [ #  # ]:          0 :                 if (queue->q_pos == OPDL_Q_POS_END) {
     436                 :            :                         /* Add this dependency */
     437                 :          0 :                         err = opdl_add_deps(device, i, i-1);
     438         [ #  # ]:          0 :                         if (err < 0) {
     439                 :          0 :                                 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
     440                 :            :                                              "dependency addition for queue:[%u] - FAILED",
     441                 :            :                                              dev->data->dev_id,
     442                 :            :                                              queue->external_qid);
     443                 :          0 :                                 break;
     444                 :            :                         }
     445                 :            :                         /* Add dependency for rx on tx */
     446                 :          0 :                         err = opdl_add_deps(device, start_qid, i);
     447         [ #  # ]:          0 :                         if (err < 0) {
     448                 :          0 :                                 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
     449                 :            :                                              "dependency addition for queue:[%u] - FAILED",
     450                 :            :                                              dev->data->dev_id,
     451                 :            :                                              queue->external_qid);
     452                 :          0 :                                 break;
     453                 :            :                         }
     454                 :            :                 }
     455                 :            :         }
     456                 :            : 
     457         [ #  # ]:          0 :         if (!err)
     458                 :          0 :                 fprintf(stdout, "Success - dependencies built\n");
     459                 :            : 
     460                 :          0 :         return err;
     461                 :            : }
     462                 :            : int
     463                 :          0 : check_queues_linked(struct rte_eventdev *dev)
     464                 :            : {
     465                 :            : 
     466                 :            :         int err = 0;
     467                 :            :         unsigned int i;
     468                 :            :         struct opdl_evdev *device = opdl_pmd_priv(dev);
     469                 :            :         uint32_t nb_iq = 0;
     470                 :            : 
     471         [ #  # ]:          0 :         for (i = 0; i < RTE_EVENT_MAX_QUEUES_PER_DEV; i++) {
     472                 :            :                 struct opdl_queue *queue = &device->queue[i];
     473                 :            : 
     474         [ #  # ]:          0 :                 if (!queue->initialized)
     475                 :            :                         break;
     476                 :            : 
     477         [ #  # ]:          0 :                 if (queue->external_qid == OPDL_INVALID_QID)
     478                 :          0 :                         nb_iq++;
     479                 :            : 
     480         [ #  # ]:          0 :                 if (queue->nb_ports == 0) {
     481                 :          0 :                         PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
     482                 :            :                                      "queue:[%u] has no associated ports",
     483                 :            :                                      dev->data->dev_id,
     484                 :            :                                      i);
     485                 :            :                         err = -EINVAL;
     486                 :            :                         break;
     487                 :            :                 }
     488                 :            :         }
     489                 :            :         if (!err) {
     490         [ #  # ]:          0 :                 if ((i - nb_iq) != device->max_queue_nb) {
     491                 :          0 :                         PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
     492                 :            :                                      "%u queues counted but should be %u",
     493                 :            :                                      dev->data->dev_id,
     494                 :            :                                      i - nb_iq,
     495                 :            :                                      device->max_queue_nb);
     496                 :            :                         err = -1;
     497                 :            :                 }
     498                 :            : 
     499                 :            :         }
     500                 :          0 :         return err;
     501                 :            : }
     502                 :            : 
     503                 :            : void
     504                 :          0 : destroy_queues_and_rings(struct rte_eventdev *dev)
     505                 :            : {
     506                 :            :         struct opdl_evdev *device = opdl_pmd_priv(dev);
     507                 :            :         uint32_t i;
     508                 :            : 
     509         [ #  # ]:          0 :         for (i = 0; i < device->nb_opdls; i++) {
     510         [ #  # ]:          0 :                 if (device->opdl[i])
     511                 :          0 :                         opdl_ring_free(device->opdl[i]);
     512                 :            :         }
     513                 :            : 
     514                 :          0 :         memset(&device->queue,
     515                 :            :                         0,
     516                 :            :                         sizeof(struct opdl_queue)
     517                 :            :                         * RTE_EVENT_MAX_QUEUES_PER_DEV);
     518                 :          0 : }
     519                 :            : 
     520                 :            : #define OPDL_ID(d)(d->nb_opdls - 1)
     521                 :            : 
     522                 :            : static __rte_always_inline void
     523                 :            : initialise_queue(struct opdl_evdev *device,
     524                 :            :                 enum queue_pos pos,
     525                 :            :                 int32_t i)
     526                 :            : {
     527                 :          0 :         struct opdl_queue *queue = &device->queue[device->nb_queues];
     528                 :            : 
     529                 :            :         if (i == -1) {
     530                 :          0 :                 queue->q_type = OPDL_Q_TYPE_ORDERED;
     531                 :          0 :                 queue->external_qid = OPDL_INVALID_QID;
     532                 :            :         } else {
     533                 :          0 :                 queue->q_type = device->q_md[i].type;
     534                 :          0 :                 queue->external_qid = device->q_md[i].ext_id;
     535                 :            :                 /* Add ex->in for queues setup */
     536                 :          0 :                 device->q_map_ex_to_in[queue->external_qid] = device->nb_queues;
     537                 :            :         }
     538                 :          0 :         queue->opdl_id = OPDL_ID(device);
     539                 :          0 :         queue->q_pos = pos;
     540                 :          0 :         queue->nb_ports = 0;
     541                 :          0 :         queue->configured = 1;
     542                 :            : 
     543                 :          0 :         device->nb_queues++;
     544                 :          0 : }
     545                 :            : 
     546                 :            : 
     547                 :            : static __rte_always_inline int
     548                 :            : create_opdl(struct opdl_evdev *device)
     549                 :            : {
     550                 :            :         int err = 0;
     551                 :            : 
     552                 :            :         char name[RTE_MEMZONE_NAMESIZE];
     553                 :            : 
     554                 :          0 :         snprintf(name, RTE_MEMZONE_NAMESIZE,
     555                 :          0 :                         "%s_%u", device->service_name, device->nb_opdls);
     556                 :            : 
     557                 :          0 :         device->opdl[device->nb_opdls] =
     558                 :          0 :                 opdl_ring_create(name,
     559                 :            :                                 device->nb_events_limit,
     560                 :            :                                 sizeof(struct rte_event),
     561                 :          0 :                                 device->max_port_nb * 2,
     562                 :            :                                 device->socket);
     563                 :            : 
     564   [ #  #  #  # ]:          0 :         if (!device->opdl[device->nb_opdls]) {
     565                 :          0 :                 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
     566                 :            :                              "opdl ring %u creation - FAILED",
     567                 :            :                              opdl_pmd_dev_id(device),
     568                 :            :                              device->nb_opdls);
     569                 :            :                 err = -EINVAL;
     570                 :            :         } else {
     571                 :          0 :                 device->nb_opdls++;
     572                 :            :         }
     573                 :            :         return err;
     574                 :            : }
     575                 :            : 
     576                 :            : static __rte_always_inline int
     577                 :            : create_link_opdl(struct opdl_evdev *device, uint32_t index)
     578                 :            : {
     579                 :            : 
     580                 :            :         int err = 0;
     581                 :            : 
     582                 :          0 :         if (device->q_md[index + 1].type !=
     583                 :            :                         OPDL_Q_TYPE_SINGLE_LINK) {
     584                 :            : 
     585                 :            :                 /* async queue with regular
     586                 :            :                  * queue following it
     587                 :            :                  */
     588                 :            : 
     589                 :            :                 /* create a new opdl ring */
     590                 :            :                 err = create_opdl(device);
     591                 :            :                 if (!err) {
     592                 :            :                         /* create an initial
     593                 :            :                          * dummy queue for new opdl
     594                 :            :                          */
     595                 :            :                         initialise_queue(device,
     596                 :            :                                         OPDL_Q_POS_START,
     597                 :            :                                         -1);
     598                 :            :                 } else {
     599                 :            :                         err = -EINVAL;
     600                 :            :                 }
     601                 :            :         } else {
     602                 :          0 :                 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
     603                 :            :                              "queue %u, two consecutive"
     604                 :            :                              " SINGLE_LINK queues, not allowed",
     605                 :            :                              opdl_pmd_dev_id(device),
     606                 :            :                              index);
     607                 :            :                 err = -EINVAL;
     608                 :            :         }
     609                 :            : 
     610                 :            :         return err;
     611                 :            : }
     612                 :            : 
     613                 :            : int
     614         [ #  # ]:          0 : create_queues_and_rings(struct rte_eventdev *dev)
     615                 :            : {
     616                 :            :         int err = 0;
     617                 :            : 
     618                 :            :         struct opdl_evdev *device = opdl_pmd_priv(dev);
     619                 :            : 
     620                 :          0 :         device->nb_queues = 0;
     621                 :            : 
     622         [ #  # ]:          0 :         if (device->nb_ports != device->max_port_nb) {
     623                 :          0 :                 PMD_DRV_LOG(ERR, "Number ports setup:%u NOT EQUAL to max port"
     624                 :            :                                 " number:%u for this device",
     625                 :            :                                 device->nb_ports,
     626                 :            :                                 device->max_port_nb);
     627                 :            :                 err = -1;
     628                 :            :         }
     629                 :            : 
     630                 :            :         if (!err) {
     631                 :            :                 /* We will have at least one opdl so create it now */
     632                 :            :                 err = create_opdl(device);
     633                 :            :         }
     634                 :            : 
     635                 :            :         if (!err) {
     636                 :            : 
     637                 :            :                 /* Create 1st "dummy" queue */
     638                 :            :                 initialise_queue(device,
     639                 :            :                                  OPDL_Q_POS_START,
     640                 :            :                                  -1);
     641                 :            : 
     642                 :            :                 uint32_t i;
     643         [ #  # ]:          0 :                 for (i = 0; i < device->nb_q_md; i++) {
     644                 :            : 
     645                 :            :                         /* Check */
     646         [ #  # ]:          0 :                         if (!device->q_md[i].setup) {
     647                 :            : 
     648                 :          0 :                                 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
     649                 :            :                                              "queue meta data slot %u"
     650                 :            :                                              " not setup - FAILING",
     651                 :            :                                              dev->data->dev_id,
     652                 :            :                                              i);
     653                 :            :                                 err = -EINVAL;
     654                 :            :                                 break;
     655         [ #  # ]:          0 :                         } else if (device->q_md[i].type !=
     656                 :            :                                         OPDL_Q_TYPE_SINGLE_LINK) {
     657                 :            : 
     658         [ #  # ]:          0 :                                 if (!device->q_md[i + 1].setup) {
     659                 :            :                                         /* Create a simple ORDERED/ATOMIC
     660                 :            :                                          * queue at the end
     661                 :            :                                          */
     662                 :          0 :                                         initialise_queue(device,
     663                 :            :                                                         OPDL_Q_POS_END,
     664                 :            :                                                         i);
     665                 :            : 
     666                 :            :                                 } else {
     667                 :            :                                         /* Create a simple ORDERED/ATOMIC
     668                 :            :                                          * queue in the middle
     669                 :            :                                          */
     670                 :          0 :                                         initialise_queue(device,
     671                 :            :                                                         OPDL_Q_POS_MIDDLE,
     672                 :            :                                                         i);
     673                 :            :                                 }
     674                 :            :                         } else if (device->q_md[i].type ==
     675                 :            :                                         OPDL_Q_TYPE_SINGLE_LINK) {
     676                 :            : 
     677                 :            :                                 /* create last queue for this opdl */
     678         [ #  # ]:          0 :                                 initialise_queue(device,
     679                 :            :                                                 OPDL_Q_POS_END,
     680                 :            :                                                 i);
     681                 :            : 
     682                 :            :                                 err = create_link_opdl(device, i);
     683                 :            : 
     684                 :            :                                 if (err)
     685                 :            :                                         break;
     686                 :            : 
     687                 :            : 
     688                 :            :                         }
     689                 :            :                 }
     690                 :            :         }
     691         [ #  # ]:          0 :         if (err)
     692                 :          0 :                 destroy_queues_and_rings(dev);
     693                 :            : 
     694                 :          0 :         return err;
     695                 :            : }
     696                 :            : 
     697                 :            : 
     698                 :            : int
     699                 :          0 : initialise_all_other_ports(struct rte_eventdev *dev)
     700                 :            : {
     701                 :            :         int err = 0;
     702                 :            :         struct opdl_stage *stage_inst = NULL;
     703                 :            : 
     704                 :            :         struct opdl_evdev *device = opdl_pmd_priv(dev);
     705                 :            : 
     706                 :            :         uint32_t i;
     707         [ #  # ]:          0 :         for (i = 0; i < device->nb_ports; i++) {
     708                 :          0 :                 struct opdl_port *port = &device->ports[i];
     709                 :          0 :                 struct opdl_queue *queue = &device->queue[port->queue_id];
     710                 :            : 
     711         [ #  # ]:          0 :                 if (port->queue_id == 0) {
     712                 :          0 :                         continue;
     713         [ #  # ]:          0 :                 } else if (queue->q_type != OPDL_Q_TYPE_SINGLE_LINK) {
     714                 :            : 
     715         [ #  # ]:          0 :                         if (queue->q_pos == OPDL_Q_POS_MIDDLE) {
     716                 :            : 
     717                 :            :                                 /* Regular port with claim/disclaim */
     718                 :          0 :                                 stage_inst = opdl_stage_add(
     719                 :          0 :                                         device->opdl[queue->opdl_id],
     720                 :            :                                                 false,
     721                 :            :                                                 false);
     722                 :          0 :                                 port->deq_stage_inst = stage_inst;
     723                 :          0 :                                 port->enq_stage_inst = stage_inst;
     724                 :            : 
     725         [ #  # ]:          0 :                                 if (queue->q_type == OPDL_Q_TYPE_ATOMIC)
     726                 :          0 :                                         port->atomic_claim = true;
     727                 :            :                                 else
     728                 :          0 :                                         port->atomic_claim = false;
     729                 :            : 
     730                 :          0 :                                 port->p_type =  OPDL_REGULAR_PORT;
     731                 :            : 
     732                 :            :                                 /* Add the port to the queue array of ports */
     733                 :          0 :                                 queue->ports[queue->nb_ports] = port;
     734                 :          0 :                                 port->instance_id = queue->nb_ports;
     735                 :          0 :                                 queue->nb_ports++;
     736                 :          0 :                                 opdl_stage_set_queue_id(stage_inst,
     737                 :          0 :                                                 port->queue_id);
     738                 :            : 
     739         [ #  # ]:          0 :                         } else if (queue->q_pos == OPDL_Q_POS_END) {
     740                 :            : 
     741                 :            :                                 /* tx port  */
     742                 :          0 :                                 stage_inst = opdl_stage_add(
     743                 :          0 :                                         device->opdl[queue->opdl_id],
     744                 :            :                                                 false,
     745                 :            :                                                 false);
     746                 :          0 :                                 port->deq_stage_inst = stage_inst;
     747                 :          0 :                                 port->enq_stage_inst = NULL;
     748                 :          0 :                                 port->p_type = OPDL_PURE_TX_PORT;
     749                 :            : 
     750                 :            :                                 /* Add the port to the queue array of ports */
     751                 :          0 :                                 queue->ports[queue->nb_ports] = port;
     752                 :          0 :                                 port->instance_id = queue->nb_ports;
     753                 :          0 :                                 queue->nb_ports++;
     754                 :            :                         } else {
     755                 :            : 
     756                 :          0 :                                 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
     757                 :            :                                              "port %u:, linked incorrectly"
     758                 :            :                                              " to a q_pos START/INVALID %u",
     759                 :            :                                              opdl_pmd_dev_id(port->opdl),
     760                 :            :                                              port->id,
     761                 :            :                                              queue->q_pos);
     762                 :            :                                 err = -EINVAL;
     763                 :            :                                 break;
     764                 :            :                         }
     765                 :            : 
     766                 :            :                 } else if (queue->q_type == OPDL_Q_TYPE_SINGLE_LINK) {
     767                 :            : 
     768                 :          0 :                         port->p_type = OPDL_ASYNC_PORT;
     769                 :            : 
     770                 :            :                         /* -- tx -- */
     771                 :          0 :                         stage_inst = opdl_stage_add(
     772                 :          0 :                                 device->opdl[queue->opdl_id],
     773                 :            :                                         false,
     774                 :            :                                         false); /* First stage */
     775                 :          0 :                         port->deq_stage_inst = stage_inst;
     776                 :            : 
     777                 :            :                         /* Add the port to the queue array of ports */
     778                 :          0 :                         queue->ports[queue->nb_ports] = port;
     779                 :          0 :                         port->instance_id = queue->nb_ports;
     780                 :          0 :                         queue->nb_ports++;
     781                 :            : 
     782         [ #  # ]:          0 :                         if (queue->nb_ports > 1) {
     783                 :          0 :                                 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
     784                 :            :                                              "queue %u:, setup as SINGLE_LINK"
     785                 :            :                                              " but has more than one port linked",
     786                 :            :                                              opdl_pmd_dev_id(port->opdl),
     787                 :            :                                              queue->external_qid);
     788                 :            :                                 err = -EINVAL;
     789                 :            :                                 break;
     790                 :            :                         }
     791                 :            : 
     792                 :            :                         /* -- single instance rx for next opdl -- */
     793                 :          0 :                         uint8_t next_qid =
     794                 :          0 :                                 device->q_map_ex_to_in[queue->external_qid] + 1;
     795         [ #  # ]:          0 :                         if (next_qid < RTE_EVENT_MAX_QUEUES_PER_DEV &&
     796         [ #  # ]:          0 :                                         device->queue[next_qid].configured) {
     797                 :            : 
     798                 :            :                                 /* Remap the queue */
     799                 :            :                                 queue = &device->queue[next_qid];
     800                 :            : 
     801                 :          0 :                                 stage_inst = opdl_stage_add(
     802                 :          0 :                                         device->opdl[queue->opdl_id],
     803                 :            :                                                 false,
     804                 :            :                                                 true);
     805                 :          0 :                                 port->enq_stage_inst = stage_inst;
     806                 :            : 
     807                 :            :                                 /* Add the port to the queue array of ports */
     808                 :          0 :                                 queue->ports[queue->nb_ports] = port;
     809                 :          0 :                                 port->instance_id = queue->nb_ports;
     810                 :          0 :                                 queue->nb_ports++;
     811         [ #  # ]:          0 :                                 if (queue->nb_ports > 1) {
     812                 :          0 :                                         PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
     813                 :            :                                                 "dummy queue %u: for "
     814                 :            :                                                 "port %u, "
     815                 :            :                                                 "SINGLE_LINK but has more "
     816                 :            :                                                 "than one port linked",
     817                 :            :                                                 opdl_pmd_dev_id(port->opdl),
     818                 :            :                                                 next_qid,
     819                 :            :                                                 port->id);
     820                 :            :                                         err = -EINVAL;
     821                 :            :                                         break;
     822                 :            :                                 }
     823                 :            :                                 /* Set this queue to initialized as it is never
     824                 :            :                                  * referenced by any ports
     825                 :            :                                  */
     826                 :          0 :                                 queue->initialized = 1;
     827                 :            :                         }
     828                 :            :                 }
     829                 :            :         }
     830                 :            : 
     831                 :            :         /* Now that all ports are initialised we need to
     832                 :            :          * setup the last bit of stage md
     833                 :            :          */
     834                 :            :         if (!err) {
     835         [ #  # ]:          0 :                 for (i = 0; i < device->nb_ports; i++) {
     836                 :            :                         struct opdl_port *port = &device->ports[i];
     837                 :            :                         struct opdl_queue *queue =
     838                 :          0 :                                 &device->queue[port->queue_id];
     839                 :            : 
     840   [ #  #  #  # ]:          0 :                         if (port->configured &&
     841                 :            :                                         (port->queue_id != OPDL_INVALID_QID)) {
     842         [ #  # ]:          0 :                                 if (queue->nb_ports == 0) {
     843                 :          0 :                                         PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
     844                 :            :                                                 "queue:[%u] has no ports"
     845                 :            :                                                 " linked to it",
     846                 :            :                                                 opdl_pmd_dev_id(port->opdl),
     847                 :            :                                                 port->id);
     848                 :            :                                         err = -EINVAL;
     849                 :          0 :                                         break;
     850                 :            :                                 }
     851                 :            : 
     852                 :          0 :                                 port->num_instance = queue->nb_ports;
     853                 :          0 :                                 port->initialized = 1;
     854                 :          0 :                                 queue->initialized = 1;
     855                 :            :                         } else {
     856                 :          0 :                                 PMD_DRV_LOG(ERR, "DEV_ID:[%02d] : "
     857                 :            :                                              "Port:[%u] not configured  invalid"
     858                 :            :                                              " queue configuration",
     859                 :            :                                              opdl_pmd_dev_id(port->opdl),
     860                 :            :                                              port->id);
     861                 :            :                                 err = -EINVAL;
     862                 :          0 :                                 break;
     863                 :            :                         }
     864                 :            :                 }
     865                 :            :         }
     866                 :          0 :         return err;
     867                 :            : }
     868                 :            : 
     869                 :            : int
     870                 :          0 : initialise_queue_zero_ports(struct rte_eventdev *dev)
     871                 :            : {
     872                 :            :         int err = 0;
     873                 :            :         uint8_t mt_rx = 0;
     874                 :            :         struct opdl_stage *stage_inst = NULL;
     875                 :            :         struct opdl_queue *queue = NULL;
     876                 :            : 
     877                 :            :         struct opdl_evdev *device = opdl_pmd_priv(dev);
     878                 :            : 
     879                 :            :         /* Assign queue zero and figure out how many Q0 ports we have */
     880                 :            :         uint32_t i;
     881         [ #  # ]:          0 :         for (i = 0; i < device->nb_ports; i++) {
     882                 :            :                 struct opdl_port *port = &device->ports[i];
     883         [ #  # ]:          0 :                 if (port->queue_id == OPDL_INVALID_QID) {
     884                 :          0 :                         port->queue_id = 0;
     885                 :          0 :                         port->external_qid = OPDL_INVALID_QID;
     886                 :          0 :                         port->p_type = OPDL_PURE_RX_PORT;
     887                 :          0 :                         mt_rx++;
     888                 :            :                 }
     889                 :            :         }
     890                 :            : 
     891                 :            :         /* Create the stage */
     892                 :          0 :         stage_inst = opdl_stage_add(device->opdl[0],
     893                 :            :                         (mt_rx > 1 ? true : false),
     894                 :            :                         true);
     895         [ #  # ]:          0 :         if (stage_inst) {
     896                 :            : 
     897                 :            :                 /* Assign the new created input stage to all relevant ports */
     898         [ #  # ]:          0 :                 for (i = 0; i < device->nb_ports; i++) {
     899                 :          0 :                         struct opdl_port *port = &device->ports[i];
     900         [ #  # ]:          0 :                         if (port->queue_id == 0) {
     901                 :            :                                 queue = &device->queue[port->queue_id];
     902                 :          0 :                                 port->enq_stage_inst = stage_inst;
     903                 :          0 :                                 port->deq_stage_inst = NULL;
     904                 :          0 :                                 port->configured = 1;
     905                 :          0 :                                 port->initialized = 1;
     906                 :            : 
     907                 :          0 :                                 queue->ports[queue->nb_ports] = port;
     908                 :          0 :                                 port->instance_id = queue->nb_ports;
     909                 :          0 :                                 queue->nb_ports++;
     910                 :            :                         }
     911                 :            :                 }
     912                 :            :         } else {
     913                 :            :                 err = -1;
     914                 :            :         }
     915                 :          0 :         return err;
     916                 :            : }
     917                 :            : 
     918                 :            : int
     919                 :          0 : assign_internal_queue_ids(struct rte_eventdev *dev)
     920                 :            : {
     921                 :            :         int err = 0;
     922                 :            :         struct opdl_evdev *device = opdl_pmd_priv(dev);
     923                 :            :         uint32_t i;
     924                 :            : 
     925         [ #  # ]:          0 :         for (i = 0; i < device->nb_ports; i++) {
     926                 :            :                 struct opdl_port *port = &device->ports[i];
     927         [ #  # ]:          0 :                 if (port->external_qid != OPDL_INVALID_QID) {
     928                 :          0 :                         port->queue_id =
     929                 :          0 :                                 device->q_map_ex_to_in[port->external_qid];
     930                 :            : 
     931                 :            :                         /* Now do the external_qid of the next queue */
     932                 :            :                         struct opdl_queue *queue =
     933                 :          0 :                                 &device->queue[port->queue_id];
     934         [ #  # ]:          0 :                         if (queue->q_pos == OPDL_Q_POS_END)
     935                 :          0 :                                 port->next_external_qid =
     936                 :          0 :                                 device->queue[port->queue_id + 2].external_qid;
     937                 :            :                         else
     938                 :          0 :                                 port->next_external_qid =
     939                 :          0 :                                 device->queue[port->queue_id + 1].external_qid;
     940                 :            :                 }
     941                 :            :         }
     942                 :          0 :         return err;
     943                 :            : }

Generated by: LCOV version 1.14