/* // 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 #include #include #include #include "log.h" #include "quit.h" #include "thread_pipeline.h" #include "lconf.h" #include "defines.h" /* Helper function: create pipeline, input ports and output ports */ void init_pipe_create_in_out(struct task_pipe *tpipe, struct task_args *targ) { struct task_base *tbase = (struct task_base *)tpipe; const char *name = targ->lconf->name; const char *mode = targ->task_init->mode_str; uint8_t lcore_id = targ->lconf->id; uint8_t task_id = targ->task; int err; /* create pipeline */ struct rte_pipeline_params pipeline_params = { .name = name, .socket_id = rte_lcore_to_socket_id(lcore_id), }; tpipe->p = rte_pipeline_create(&pipeline_params); PROX_PANIC(tpipe->p == NULL, "Failed to create %s pipeline on core %u task %u\n", mode, lcore_id, task_id); /* create pipeline input ports */ if (targ->nb_rxrings != 0) { for (uint8_t i = 0; i < tbase->rx_params_sw.nb_rxrings; ++i) { struct rte_port_ring_reader_params port_ring_params = { .ring = tbase->rx_params_sw.rx_rings[i], }; struct rte_pipeline_port_in_params port_params = { .ops = &rte_port_ring_reader_ops, .arg_create = &port_ring_params, .f_action = NULL, //TODO: fill metadata .arg_ah = NULL, .burst_size = MAX_RING_BURST, }; err = rte_pipeline_port_in_create(tpipe->p, &port_params, &tpipe->port_in_id[i]); PROX_PANIC(err != 0, "Failed to create SW input port %u " "for %s pipeline on core %u task %u: " "err = %d\n", i, mode, lcore_id, task_id, err); } tpipe->n_ports_in = tbase->rx_params_sw.nb_rxrings; } else { for (uint8_t i = 0; i < tbase->rx_params_hw.nb_rxports; ++i) { struct rte_port_ethdev_reader_params port_ethdev_params = { .port_id = tbase->rx_params_hw.rx_pq[i].port, .queue_id = tbase->rx_params_hw.rx_pq[i].queue, }; struct rte_pipeline_port_in_params port_params = { .ops = &rte_port_ethdev_reader_ops, .arg_create = &port_ethdev_params, .f_action = NULL, //TODO: fill metadata .arg_ah = NULL, .burst_size = MAX_PKT_BURST, }; err = rte_pipeline_port_in_create(tpipe->p, &port_params, &tpipe->port_in_id[0]); PROX_PANIC(err != 0, "Failed to create HW input port " "for %s pipeline on core %u task %u: " "err = %d\n", mode, lcore_id, task_id, err); } tpipe->n_ports_in = tbase->rx_params_hw.nb_rxports; } PROX_PANIC(tpipe->n_ports_in < 1, "No input port created " "for %s pipeline on core %u task %u\n", mode, lcore_id, task_id); /* create pipeline output ports */ if (targ->nb_txrings != 0) { for (uint8_t i = 0; i < tbase->tx_params_sw.nb_txrings; ++i) { struct rte_port_ring_writer_params port_ring_params = { .ring = tbase->tx_params_sw.tx_rings[i], .tx_burst_sz = MAX_RING_BURST, }; struct rte_pipeline_port_out_params port_params = { .ops = &rte_port_ring_writer_ops, .arg_create = &port_ring_params, .f_action = NULL, //TODO #if RTE_VERSION < RTE_VERSION_NUM(16,4,0,0) .f_action_bulk = NULL, //TODO #endif .arg_ah = NULL, }; err = rte_pipeline_port_out_create(tpipe->p, &port_params, &tpipe->port_out_id[i]); PROX_PANIC(err != 0, "Failed to create SW output port %u " "for %s pipeline on core %u task %u: " "err = %d\n", i, mode, lcore_id, task_id, err); } tpipe->n_ports_out = tbase->tx_params_sw.nb_txrings; } else { for (uint8_t i = 0; i < tbase->tx_params_hw.