LCOV - code coverage report
Current view: top level - drivers/event/sw - sw_evdev_worker.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 72 73 98.6 %
Date: 2024-01-22 16:26:08 Functions: 6 6 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 32 44 72.7 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2016-2017 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <rte_atomic.h>
       6                 :            : #include <rte_cycles.h>
       7                 :            : #include <rte_event_ring.h>
       8                 :            : 
       9                 :            : #include "sw_evdev.h"
      10                 :            : 
      11                 :            : #define PORT_ENQUEUE_MAX_BURST_SIZE 64
      12                 :            : 
      13                 :            : static inline void
      14                 :       4106 : sw_event_release(struct sw_port *p, uint8_t index)
      15                 :            : {
      16                 :            :         /*
      17                 :            :          * Drops the next outstanding event in our history. Used on dequeue
      18                 :            :          * to clear any history before dequeuing more events.
      19                 :            :          */
      20                 :            :         RTE_SET_USED(index);
      21                 :            : 
      22                 :            :         /* create drop message */
      23                 :            :         struct rte_event ev;
      24                 :       4106 :         ev.op = sw_qe_flag_map[RTE_EVENT_OP_RELEASE];
      25                 :            : 
      26                 :            :         uint16_t free_count;
      27   [ -  +  -  -  :       4106 :         rte_event_ring_enqueue_burst(p->rx_worker_ring, &ev, 1, &free_count);
                      - ]
      28                 :            : 
      29                 :            :         /* each release returns one credit */
      30                 :       4106 :         p->outstanding_releases--;
      31                 :       4106 :         p->inflight_credits++;
      32                 :       4106 : }
      33                 :            : 
      34                 :            : /*
      35                 :            :  * special-case of rte_event_ring enqueue, with overriding the ops member on
      36                 :            :  * the events that get written to the ring.
      37                 :            :  */
      38                 :            : static inline unsigned int
      39                 :       9563 : enqueue_burst_with_ops(struct rte_event_ring *r, const struct rte_event *events,
      40                 :            :                 unsigned int n, uint8_t *ops)
      41                 :            : {
      42                 :            :         struct rte_event tmp_evs[PORT_ENQUEUE_MAX_BURST_SIZE];
      43                 :            :         unsigned int i;
      44                 :            : 
      45                 :       9563 :         memcpy(tmp_evs, events, n * sizeof(events[0]));
      46         [ +  + ]:      19126 :         for (i = 0; i < n; i++)
      47                 :       9563 :                 tmp_evs[i].op = ops[i];
      48                 :            : 
      49                 :       9563 :         return rte_event_ring_enqueue_burst(r, tmp_evs, n, NULL);
      50                 :            : }
      51                 :            : 
      52                 :            : uint16_t
      53                 :       9563 : sw_event_enqueue_burst(void *port, const struct rte_event ev[], uint16_t num)
      54                 :            : {
      55                 :            :         int32_t i;
      56                 :            :         uint8_t new_ops[PORT_ENQUEUE_MAX_BURST_SIZE];
      57                 :            :         struct sw_port *p = port;
      58                 :       9563 :         struct sw_evdev *sw = (void *)p->sw;
      59                 :       9563 :         uint32_t sw_inflights = rte_atomic32_read(&sw->inflights);
      60                 :       9563 :         uint32_t credit_update_quanta = sw->credit_update_quanta;
      61                 :            :         int new = 0;
      62                 :            : 
      63                 :            :         if (num > PORT_ENQUEUE_MAX_BURST_SIZE)
      64                 :            :                 num = PORT_ENQUEUE_MAX_BURST_SIZE;
      65                 :            : 
      66         [ +  + ]:      19126 :         for (i = 0; i < num; i++)
      67                 :       9563 :                 new += (ev[i].op == RTE_EVENT_OP_NEW);
      68                 :            : 
      69   [ +  +  +  - ]:       9563 :         if (unlikely(new > 0 && p->inflight_max < sw_inflights))
      70                 :            :                 return 0;
      71                 :            : 
      72         [ +  + ]:       9563 :         if (p->inflight_credits < new) {
      73                 :            :                 /* check if event enqueue brings port over max threshold */
      74         [ +  - ]:        185 :                 if (sw_inflights + credit_update_quanta > sw->nb_events_limit)
      75                 :            :                         return 0;
      76                 :            : 
      77                 :            :                 rte_atomic32_add(&sw->inflights, credit_update_quanta);
      78                 :        185 :                 p->inflight_credits += (credit_update_quanta);
      79                 :            : 
      80                 :            :                 /* If there are fewer inflight credits than new events, limit
      81                 :            :                  * the number of enqueued events.
      82                 :            :                  */
      83                 :        185 :                 num = (p->inflight_credits < new) ? p->inflight_credits : new;
      84                 :            :         }
      85                 :            : 
      86         [ +  + ]:      19126 :         for (i = 0; i < num; i++) {
      87                 :       9563 :                 int op = ev[i].op;
      88                 :       9563 :                 int outstanding = p->outstanding_releases > 0;
      89                 :       9563 :                 const uint8_t invalid_qid = (ev[i].queue_id >= sw->qid_count);
      90                 :            : 
      91                 :       9563 :                 p->inflight_credits -= (op == RTE_EVENT_OP_NEW);
      92                 :       9563 :                 p->inflight_credits += (op == RTE_EVENT_OP_RELEASE) *
      93                 :            :                                         outstanding;
      94                 :            : 
      95                 :       9563 :                 new_ops[i] = sw_qe_flag_map[op];
      96                 :       9563 :                 new_ops[i] &= ~(invalid_qid << QE_FLAG_VALID_SHIFT);
      97                 :            : 
      98                 :            :                 /* FWD and RELEASE packets will both resolve to taken (assuming
      99                 :            :                  * correct usage of the API), providing very high correct
     100                 :            :                  * prediction rate.
     101                 :            :                  */
     102   [ +  +  +  + ]:       9563 :                 if ((new_ops[i] & QE_FLAG_COMPLETE) && outstanding)
     103                 :       5208 :                         p->outstanding_releases--;
     104                 :            : 
     105                 :            :                 /* error case: branch to avoid touching p->stats */
     106         [ +  + ]:       9563 :                 if (unlikely(invalid_qid && op != RTE_EVENT_OP_RELEASE)) {
     107                 :          1 :                         p->stats.rx_dropped++;
     108                 :          1 :                         p->inflight_credits++;
     109                 :            :                 }
     110                 :            :         }
     111                 :            : 
     112                 :            :         /* returns number of events actually enqueued */
     113                 :       9563 :         uint32_t enq = enqueue_burst_with_ops(p->rx_worker_ring, ev, i,
     114                 :            :                                              new_ops);
     115   [ +  +  +  + ]:       9563 :         if (p->outstanding_releases == 0 && p->last_dequeue_burst_sz != 0) {
     116                 :       5203 :                 uint64_t burst_ticks = rte_get_timer_cycles() -
     117                 :       5203 :                                 p->last_dequeue_ticks;
     118                 :       5203 :                 uint64_t burst_pkt_ticks =
     119                 :       5203 :                         burst_ticks / p->last_dequeue_burst_sz;
     120                 :       5203 :                 p->avg_pkt_ticks -= p->avg_pkt_ticks / NUM_SAMPLES;
     121                 :       5203 :                 p->avg_pkt_ticks += burst_pkt_ticks / NUM_SAMPLES;
     122                 :       5203 :                 p->last_dequeue_ticks = 0;
     123                 :            :         }
     124                 :            : 
     125                 :            :         /* Replenish credits if enough releases are performed */
     126         [ -  + ]:       9563 :         if (p->inflight_credits >= credit_update_quanta * 2) {
     127                 :            :                 rte_atomic32_sub(&sw->inflights, credit_update_quanta);
     128                 :          0 :                 p->inflight_credits -= credit_update_quanta;
     129                 :            :         }
     130                 :            : 
     131                 :       9563 :         return enq;
     132                 :            : }
     133                 :            : 
     134                 :            : uint16_t
     135                 :       9563 : sw_event_enqueue(void *port, const struct rte_event *ev)
     136                 :            : {
     137                 :       9563 :         return sw_event_enqueue_burst(port, ev, 1);
     138                 :            : }
     139                 :            : 
     140                 :            : uint16_t
     141                 :    4207794 : sw_event_dequeue_burst(void *port, struct rte_event *ev, uint16_t num,
     142                 :            :                 uint64_t wait)
     143                 :            : {
     144                 :            :         RTE_SET_USED(wait);
     145                 :            :         struct sw_port *p = (void *)port;
     146                 :    4207794 :         struct rte_event_ring *ring = p->cq_worker_ring;
     147                 :            : 
     148                 :            :         /* check that all previous dequeues have been released */
     149         [ +  - ]:    4207794 :         if (p->implicit_release) {
     150                 :    4207794 :                 struct sw_evdev *sw = (void *)p->sw;
     151                 :    4207794 :                 uint32_t credit_update_quanta = sw->credit_update_quanta;
     152                 :    4207794 :                 uint16_t out_rels = p->outstanding_releases;
     153                 :            :                 uint16_t i;
     154         [ +  + ]:    4211900 :                 for (i = 0; i < out_rels; i++)
     155                 :       4106 :                         sw_event_release(p, i);
     156                 :            : 
     157                 :            :                 /* Replenish credits if enough releases are performed */
     158         [ +  + ]:    4207794 :                 if (p->inflight_credits >= credit_update_quanta * 2) {
     159                 :            :                         rte_atomic32_sub(&sw->inflights, credit_update_quanta);
     160                 :        127 :                         p->inflight_credits -= credit_update_quanta;
     161                 :            :                 }
     162                 :            :         }
     163                 :            : 
     164                 :            :         /* returns number of events actually dequeued */
     165   [ -  +  -  -  :    4207794 :         uint16_t ndeq = rte_event_ring_dequeue_burst(ring, ev, num, NULL);
                      - ]
     166         [ +  + ]:    4207794 :         if (unlikely(ndeq == 0)) {
     167                 :    4198449 :                 p->zero_polls++;
     168                 :    4198449 :                 p->total_polls++;
     169                 :    4198449 :                 goto end;
     170                 :            :         }
     171                 :            : 
     172                 :       9345 :         p->outstanding_releases += ndeq;
     173                 :       9345 :         p->last_dequeue_burst_sz = ndeq;
     174                 :       9345 :         p->last_dequeue_ticks = rte_get_timer_cycles();
     175                 :       9345 :         p->poll_buckets[(ndeq - 1) >> SW_DEQ_STAT_BUCKET_SHIFT]++;
     176                 :       9345 :         p->total_polls++;
     177                 :            : 
     178                 :    4207794 : end:
     179                 :    4207794 :         return ndeq;
     180                 :            : }
     181                 :            : 
     182                 :            : uint16_t
     183                 :       5293 : sw_event_dequeue(void *port, struct rte_event *ev, uint64_t wait)
     184                 :            : {
     185                 :       5293 :         return sw_event_dequeue_burst(port, ev, 1, wait);
     186                 :            : }

Generated by: LCOV version 1.14