aboutsummaryrefslogtreecommitdiffstats
path: root/lib/librte_power/rte_power_empty_poll.h
blob: c1ad5c24dfba9feebc25d8c1f4b14b9dfa96eebb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/* SPDX-License-Identifier: BSD-3-Clause
 * Copyright(c) 2010-2018 Intel Corporation
 */

#ifndef _RTE_EMPTY_POLL_H
#define _RTE_EMPTY_POLL_H

/**
 * @file
 * RTE Power Management
 */
#include <stdint.h>
#include <stdbool.h>

#include <rte_common.h>
#include <rte_byteorder.h>
#include <rte_log.h>
#include <rte_string_fns.h>
#include <rte_power.h>
#include <rte_timer.h>

#ifdef __cplusplus
extern "C" {
#endif

#define NUM_FREQS  RTE_MAX_LCORE_FREQS

#define BINS_AV 4 /* Has to be ^2 */

#define DROP (NUM_DIRECTIONS * NUM_DEVICES)

#define NUM_PRIORITIES          2

#define NUM_NODES         256  /* Max core number*/

/* Processor Power State */
enum freq_val {
	LOW,
	MED,
	HGH,
	NUM_FREQ = NUM_FREQS
};


/* Queue Polling State */
enum queue_state {
	TRAINING, /* NO TRAFFIC */
	MED_NORMAL,   /* MED */
	HGH_BUSY,     /* HIGH */
	LOW_PURGE,    /* LOW */
};

/* Queue Stats */
struct freq_threshold {

	uint64_t base_edpi;
	bool trained;
	uint32_t threshold_percent;
	uint32_t cur_train_iter;
};

/* Each Worder Thread Empty Poll Stats */
struct priority_worker {

	/* Current dequeue and throughput counts */
	/* These 2 are written to by the worker threads */
	/* So keep them on their own cache line */
	uint64_t empty_dequeues;
	uint64_t num_dequeue_pkts;

	enum queue_state queue_state;

	uint64_t empty_dequeues_prev;
	uint64_t num_dequeue_pkts_prev;

	/* Used for training only */
	struct freq_threshold thresh[NUM_FREQ];
	enum freq_val cur_freq;

	/* bucket arrays to calculate the averages */
	/* edpi mean empty poll counter difference per interval */
	uint64_t edpi_av[BINS_AV];
	/* empty poll counter */
	uint32_t ec;
	/* ppi mean valid poll counter per interval */
	uint64_t ppi_av[BINS_AV];
	/* valid poll counter */
	uint32_t pc;

	uint32_t lcore_id;
	uint32_t iter_counter;
	uint32_t threshold_ctr;
	uint32_t display_ctr;
	uint8_t  dev_id;

} __rte_cache_aligned;


struct stats_data {

	struct priority_worker wrk_stats[NUM_NODES];

	/* flag to stop rx threads processing packets until training over */
	bool start_rx;

};

/* Empty Poll Parameters */
struct ep_params {

	/* Timer related stuff */
	uint64_t interval_ticks;
	uint32_t max_train_iter;

	struct rte_timer timer0;
	struct stats_data wrk_data;
};


/* Sample App Init information */
struct ep_policy {

	uint64_t med_base_edpi;
	uint64_t hgh_base_edpi;

	enum queue_state state;
};



/**
 * Initialize the power management system.
 *
 * @param eptr
 *   the structure of empty poll configuration
 * @param freq_tlb
 *   the power state/frequency mapping table
 * @param policy
 *   the initialization policy from sample app
 *
 * @return
 *  - 0 on success.
 *  - Negative on error.
 */
int __rte_experimental
rte_power_empty_poll_stat_init(struct ep_params **eptr, uint8_t *freq_tlb,
		struct ep_policy *policy);

/**
 * Free the resource hold by power management system.
 */
void __rte_experimental
rte_power_empty_poll_stat_free(void);

/**
 * Update specific core empty poll counter
 * It's not thread safe.
 *
 * @param lcore_id
 *  lcore id
 *
 * @return
 *  - 0 on success.
 *  - Negative on error.
 */
int __rte_experimental
rte_power_empty_poll_stat_update(unsigned int lcore_id);

/**
 * Update specific core valid poll counter, not thread safe.
 *
 * @param lcore_id
 *  lcore id.
 * @param nb_pkt
 *  The packet number of one valid poll.
 *
 * @return
 *  - 0 on success.
 *  - Negative on error.
 */
int __rte_experimental
rte_power_poll_stat_update(unsigned int lcore_id, uint8_t nb_pkt);

/**
 * Fetch specific core empty poll counter.
 *
 * @param lcore_id
 *  lcore id
 *
 * @return
 *  Current lcore empty poll counter value.
 */
uint64_t __rte_experimental
rte_power_empty_poll_stat_fetch(unsigned int lcore_id);

/**
 * Fetch specific core valid poll counter.
 *
 * @param lcore_id
 *  lcore id
 *
 * @return
 *  Current lcore valid poll counter value.
 */
uint64_t __rte_experimental
rte_power_poll_stat_fetch(unsigned int lcore_id);

/**
 * Empty poll  state change detection function
 *
 * @param  tim
 *  The timer structure
 * @param  arg
 *  The customized parameter
 */
void  __rte_experimental
rte_empty_poll_detection(struct rte_timer *tim, void *arg);

#ifdef __cplusplus
}
#endif

#endif