diff options
Diffstat (limited to 'VNFs/DPPD-PROX/lconf.c')
-rw-r--r-- | VNFs/DPPD-PROX/lconf.c | 355 |
1 files changed, 355 insertions, 0 deletions
diff --git a/VNFs/DPPD-PROX/lconf.c b/VNFs/DPPD-PROX/lconf.c new file mode 100644 index 00000000..88d8f4f9 --- /dev/null +++ b/VNFs/DPPD-PROX/lconf.c @@ -0,0 +1,355 @@ +/* +// 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 "prox_malloc.h" +#include "lconf.h" +#include "rx_pkt.h" +#include "tx_pkt.h" +#include "log.h" +#include "quit.h" +#include "prox_cfg.h" + +struct lcore_cfg *lcore_cfg; +/* only used at initialization time */ +struct lcore_cfg lcore_cfg_init[RTE_MAX_LCORE]; + +static int core_targ_next_from(struct lcore_cfg **lconf, struct task_args **targ, struct lcore_cfg *lcore_cfg, const int with_master) +{ + uint32_t lcore_id, task_id; + + if (*lconf && *targ) { + lcore_id = *lconf - lcore_cfg; + task_id = *targ - lcore_cfg[lcore_id].targs; + + if (task_id + 1 < lcore_cfg[lcore_id].n_tasks_all) { + *targ = &lcore_cfg[lcore_id].targs[task_id + 1]; + return 0; + } else { + if (prox_core_next(&lcore_id, with_master)) + return -1; + *lconf = &lcore_cfg[lcore_id]; + *targ = &lcore_cfg[lcore_id].targs[0]; + return 0; + } + } else { + lcore_id = -1; + + if (prox_core_next(&lcore_id, with_master)) + return -1; + *lconf = &lcore_cfg[lcore_id]; + *targ = &lcore_cfg[lcore_id].targs[0]; + return 0; + } +} + +int core_targ_next(struct lcore_cfg **lconf, struct task_args **targ, const int with_master) +{ + return core_targ_next_from(lconf, targ, lcore_cfg, with_master); +} + +int core_targ_next_early(struct lcore_cfg **lconf, struct task_args **targ, const int with_master) +{ + return core_targ_next_from(lconf, targ, lcore_cfg_init, with_master); +} + +struct task_args *core_targ_get(uint32_t lcore_id, uint32_t task_id) +{ + return &lcore_cfg[lcore_id].targs[task_id]; +} + +void lcore_cfg_alloc_hp(void) +{ + size_t mem_size = RTE_MAX_LCORE * sizeof(struct lcore_cfg); + + lcore_cfg = prox_zmalloc(mem_size, rte_socket_id()); + PROX_PANIC(lcore_cfg == NULL, "Could not allocate memory for core control structures\n"); + rte_memcpy(lcore_cfg, lcore_cfg_init, mem_size); + + /* get thread ID for master core */ + lcore_cfg[rte_lcore_id()].thread_id = pthread_self(); +} + +int lconf_run(__attribute__((unused)) void *dummy) +{ + uint32_t lcore_id = rte_lcore_id(); + struct lcore_cfg *lconf = &lcore_cfg[lcore_id]; + + /* get thread ID, and set cancellation type to asynchronous */ + lconf->thread_id = pthread_self(); + int ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + if (ret != 0) + plog_warn("pthread_setcanceltype() failed on core %u: %i\n", lcore_id, ret); + + plog_info("Entering main loop on core %u\n", lcore_id); + return lconf->thread_x(lconf); +} + +static void msg_stop(struct lcore_cfg *lconf) +{ + int idx = -1; + struct task_base *t = NULL; + + if (lconf->msg.task_id == -1) { + for (int i = 0; i < lconf->n_tasks_all; ++i) { + if (lconf->task_is_running[i]) { + lconf->task_is_running[i] = 0; + t = lconf->tasks_all[i]; + if (t->aux->stop) + t->aux->stop(t); + } + } + lconf->n_tasks_run = 0; + + if (t && t->aux->stop_last) + t->aux->stop_last(t); + } + else { + for (int i = 0; i < lconf->n_tasks_run; ++i) { + if (lconf_get_task_id(lconf, lconf->tasks_run[i]) == lconf->msg.task_id) { + idx = i; + } + else if (idx != -1) { + lconf->tasks_run[idx] = lconf->tasks_run[i]; + + idx++; + } + } + lconf->task_is_running[lconf->msg.task_id] = 0; + + t = lconf->tasks_all[lconf->msg.task_id]; + if (t->aux->stop) + t->aux->stop(t); + lconf->n_tasks_run--; + if (lconf->n_tasks_run == 0 && t->aux->stop_last) + t->aux->stop_last(t); + } +} + +static void msg_start(struct lcore_cfg *lconf) +{ + int idx = 1; + struct task_base *t = NULL; + + if (lconf->msg.task_id == -1) { + for (int i = 0; i < lconf->n_tasks_all; ++i) { + t = lconf->tasks_run[i] = lconf->tasks_all[i]; + lconf->task_is_running[i] = 1; + if (lconf->n_tasks_run == 0 && t->aux->start_first) { + t->aux->start_first(t); + lconf->n_tasks_run = 1; + } + if (t->aux->start) + t->aux->start(t); + } + lconf->n_tasks_run = lconf->n_tasks_all; + } + else if (lconf->n_tasks_run == 0) { + t = lconf->tasks_run[0] = lconf->tasks_all[lconf->msg.task_id]; + lconf->n_tasks_run = 1; + lconf->task_is_running[lconf->msg.task_id] = 1; + + if (t->aux->start_first) + t->aux->start_first(t); + if (t->aux->start) + t->aux->start(t); + } + else { + for (int i = lconf->n_tasks_run - 1; i >= 0; --i) { + idx = lconf_get_task_id(lconf, lconf->tasks_run[i]); + if (idx == lconf->msg.task_id) { + break; + } + else if (idx > lconf->msg.task_id) { + lconf->tasks_run[i + 1] = lconf->tasks_run[i]; + if (i == 0) { + lconf->tasks_run[i] = lconf->tasks_all[lconf->msg.task_id]; + lconf->n_tasks_run++; + break; + } + } + else { + lconf->tasks_run[i + 1] = lconf->tasks_all[lconf->msg.task_id]; + lconf->n_tasks_run++; + break; + } + } + lconf->task_is_running[lconf->msg.task_id] = 1; + + if (lconf->tasks_all[lconf->msg.task_id]->aux->start) + lconf->tasks_all[lconf->msg.task_id]->aux->start(lconf->tasks_all[lconf->msg.task_id]); + } +} + +int lconf_do_flags(struct lcore_cfg *lconf) +{ + struct task_base *t; + int ret = 0; + + switch (lconf->msg.type) { + case LCONF_MSG_STOP: + msg_stop(lconf); + ret = -1; + break; + case LCONF_MSG_START: + msg_start(lconf); + ret = -1; + break; + case LCONF_MSG_DUMP_RX: + case LCONF_MSG_DUMP_TX: + case LCONF_MSG_DUMP: + t = lconf->tasks_all[lconf->msg.task_id]; + + if (lconf->msg.val) { + if (lconf->msg.type == LCONF_MSG_DUMP || + lconf->msg.type == LCONF_MSG_DUMP_RX) { + t->aux->task_rt_dump.n_print_rx = lconf->msg.val; + + task_base_add_rx_pkt_function(t, rx_pkt_dump); + } + + if (lconf->msg.type == LCONF_MSG_DUMP || + lconf->msg.type == LCONF_MSG_DUMP_TX) { + t->aux->task_rt_dump.n_print_tx = lconf->msg.val; + if (t->aux->tx_pkt_orig) + t->tx_pkt = t->aux->tx_pkt_orig; + t->aux->tx_pkt_orig = t->tx_pkt; + t->tx_pkt = tx_pkt_dump; + } + } + break; + case LCONF_MSG_TRACE: + t = lconf->tasks_all[lconf->msg.task_id]; + + if (lconf->msg.val) { + t->aux->task_rt_dump.n_trace = lconf->msg.val; + + if (task_base_get_original_rx_pkt_function(t) != rx_pkt_dummy) { + task_base_add_rx_pkt_function(t, rx_pkt_trace); + if (t->aux->tx_pkt_orig) + t->tx_pkt = t->aux->tx_pkt_orig; + t->aux->tx_pkt_orig = t->tx_pkt; + t->tx_pkt = tx_pkt_trace; + } else { + t->aux->task_rt_dump.n_print_tx = lconf->msg.val; + if (t->aux->tx_pkt_orig) + t->tx_pkt = t->aux->tx_pkt_orig; + t->aux->tx_pkt_orig = t->tx_pkt; + t->tx_pkt = tx_pkt_dump; + } + } + break; + case LCONF_MSG_RX_DISTR_START: + for (uint8_t task_id = 0; task_id < lconf->n_tasks_all; ++task_id) { + t = lconf->tasks_all[task_id]; + task_base_add_rx_pkt_function(t, rx_pkt_distr); + memset(t->aux->rx_bucket, 0, sizeof(t->aux->rx_bucket)); + lconf->flags |= LCONF_FLAG_RX_DISTR_ACTIVE; + } + break; + case LCONF_MSG_TX_DISTR_START: + for (uint8_t task_id = 0; task_id < lconf->n_tasks_all; ++task_id) { + t = lconf->tasks_all[task_id]; + + t->aux->tx_pkt_orig = t->tx_pkt; + t->tx_pkt = tx_pkt_distr; + memset(t->aux->tx_bucket, 0, sizeof(t->aux->tx_bucket)); + lconf->flags |= LCONF_FLAG_TX_DISTR_ACTIVE; + } + break; + case LCONF_MSG_RX_DISTR_STOP: + for (uint8_t task_id = 0; task_id < lconf->n_tasks_all; ++task_id) { + t = lconf->tasks_all[task_id]; + task_base_del_rx_pkt_function(t, rx_pkt_distr); + lconf->flags &= ~LCONF_FLAG_RX_DISTR_ACTIVE; + } + break; + case LCONF_MSG_TX_DISTR_STOP: + for (uint8_t task_id = 0; task_id < lconf->n_tasks_all; ++task_id) { + t = lconf->tasks_all[task_id]; + if (t->aux->tx_pkt_orig) { + t->tx_pkt = t->aux->tx_pkt_orig; + t->aux->tx_pkt_orig = NULL; + lconf->flags &= ~LCONF_FLAG_TX_DISTR_ACTIVE; + } + } + break; + case LCONF_MSG_RX_DISTR_RESET: + for (uint8_t task_id = 0; task_id < lconf->n_tasks_all; ++task_id) { + t = lconf->tasks_all[task_id]; + + memset(t->aux->rx_bucket, 0, sizeof(t->aux->rx_bucket)); + } + break; + case LCONF_MSG_TX_DISTR_RESET: + for (uint8_t task_id = 0; task_id < lconf->n_tasks_all; ++task_id) { + t = lconf->tasks_all[task_id]; + + memset(t->aux->tx_bucket, 0, sizeof(t->aux->tx_bucket)); + } + break; + case LCONF_MSG_RX_BW_START: + for (uint8_t task_id = 0; task_id < lconf->n_tasks_all; ++task_id) { + t = lconf->tasks_all[task_id]; + task_base_add_rx_pkt_function(t, rx_pkt_bw); + lconf->flags |= LCONF_FLAG_RX_BW_ACTIVE; + } + break; + case LCONF_MSG_RX_BW_STOP: + for (uint8_t task_id = 0; task_id < lconf->n_tasks_all; ++task_id) { + t = lconf->tasks_all[task_id]; + task_base_del_rx_pkt_function(t, rx_pkt_bw); + lconf->flags &= ~LCONF_FLAG_RX_BW_ACTIVE; + } + break; + case LCONF_MSG_TX_BW_START: + for (uint8_t task_id = 0; task_id < lconf->n_tasks_all; ++task_id) { + t = lconf->tasks_all[task_id]; + + t->aux->tx_pkt_orig = t->tx_pkt; + t->tx_pkt = tx_pkt_bw; + lconf->flags |= LCONF_FLAG_TX_BW_ACTIVE; + } + break; + case LCONF_MSG_TX_BW_STOP: + for (uint8_t task_id = 0; task_id < lconf->n_tasks_all; ++task_id) { + t = lconf->tasks_all[task_id]; + if (t->aux->tx_pkt_orig) { + t->tx_pkt = t->aux->tx_pkt_orig; + t->aux->tx_pkt_orig = NULL; + lconf->flags &= ~LCONF_FLAG_TX_BW_ACTIVE; + } + } + break; + } + + lconf_unset_req(lconf); + return ret; +} + +int lconf_get_task_id(const struct lcore_cfg *lconf, const struct task_base *task) +{ + for (int i = 0; i < lconf->n_tasks_all; ++i) { + if (lconf->tasks_all[i] == task) + return i; + } + + return -1; +} + +int lconf_task_is_running(const struct lcore_cfg *lconf, uint8_t task_id) +{ + return lconf->task_is_running[task_id]; +} |