33 #include <rte_config.h> 35 #include <rte_lcore.h> 36 #include <rte_launch.h> 37 #include <rte_cycles.h> 38 #include <rte_malloc.h> 40 #include <tas_memif.h> 41 #include <utils_timeout.h> 45 #include "fast/internal.h" 54 volatile unsigned fp_cores_cur = 1;
55 volatile unsigned fp_scale_to = 0;
57 static unsigned threads_launched = 0;
63 static int start_threads(
void);
64 static void thread_error(
void);
65 static int common_thread(
void *arg);
68 static void *slowpath_thread(
void)
74 int main(
int argc,
char *argv[])
76 int res = EXIT_SUCCESS;
79 if (config_parse(&config, argc, argv) != 0) {
86 if (shm_preinit() != 0) {
92 rte_log_set_global_level(RTE_LOG_ERR);
94 fprintf(stderr,
"dpdk init failed\n");
98 if ((core_loads = calloc(fp_cores_max,
sizeof(*core_loads))) == NULL) {
100 fprintf(stderr,
"core loads alloc failed\n");
104 if (shm_init(fp_cores_max) != 0) {
106 fprintf(stderr,
"dma init failed\n");
110 if (network_init(fp_cores_max) != 0) {
112 fprintf(stderr,
"network init failed\n");
113 goto error_shm_cleanup;
116 if (dataplane_init() != 0) {
118 fprintf(stderr,
"dpinit failed\n");
119 goto error_network_cleanup;
124 if (start_threads() != 0) {
126 goto error_dataplane_cleanup;
132 error_dataplane_cleanup:
134 error_network_cleanup:
142 static int common_thread(
void *arg)
144 uint16_t
id = (uintptr_t) arg;
149 snprintf(name,
sizeof(name),
"stcp-fp-%u",
id);
150 pthread_setname_np(pthread_self(), name);
154 if ((ctx = rte_zmalloc(
"fastpath core context",
sizeof(*ctx), 0)) == NULL) {
155 fprintf(stderr,
"Allocating fastpath core context failed\n");
163 #ifdef FLEXNIC_TRACING 164 if (trace_thread_init(
id) != 0) {
165 fprintf(stderr,
"initializing trace failed\n");
171 if (dataplane_context_init(ctx) != 0) {
172 fprintf(stderr,
"initializing data plane context\n");
179 dataplane_context_destroy(ctx);
183 #ifdef FLEXNIC_TRACING 186 dataplane_context_destroy(ctx);
192 static int start_threads(
void)
194 unsigned cores_avail, cores_needed, core;
197 cores_avail = rte_lcore_count();
199 cores_needed = fp_cores_max + 1;
201 if ((ctxs = rte_calloc(
"context list", fp_cores_max,
sizeof(*ctxs), 64)) == NULL) {
202 perror(
"datplane_init: calloc failed");
207 if (cores_avail < cores_needed) {
208 fprintf(stderr,
"Not enough cores: got %u need %u\n", cores_avail,
214 RTE_LCORE_FOREACH_SLAVE(core) {
215 if (threads_launched < fp_cores_max) {
216 arg = (
void *) (uintptr_t) threads_launched;
217 if (rte_eal_remote_launch(common_thread, arg, core) != 0) {
218 fprintf(stderr,
"ERROR\n");
228 static void thread_error(
void)
230 fprintf(stderr,
"thread_error\n");
234 int flexnic_scale_to(uint32_t cores)
236 if (fp_scale_to != 0) {
237 fprintf(stderr,
"flexnic_scale_to: already scaling\n");
243 notify_fastpath_core(0);
247 void flexnic_loadmon(uint32_t ts)
249 uint64_t cyc_busy = 0, x, tsc, cycles, id_cyc;
250 unsigned i, num_cores;
251 static uint64_t ewma_busy = 0, ewma_cycles = 0, last_tsc = 0, kdrops = 0;
252 static int waiting = 1, waiting_n = 0, count = 0;
254 num_cores = fp_cores_cur;
257 for (i = 0; i < num_cores; i++) {
261 x = ctxs[i]->loadmon_cyc_busy;
262 cyc_busy += x - core_loads[i].cyc_busy;
263 core_loads[i].cyc_busy = x;
265 kdrops += ctxs[i]->kernel_drop;
266 ctxs[i]->kernel_drop = 0;
270 tsc = rte_get_tsc_cycles();
275 cycles = tsc - last_tsc;
279 ewma_busy = (7 * ewma_busy + cyc_busy) / 8;
280 ewma_cycles = (7 * ewma_cycles + cycles) / 8;
283 if (count++ % 100 == 0) {
285 fprintf(stderr,
"flexnic_loadmon: status cores = %u busy = %lu " 286 "cycles =%lu kdrops=%lu\n", num_cores, ewma_busy, ewma_cycles,
292 if (waiting && ++waiting_n < 10)
296 if (num_cores * ewma_cycles > ewma_busy) {
297 id_cyc = num_cores * ewma_cycles - ewma_busy;
303 if (num_cores > 1 && id_cyc > ewma_cycles * 5 / 4) {
305 fprintf(stderr,
"flexnic_loadmon: down cores = %u idle_cyc = %lu " 306 "1.2 cores = %lu\n", num_cores, id_cyc, ewma_cycles * 5 / 4);
307 flexnic_scale_to(num_cores - 1);
314 if (num_cores < fp_cores_max && id_cyc < ewma_cycles / 5) {
316 fprintf(stderr,
"flexnic_loadmon: up cores = %u idle_cyc = %lu " 317 "0.2 cores = %lu\n", num_cores, id_cyc, ewma_cycles / 5);
318 flexnic_scale_to(num_cores + 1);