diff options
Diffstat (limited to 'VNFs/DPPD-PROX/run.c')
-rw-r--r-- | VNFs/DPPD-PROX/run.c | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/VNFs/DPPD-PROX/run.c b/VNFs/DPPD-PROX/run.c new file mode 100644 index 00000000..971d7148 --- /dev/null +++ b/VNFs/DPPD-PROX/run.c @@ -0,0 +1,241 @@ +/* +// 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 <inttypes.h> +#include <string.h> + +#include <rte_launch.h> +#include <rte_cycles.h> +#include <rte_atomic.h> + +#include "run.h" +#include "prox_cfg.h" +#include "prox_port_cfg.h" +#include "quit.h" +#include "commands.h" +#include "main.h" +#include "log.h" +#include "display.h" +#include "stats.h" +#include "stats_cons.h" +#include "stats_cons_log.h" +#include "stats_cons_cli.h" + +#include "input.h" +#include "input_curses.h" +#include "input_conn.h" + +static int needs_refresh; +static uint64_t update_interval; +static int stop_prox = 0; /* set to 1 to stop prox */ + +void set_update_interval(uint32_t msec) +{ + update_interval = msec_to_tsc(msec); +} + +void req_refresh(void) +{ + needs_refresh = 1; +} + +void quit(void) +{ + static rte_atomic32_t already_leaving = RTE_ATOMIC32_INIT(0); + if (!rte_atomic32_test_and_set(&already_leaving)) + return; + + plog_info("Leaving...\n"); + if (lcore_cfg == NULL) + exit(EXIT_SUCCESS); + stop_core_all(-1); + stop_prox = 1; +} + +static void update_link_states(void) +{ + struct prox_port_cfg *port_cfg; + struct rte_eth_link link; + + for (uint8_t portid = 0; portid < PROX_MAX_PORTS; ++portid) { + if (!prox_port_cfg[portid].active) { + continue; + } + + port_cfg = &prox_port_cfg[portid]; + rte_eth_link_get_nowait(portid, &link); + port_cfg->link_up = link.link_status; + port_cfg->link_speed = link.link_speed; + } +} + +static struct stats_cons stats_cons[8]; +static size_t n_stats_cons = 0; +static uint16_t stats_cons_flags = 0; + +static void stats_cons_add(struct stats_cons *sc) +{ + if (n_stats_cons == sizeof(stats_cons)/sizeof(stats_cons[0])) + return; + + stats_cons[n_stats_cons++] = *sc; + sc->init(); + stats_cons_flags |= sc->flags; +} + +static void stats_cons_notify(void) +{ + for (size_t i = 0; i < n_stats_cons; ++i) { + stats_cons[i].notify(); + } +} + +static void stats_cons_refresh(void) +{ + for (size_t i = 0; i < n_stats_cons; ++i) { + if (stats_cons[i].refresh) + stats_cons[i].refresh(); + } +} + +static void stats_cons_finish(void) +{ + for (size_t i = 0; i < n_stats_cons; ++i) { + if (stats_cons[i].finish) + stats_cons[i].finish(); + } +} + +static void busy_wait_until(uint64_t deadline) +{ + while (rte_rdtsc() < deadline) + ; +} + +static void multiplexed_input_stats(uint64_t deadline) +{ + input_proc_until(deadline); + + if (needs_refresh) { + needs_refresh = 0; + stats_cons_refresh(); + } + + if (rte_atomic32_read(&lsc)) { + rte_atomic32_dec(&lsc); + update_link_states(); + stats_cons_refresh(); + } +} + +static void print_warnings(void) +{ + if (get_n_warnings() == -1) { + plog_info("Warnings disabled\n"); + } + else if (get_n_warnings() > 0) { + int n_print = get_n_warnings() < 5? get_n_warnings(): 5; + plog_info("Started with %d warnings, last %d warnings: \n", get_n_warnings(), n_print); + for (int i = -n_print + 1; i <= 0; ++i) { + plog_info("%s", get_warning(i)); + } + } + else { + plog_info("Started without warnings\n"); + } +} + +/* start main loop */ +void __attribute__((noreturn)) run(uint32_t flags) +{ + uint64_t cur_tsc; + uint64_t next_update; + uint64_t stop_tsc = 0; + const uint64_t update_interval_threshold = usec_to_tsc(1); + + if (flags & DSF_LISTEN_TCP) + PROX_PANIC(reg_input_tcp(), "Failed to start listening on TCP port 8474: %s\n", strerror(errno)); + if (flags & DSF_LISTEN_UDS) + PROX_PANIC(reg_input_uds(), "Failed to start listening on UDS /tmp/prox.sock: %s\n", strerror(errno)); + + if (prox_cfg.use_stats_logger) + stats_cons_add(stats_cons_log_get()); + + stats_init(prox_cfg.start_time, prox_cfg.duration_time); + stats_update(STATS_CONS_F_ALL); + + switch (prox_cfg.ui) { + case PROX_UI_CURSES: + reg_input_curses(); + stats_cons_add(&display); + break; + case PROX_UI_CLI: + stats_cons_add(stats_cons_cli_get()); + break; + case PROX_UI_NONE: + default: + break; + } + + if (flags & DSF_AUTOSTART) + start_core_all(-1); + else + stop_core_all(-1); + + cur_tsc = rte_rdtsc(); + if (prox_cfg.duration_time != 0) { + stop_tsc = cur_tsc + sec_to_tsc(prox_cfg.start_time + prox_cfg.duration_time); + } + + stats_cons_notify(); + stats_cons_refresh(); + + update_interval = str_to_tsc(prox_cfg.update_interval_str); + next_update = cur_tsc + update_interval; + + cmd_rx_tx_info(); + print_warnings(); + + while (stop_prox == 0) { + + if (update_interval < update_interval_threshold) + busy_wait_until(next_update); + else + multiplexed_input_stats(next_update); + + next_update += update_interval; + + stats_update(stats_cons_flags); + stats_cons_notify(); + + if (stop_tsc && rte_rdtsc() >= stop_tsc) { + stop_prox = 1; + } + } + + stats_cons_finish(); + + if (prox_cfg.flags & DSF_WAIT_ON_QUIT) { + stop_core_all(-1); + } + + if (prox_cfg.logbuf) { + file_print(prox_cfg.logbuf); + } + + display_end(); + exit(EXIT_SUCCESS); +} |