Support packets in flight
[samplevnf.git] / VNFs / DPPD-PROX / stats_task.h
1 /*
2 // Copyright (c) 2010-2017 Intel Corporation
3 //
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
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
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.
15 */
16
17 #ifndef _STATS_TASK_H_
18 #define _STATS_TASK_H_
19
20 #include <rte_common.h>
21 #ifndef __rte_cache_aligned
22 #include <rte_memory.h>
23 #endif
24
25 #include <inttypes.h>
26
27 #include "clock.h"
28
29 /* The struct task_stats is read/write from the task itself and
30    read-only from the core that collects the stats. Since only the
31    task executing the actual work ever modifies the stats, no locking
32    is required. Both a read and a write are atomic (assuming the
33    correct alignment). From this, it followed that the statistics can
34    be incremented directly by the task itself. In cases where these
35    assumptions do not hold, a possible solution (although slightly
36    less accurate) would be to keep accumulate statistics temporarily
37    in a separate structure and periodically copying the statistics to
38    the statistics core through atomic primitives, for example through
39    rte_atomic32_set(). The accuracy would be determined by the
40    frequency at which the statistics are transferred to the statistics
41    core. */
42
43 struct task_rt_stats {
44         uint32_t        rx_pkt_count;
45         uint32_t        tx_pkt_count;
46         uint32_t        drop_tx_fail;
47         uint32_t        drop_discard;
48         uint32_t        drop_handled;
49         uint32_t        idle_cycles;
50         uint64_t        rx_bytes;
51         uint64_t        tx_bytes;
52         uint64_t        drop_bytes;
53         uint64_t        rx_non_dp;
54         uint64_t        tx_non_dp;
55 } __attribute__((packed)) __rte_cache_aligned;
56
57 #ifdef PROX_STATS
58 #define TASK_STATS_ADD_IDLE(stats, cycles) do {                         \
59                 (stats)->idle_cycles += (cycles) + rdtsc_overhead_stats; \
60         } while(0)                                                      \
61
62 #define TASK_STATS_ADD_TX(stats, ntx) do {      \
63                 (stats)->tx_pkt_count += ntx;   \
64         } while(0)                              \
65
66 #define TASK_STATS_ADD_DROP_TX_FAIL(stats, ntx) do {    \
67                 (stats)->drop_tx_fail += ntx;           \
68         } while(0)                                      \
69
70 #define TASK_STATS_ADD_DROP_HANDLED(stats, ntx) do {    \
71                 (stats)->drop_handled += ntx;           \
72         } while(0)                                      \
73
74 #define TASK_STATS_ADD_DROP_DISCARD(stats, ntx) do {    \
75                 (stats)->drop_discard += ntx;           \
76         } while(0)                                      \
77
78 #define TASK_STATS_ADD_RX(stats, ntx) do {      \
79                 (stats)->rx_pkt_count += ntx;   \
80         } while (0)                             \
81
82 #define TASK_STATS_ADD_RX_NON_DP(stats, ntx) do {       \
83                 (stats)->rx_non_dp += ntx;             \
84         } while(0)
85
86 #define TASK_STATS_ADD_TX_NON_DP(stats, ntx) do {       \
87                 (stats)->tx_non_dp += ntx;              \
88          } while(0)
89
90 #define TASK_STATS_ADD_RX_BYTES(stats, bytes) do {      \
91                 (stats)->rx_bytes += bytes;             \
92         } while (0)                                     \
93
94 #define TASK_STATS_ADD_TX_BYTES(stats, bytes) do {      \
95                 (stats)->tx_bytes += bytes;             \
96         } while (0)                                     \
97
98 #define TASK_STATS_ADD_DROP_BYTES(stats, bytes) do {    \
99                 (stats)->drop_bytes += bytes;           \
100         } while (0)                                     \
101
102 #define START_EMPTY_MEASSURE() uint64_t cur_tsc = rte_rdtsc();
103 #else
104 #define TASK_STATS_ADD_IDLE(stats, cycles) do {} while(0)
105 #define TASK_STATS_ADD_TX(stats, ntx)  do {} while(0)
106 #define TASK_STATS_ADD_DROP_TX_FAIL(stats, ntx)  do {} while(0)
107 #define TASK_STATS_ADD_DROP_HANDLED(stats, ntx)  do {} while(0)
108 #define TASK_STATS_ADD_DROP_DISCARD(stats, ntx)  do {} while(0)
109 #define TASK_STATS_ADD_RX(stats, ntx)  do {} while(0)
110 #define TASK_STATS_ADD_RX_BYTES(stats, bytes)  do {} while(0)
111 #define TASK_STATS_ADD_TX_BYTES(stats, bytes)  do {} while(0)
112 #define TASK_STATS_ADD_DROP_BYTES(stats, bytes) do {} while(0)
113 #define START_EMPTY_MEASSURE()  do {} while(0)
114 #endif
115
116 struct task_stats_sample {
117         uint64_t tsc;
118         uint32_t tx_pkt_count;
119         uint32_t drop_tx_fail;
120         uint32_t drop_discard;
121         uint32_t drop_handled;
122         uint32_t rx_pkt_count;
123         uint32_t empty_cycles;
124         uint64_t rx_bytes;
125         uint64_t tx_bytes;
126         uint64_t drop_bytes;
127         uint64_t rx_non_dp;
128         uint64_t tx_non_dp;
129 };
130
131 struct task_stats {
132         uint64_t tot_tx_pkt_count;
133         uint64_t tot_drop_tx_fail;
134         uint64_t tot_drop_discard;
135         uint64_t tot_drop_handled;
136         uint64_t tot_rx_pkt_count;
137         uint64_t tot_tx_non_dp;
138         uint64_t tot_rx_non_dp;
139
140         struct task_stats_sample sample[2];
141
142         struct task_rt_stats *stats;
143         /* flags set if total RX/TX values need to be reported set at
144            initialization time, only need to access stats values in port */
145         uint8_t flags;
146 };
147
148 void stats_task_reset(void);
149 void stats_task_post_proc(void);
150 void stats_task_update(void);
151 void stats_task_init(void);
152
153 int stats_get_n_tasks_tot(void);
154
155 struct task_stats *stats_get_task_stats(uint32_t lcore_id, uint32_t task_id);
156 struct task_stats_sample *stats_get_task_stats_sample(uint32_t lcore_id, uint32_t task_id, int last);
157 void stats_task_get_host_rx_tx_packets(uint64_t *rx, uint64_t *tx, uint64_t *tsc);
158
159 uint64_t stats_core_task_tot_rx(uint8_t lcore_id, uint8_t task_id);
160 uint64_t stats_core_task_tot_tx(uint8_t lcore_id, uint8_t task_id);
161 uint64_t stats_core_task_tot_tx_fail(uint8_t lcore_id, uint8_t task_id);
162 uint64_t stats_core_task_tot_drop(uint8_t lcore_id, uint8_t task_id);
163 uint64_t stats_core_task_last_tsc(uint8_t lcore_id, uint8_t task_id);
164 uint64_t stats_core_task_tot_rx_non_dp(uint8_t lcore_id, uint8_t task_id);
165 uint64_t stats_core_task_tot_tx_non_dp(uint8_t lcore_id, uint8_t task_id);
166
167 #endif /* _STATS_TASK_H_ */