From 7286b2518ec8e4398b512ce95def9166a7af2e4a Mon Sep 17 00:00:00 2001 From: Deepak S Date: Thu, 13 Jul 2017 21:26:50 -0700 Subject: Adding PROX(Packet pROcessing eXecution engine) VNF to sampleVNF JIRA: SAMPLEVNF-55 PROX is a DPDK-based application implementing Telco use-cases such as a simplified BRAS/BNG, light-weight AFTR... It also allows configuring finer grained network functions like QoS, Routing, load-balancing... (We are moving PROX version v039 to sampleVNF https://01.org/intel-data-plane-performance-demonstrators/prox-overview) Change-Id: Ia3cb02cf0e49ac5596e922c197ff7e010293d033 Signed-off-by: Deepak S --- VNFs/DPPD-PROX/stats_ring.c | 160 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 VNFs/DPPD-PROX/stats_ring.c (limited to 'VNFs/DPPD-PROX/stats_ring.c') diff --git a/VNFs/DPPD-PROX/stats_ring.c b/VNFs/DPPD-PROX/stats_ring.c new file mode 100644 index 00000000..d0792ac1 --- /dev/null +++ b/VNFs/DPPD-PROX/stats_ring.c @@ -0,0 +1,160 @@ +/* +// Copyright (c) 2010-2017 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +*/ + +#include +#include +#include + +#include "prox_malloc.h" +#include "stats_ring.h" +#include "prox_port_cfg.h" +#include "prox_cfg.h" +#include "lconf.h" +#include "log.h" +#include "quit.h" + +struct stats_ring_manager { + uint16_t n_rings; + struct ring_stats ring_stats[0]; +}; + +static struct stats_ring_manager *rsm; + +int stats_get_n_rings(void) +{ + return rsm->n_rings; +} + +struct ring_stats *stats_get_ring_stats(uint32_t i) +{ + return &rsm->ring_stats[i]; +} + +void stats_ring_update(void) +{ + for (uint16_t r_id = 0; r_id < rsm->n_rings; ++r_id) { + rsm->ring_stats[r_id].free = rte_ring_free_count(rsm->ring_stats[r_id].ring); + } +} + +static struct ring_stats *init_rings_add(struct stats_ring_manager *rsm, struct rte_ring *ring) +{ + for (uint16_t i = 0; i < rsm->n_rings; ++i) { + if (strcmp(ring->name, rsm->ring_stats[i].ring->name) == 0) + return &rsm->ring_stats[i]; + } + rsm->ring_stats[rsm->n_rings++].ring = ring; + return &rsm->ring_stats[rsm->n_rings - 1]; +} + +static struct stats_ring_manager *alloc_stats_ring_manager(void) +{ + const uint32_t socket_id = rte_lcore_to_socket_id(rte_lcore_id()); + struct lcore_cfg *lconf; + uint32_t lcore_id = -1; + uint32_t n_rings = 0; + struct task_args *targ; + + /* n_rings could be more than total number of rings since + rings could be referenced by multiple cores. */ + while(prox_core_next(&lcore_id, 1) == 0) { + lconf = &lcore_cfg[lcore_id]; + + for(uint8_t task_id = 0; task_id < lconf->n_tasks_all; ++task_id) { + targ = &lconf->targs[task_id]; + + for(uint32_t rxring_id = 0; rxring_id < targ->nb_rxrings; ++rxring_id) { + if (!targ->tx_opt_ring_task) + n_rings++; + } + for (uint32_t txring_id = 0; txring_id < targ->nb_txrings; ++txring_id) { + if (!targ->tx_opt_ring) + n_rings++; + } + } + } + + for (uint8_t port_id = 0; port_id < PROX_MAX_PORTS; ++port_id) { + if (!prox_port_cfg[port_id].active) { + continue; + } + + if (prox_port_cfg[port_id].rx_ring[0] != '\0') + n_rings++; + + if (prox_port_cfg[port_id].tx_ring[0] != '\0') + n_rings++; + } + + size_t mem_size = sizeof(struct stats_ring_manager) + + n_rings * sizeof(struct ring_stats); + + return prox_zmalloc(mem_size, socket_id); +} + +void stats_ring_init(void) +{ + uint32_t lcore_id = -1; + struct lcore_cfg *lconf; + struct task_args *targ; + + rsm = alloc_stats_ring_manager(); + while(prox_core_next(&lcore_id, 1) == 0) { + lconf = &lcore_cfg[lcore_id]; + + for(uint8_t task_id = 0; task_id < lconf->n_tasks_all; ++task_id) { + targ = &lconf->targs[task_id]; + + for(uint32_t rxring_id = 0; rxring_id < targ->nb_rxrings; ++rxring_id) { + if (!targ->tx_opt_ring_task) + init_rings_add(rsm, targ->rx_rings[rxring_id]); + } + + for (uint32_t txring_id = 0; txring_id < targ->nb_txrings; ++txring_id) { + if (!targ->tx_opt_ring) + init_rings_add(rsm, targ->tx_rings[txring_id]); + } + } + } + + struct ring_stats *stats = NULL; + + for (uint8_t port_id = 0; port_id < PROX_MAX_PORTS; ++port_id) { + if (!prox_port_cfg[port_id].active) { + continue; + } + + if (prox_port_cfg[port_id].rx_ring[0] != '\0') { + stats = init_rings_add(rsm, rte_ring_lookup(prox_port_cfg[port_id].rx_ring)); + stats->port[stats->nb_ports++] = &prox_port_cfg[port_id]; + } + + if (prox_port_cfg[port_id].tx_ring[0] != '\0') { + stats = init_rings_add(rsm, rte_ring_lookup(prox_port_cfg[port_id].tx_ring)); + stats->port[stats->nb_ports++] = &prox_port_cfg[port_id]; + } + } + + /* The actual usable space for a ring is size - 1. There is at + most one free entry in the ring to distinguish between + full/empty. */ + for (uint16_t ring_id = 0; ring_id < rsm->n_rings; ++ring_id) +#if RTE_VERSION < RTE_VERSION_NUM(17,5,0,1) + rsm->ring_stats[ring_id].size = rsm->ring_stats[ring_id].ring->prod.size - 1; +#else + rsm->ring_stats[ring_id].size = rsm->ring_stats[ring_id].ring->size - 1; +#endif +} -- cgit 1.2.3-korg