2 // Copyright (c) 2010-2017 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
19 #include <rte_version.h>
21 #include "prox_malloc.h"
22 #include "stats_ring.h"
23 #include "prox_port_cfg.h"
29 struct stats_ring_manager {
31 struct ring_stats ring_stats[0];
34 static struct stats_ring_manager *rsm;
36 int stats_get_n_rings(void)
41 struct ring_stats *stats_get_ring_stats(uint32_t i)
43 return &rsm->ring_stats[i];
46 void stats_ring_update(void)
48 for (uint16_t r_id = 0; r_id < rsm->n_rings; ++r_id) {
49 rsm->ring_stats[r_id].free = rte_ring_free_count(rsm->ring_stats[r_id].ring);
53 static struct ring_stats *init_rings_add(struct stats_ring_manager *rsm, struct rte_ring *ring)
55 for (uint16_t i = 0; i < rsm->n_rings; ++i) {
56 if (strcmp(ring->name, rsm->ring_stats[i].ring->name) == 0)
57 return &rsm->ring_stats[i];
59 rsm->ring_stats[rsm->n_rings++].ring = ring;
60 return &rsm->ring_stats[rsm->n_rings - 1];
63 static struct stats_ring_manager *alloc_stats_ring_manager(void)
65 const uint32_t socket_id = rte_lcore_to_socket_id(rte_lcore_id());
66 struct lcore_cfg *lconf;
67 uint32_t lcore_id = -1;
69 struct task_args *targ;
71 /* n_rings could be more than total number of rings since
72 rings could be referenced by multiple cores. */
73 while(prox_core_next(&lcore_id, 1) == 0) {
74 lconf = &lcore_cfg[lcore_id];
76 for(uint8_t task_id = 0; task_id < lconf->n_tasks_all; ++task_id) {
77 targ = &lconf->targs[task_id];
79 for(uint32_t rxring_id = 0; rxring_id < targ->nb_rxrings; ++rxring_id) {
80 if (!targ->tx_opt_ring_task)
83 for (uint32_t txring_id = 0; txring_id < targ->nb_txrings; ++txring_id) {
84 if (!targ->tx_opt_ring)
90 for (uint8_t port_id = 0; port_id < PROX_MAX_PORTS; ++port_id) {
91 if (!prox_port_cfg[port_id].active) {
95 if (prox_port_cfg[port_id].rx_ring[0] != '\0')
98 if (prox_port_cfg[port_id].tx_ring[0] != '\0')
102 size_t mem_size = sizeof(struct stats_ring_manager) +
103 n_rings * sizeof(struct ring_stats);
105 return prox_zmalloc(mem_size, socket_id);
108 void stats_ring_init(void)
110 uint32_t lcore_id = -1;
111 struct lcore_cfg *lconf;
112 struct task_args *targ;
114 rsm = alloc_stats_ring_manager();
115 while(prox_core_next(&lcore_id, 1) == 0) {
116 lconf = &lcore_cfg[lcore_id];
118 for(uint8_t task_id = 0; task_id < lconf->n_tasks_all; ++task_id) {
119 targ = &lconf->targs[task_id];
121 for(uint32_t rxring_id = 0; rxring_id < targ->nb_rxrings; ++rxring_id) {
122 if (!targ->tx_opt_ring_task)
123 init_rings_add(rsm, targ->rx_rings[rxring_id]);
126 for (uint32_t txring_id = 0; txring_id < targ->nb_txrings; ++txring_id) {
127 if (!targ->tx_opt_ring)
128 init_rings_add(rsm, targ->tx_rings[txring_id]);
133 struct ring_stats *stats = NULL;
135 for (uint8_t port_id = 0; port_id < PROX_MAX_PORTS; ++port_id) {
136 if (!prox_port_cfg[port_id].active) {
140 if (prox_port_cfg[port_id].rx_ring[0] != '\0') {
141 stats = init_rings_add(rsm, rte_ring_lookup(prox_port_cfg[port_id].rx_ring));
142 stats->port[stats->nb_ports++] = &prox_port_cfg[port_id];
145 if (prox_port_cfg[port_id].tx_ring[0] != '\0') {
146 stats = init_rings_add(rsm, rte_ring_lookup(prox_port_cfg[port_id].tx_ring));
147 stats->port[stats->nb_ports++] = &prox_port_cfg[port_id];
151 /* The actual usable space for a ring is size - 1. There is at
152 most one free entry in the ring to distinguish between
154 for (uint16_t ring_id = 0; ring_id < rsm->n_rings; ++ring_id)
155 #if RTE_VERSION < RTE_VERSION_NUM(17,5,0,1)
156 rsm->ring_stats[ring_id].size = rsm->ring_stats[ring_id].ring->prod.size - 1;
158 rsm->ring_stats[ring_id].size = rsm->ring_stats[ring_id].ring->size - 1;