1*a2bc0584SZhirun Yan /* SPDX-License-Identifier: BSD-3-Clause 2*a2bc0584SZhirun Yan * Copyright(C) 2020 Marvell International Ltd. 3*a2bc0584SZhirun Yan * Copyright(C) 2023 Intel Corporation 4*a2bc0584SZhirun Yan */ 5*a2bc0584SZhirun Yan 6*a2bc0584SZhirun Yan #include "rte_graph_worker_common.h" 7*a2bc0584SZhirun Yan 8*a2bc0584SZhirun Yan /** 9*a2bc0584SZhirun Yan * Perform graph walk on the circular buffer and invoke the process function 10*a2bc0584SZhirun Yan * of the nodes and collect the stats. 11*a2bc0584SZhirun Yan * 12*a2bc0584SZhirun Yan * @param graph 13*a2bc0584SZhirun Yan * Graph pointer returned from rte_graph_lookup function. 14*a2bc0584SZhirun Yan * 15*a2bc0584SZhirun Yan * @see rte_graph_lookup() 16*a2bc0584SZhirun Yan */ 17*a2bc0584SZhirun Yan static inline void 18*a2bc0584SZhirun Yan rte_graph_walk_rtc(struct rte_graph *graph) 19*a2bc0584SZhirun Yan { 20*a2bc0584SZhirun Yan const rte_graph_off_t *cir_start = graph->cir_start; 21*a2bc0584SZhirun Yan const rte_node_t mask = graph->cir_mask; 22*a2bc0584SZhirun Yan uint32_t head = graph->head; 23*a2bc0584SZhirun Yan struct rte_node *node; 24*a2bc0584SZhirun Yan uint64_t start; 25*a2bc0584SZhirun Yan uint16_t rc; 26*a2bc0584SZhirun Yan void **objs; 27*a2bc0584SZhirun Yan 28*a2bc0584SZhirun Yan /* 29*a2bc0584SZhirun Yan * Walk on the source node(s) ((cir_start - head) -> cir_start) and then 30*a2bc0584SZhirun Yan * on the pending streams (cir_start -> (cir_start + mask) -> cir_start) 31*a2bc0584SZhirun Yan * in a circular buffer fashion. 32*a2bc0584SZhirun Yan * 33*a2bc0584SZhirun Yan * +-----+ <= cir_start - head [number of source nodes] 34*a2bc0584SZhirun Yan * | | 35*a2bc0584SZhirun Yan * | ... | <= source nodes 36*a2bc0584SZhirun Yan * | | 37*a2bc0584SZhirun Yan * +-----+ <= cir_start [head = 0] [tail = 0] 38*a2bc0584SZhirun Yan * | | 39*a2bc0584SZhirun Yan * | ... | <= pending streams 40*a2bc0584SZhirun Yan * | | 41*a2bc0584SZhirun Yan * +-----+ <= cir_start + mask 42*a2bc0584SZhirun Yan */ 43*a2bc0584SZhirun Yan while (likely(head != graph->tail)) { 44*a2bc0584SZhirun Yan node = (struct rte_node *)RTE_PTR_ADD(graph, cir_start[(int32_t)head++]); 45*a2bc0584SZhirun Yan RTE_ASSERT(node->fence == RTE_GRAPH_FENCE); 46*a2bc0584SZhirun Yan objs = node->objs; 47*a2bc0584SZhirun Yan rte_prefetch0(objs); 48*a2bc0584SZhirun Yan 49*a2bc0584SZhirun Yan if (rte_graph_has_stats_feature()) { 50*a2bc0584SZhirun Yan start = rte_rdtsc(); 51*a2bc0584SZhirun Yan rc = node->process(graph, node, objs, node->idx); 52*a2bc0584SZhirun Yan node->total_cycles += rte_rdtsc() - start; 53*a2bc0584SZhirun Yan node->total_calls++; 54*a2bc0584SZhirun Yan node->total_objs += rc; 55*a2bc0584SZhirun Yan } else { 56*a2bc0584SZhirun Yan node->process(graph, node, objs, node->idx); 57*a2bc0584SZhirun Yan } 58*a2bc0584SZhirun Yan node->idx = 0; 59*a2bc0584SZhirun Yan head = likely((int32_t)head > 0) ? head & mask : head; 60*a2bc0584SZhirun Yan } 61*a2bc0584SZhirun Yan graph->tail = 0; 62*a2bc0584SZhirun Yan } 63