aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.vppodp9
-rwxr-xr-xsrc/plugins/odp/cli.c20
-rwxr-xr-xsrc/plugins/odp/device.c16
-rwxr-xr-xsrc/plugins/odp/node.c11
-rwxr-xr-xsrc/plugins/odp/odp_packet.c314
-rwxr-xr-xsrc/plugins/odp/odp_packet.h29
-rw-r--r--src/vpp/conf/startup.conf36
7 files changed, 352 insertions, 83 deletions
diff --git a/README.vppodp b/README.vppodp
index 6e536987..fe1e2985 100644
--- a/README.vppodp
+++ b/README.vppodp
@@ -73,10 +73,13 @@ Below is a basic verification test.
Note :For odp-dpdk the port has to bound with dpdk driver prior to test and interface name is passed as 0,1..etc.
-1)Configure odp packet interface with mode ie (0-burst,1-queue,2-schedule) default mode is 0.
- Setting rx-queues to more than 1 will enable RSS.
+1)Configure odp packet interface with Rx/Tx mode and number of queues.
+ Rx mode can be set to 0-burst, 1-queue, 2-schedule (default mode is burst).
+ Tx mode can be set to 0-burst, 1-queue (default mode is burst)
+ Number of Rx queues can be 1 or more. It will determine number of threads and enable RSS (default is 1).
+ Number of Tx queues can be 0 (equal to number of threads, default) or 1 (single shared queue).
--create pktio-interface name <int name> hw-addr <mac> mode <0/1/2> rx-queues <number of input queues>
+-create pktio-interface name <int name> hw-addr <mac> rx-mode <0/1/2> rx-queues <num queues> tx-mode <0/1> tx-queues <num queues>
-set int ip address odp-<int name> X.X.X.X/24
-set int state odp-<int name> up
diff --git a/src/plugins/odp/cli.c b/src/plugins/odp/cli.c
index 4da921a0..2392ca1d 100755
--- a/src/plugins/odp/cli.c
+++ b/src/plugins/odp/cli.c
@@ -25,14 +25,14 @@ odp_packet_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
u8 *host_if_name = NULL;
u8 hwaddr[6];
u8 *hw_addr_ptr = 0;
- u32 sw_if_index;
- u32 mode = APPL_MODE_PKT_BURST;
- u32 rx_queues = 0;
+ u32 sw_if_index, num;
+ odp_if_mode_t if_mode;
int r;
if (!unformat_user (input, unformat_line_input, line_input))
return 0;
+ if_mode = def_if_mode;
while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
{
@@ -42,10 +42,14 @@ odp_packet_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
if (unformat
(line_input, "hw-addr %U", unformat_ethernet_address, hwaddr))
hw_addr_ptr = hwaddr;
- else if (unformat (line_input, "mode %d", &mode))
- ;
- else if (unformat (line_input, "rx-queues %d", &rx_queues))
- ;
+ else if (unformat (line_input, "rx-mode %d", &num))
+ if_mode.rx_mode = num;
+ else if (unformat (line_input, "tx-mode %d", &num))
+ if_mode.tx_mode = num;
+ else if (unformat (line_input, "rx-queues %d", &num))
+ if_mode.num_rx_queues = num;
+ else if (unformat (line_input, "tx-queues %d", &num))
+ if_mode.num_tx_queues = num;
else
return clib_error_return (0, "unknown input `%U'",
format_unformat_error, input);
@@ -56,7 +60,7 @@ odp_packet_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
return clib_error_return (0, "missing host interface name");
r = odp_packet_create_if (vm, host_if_name, hw_addr_ptr, &sw_if_index,
- mode, rx_queues);
+ &if_mode);
vec_free (host_if_name);
if (r == VNET_API_ERROR_SYSCALL_ERROR_1)
diff --git a/src/plugins/odp/device.c b/src/plugins/odp/device.c
index 68397dbb..eebc2aa0 100755
--- a/src/plugins/odp/device.c
+++ b/src/plugins/odp/device.c
@@ -77,10 +77,11 @@ odp_packet_interface_tx (vlib_main_t * vm,
u32 n_left = frame->n_vectors;
vnet_interface_output_runtime_t *rd = (void *) node->runtime_data;
odp_packet_if_t *oif = pool_elt_at_index (om->interfaces, rd->dev_instance);
- uword queue_index = vlib_get_thread_index () % oif->tx_queues;
- u32 mode = oif->mode;
- odp_packet_t pkt_tbl[VLIB_FRAME_SIZE];
- odp_event_t evt_tbl[VLIB_FRAME_SIZE];
+ uword queue_index = vlib_get_thread_index () % oif->m.num_tx_queues;
+ u32 mode = oif->m.tx_mode;
+ u32 burst_size = (tx_burst_size ? tx_burst_size : VLIB_FRAME_SIZE);
+ odp_packet_t pkt_tbl[burst_size];
+ odp_event_t evt_tbl[burst_size];
vlib_buffer_t *b0;
u32 bi, sent, count = 0;
@@ -122,10 +123,9 @@ odp_packet_interface_tx (vlib_main_t * vm,
count++;
bi = b0->next_buffer;
}
- while ((b0->flags & VLIB_BUFFER_NEXT_PRESENT)
- && (count < VLIB_FRAME_SIZE));
+ while ((b0->flags & VLIB_BUFFER_NEXT_PRESENT) && (count < burst_size));
- if ((n_left > 0) && (count < VLIB_FRAME_SIZE))
+ if ((n_left > 0) && (count < burst_size))
continue;
sent = 0;
@@ -133,7 +133,6 @@ odp_packet_interface_tx (vlib_main_t * vm,
{
switch (mode)
{
- case APPL_MODE_PKT_SCHED:
case APPL_MODE_PKT_BURST:
ret =
odp_pktout_send (oif->outq[queue_index], &pkt_tbl[sent],
@@ -143,6 +142,7 @@ odp_packet_interface_tx (vlib_main_t * vm,
ret = odp_queue_enq_multi (oif->txq[queue_index],
&evt_tbl[sent], count);
break;
+ case APPL_MODE_PKT_TM:
default:
ret = 0;
clib_error ("Invalid mode\n");
diff --git a/src/plugins/odp/node.c b/src/plugins/odp/node.c
index f7e02b7b..1a8b04c9 100755
--- a/src/plugins/odp/node.c
+++ b/src/plugins/odp/node.c
@@ -80,7 +80,7 @@ odp_packet_queue_mode (odp_packet_if_t * oif, odp_packet_t pkt_tbl[],
clib_warning ("invalid oif->pktio value");
return 0;
}
- if ((oif->mode == APPL_MODE_PKT_QUEUE) &&
+ if ((oif->m.rx_mode == APPL_MODE_PKT_QUEUE) &&
(oif->rxq[queue_id] == ODP_QUEUE_INVALID))
{
clib_warning ("invalid rxq[%d] queue", queue_id);
@@ -89,14 +89,15 @@ odp_packet_queue_mode (odp_packet_if_t * oif, odp_packet_t pkt_tbl[],
while (req_pkts)
{
- if (oif->mode == APPL_MODE_PKT_QUEUE)
+ if (oif->m.rx_mode == APPL_MODE_PKT_QUEUE)
{
i = odp_queue_deq_multi (oif->rxq[queue_id],
&evt_tbl[num_evts], req_pkts);
}
else
{
- sched_wait = odp_schedule_wait_time (ODP_TIME_USEC_IN_NS);
+ sched_wait = odp_schedule_wait_time (ODP_TIME_USEC_IN_NS *
+ rx_sched_wait);
i = odp_schedule_multi (NULL, sched_wait,
&evt_tbl[num_evts], req_pkts);
}
@@ -229,8 +230,8 @@ odp_packet_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
do
{
- if ((oif->mode == (APPL_MODE_PKT_QUEUE)) ||
- (oif->mode == (APPL_MODE_PKT_SCHED)))
+ if ((oif->m.rx_mode == (APPL_MODE_PKT_QUEUE)) ||
+ (oif->m.rx_mode == (APPL_MODE_PKT_SCHED)))
{
pkts =
odp_packet_queue_mode (oif, pkt_tbl, queue_id, n_left_to_next);
diff --git a/src/plugins/odp/odp_packet.c b/src/plugins/odp/odp_packet.c
index bcb8a489..86992c67 100755
--- a/src/plugins/odp/odp_packet.c
+++ b/src/plugins/odp/odp_packet.c
@@ -10,11 +10,17 @@
#include <vlib/unix/unix.h>
#include <vnet/ip/ip.h>
#include <vnet/ethernet/ethernet.h>
-#include <odp/odp_packet.h>
#include <vnet/plugin/plugin.h>
#include <vpp/app/version.h>
+#include <odp/odp_packet.h>
odp_packet_main_t *odp_packet_main;
+odp_platform_init_t platform_params;
+u32 rx_sched_wait;
+u32 tx_burst_size;
+u32 num_pkts_in_pool = SHM_PKT_POOL_NB_PKTS;
+odp_if_mode_t def_if_mode;
+odp_if_config_t *if_config;
static u32
odp_packet_eth_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi,
@@ -61,8 +67,7 @@ drop_err_pkts (odp_packet_t pkt_tbl[], unsigned len)
}
static odp_pktio_t
-create_pktio (const char *dev, odp_pool_t pool, u32 mode,
- odp_packet_if_t * oif)
+create_pktio (const char *dev, odp_pool_t pool, odp_packet_if_t * oif)
{
odp_pktio_t pktio;
int ret;
@@ -75,22 +80,35 @@ create_pktio (const char *dev, odp_pool_t pool, u32 mode,
odp_pktio_param_init (&pktio_param);
- switch (mode)
+ switch (oif->m.rx_mode)
{
case APPL_MODE_PKT_BURST:
pktio_param.in_mode = ODP_PKTIN_MODE_DIRECT;
- pktio_param.out_mode = ODP_PKTOUT_MODE_DIRECT;
break;
case APPL_MODE_PKT_QUEUE:
pktio_param.in_mode = ODP_PKTIN_MODE_QUEUE;
- pktio_param.out_mode = ODP_PKTOUT_MODE_QUEUE;
break;
case APPL_MODE_PKT_SCHED:
pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
+ break;
+ default:
+ clib_warning ("Invalid RX mode\n");
+ }
+
+ switch (oif->m.tx_mode)
+ {
+ case APPL_MODE_PKT_BURST:
pktio_param.out_mode = ODP_PKTOUT_MODE_DIRECT;
break;
+ case APPL_MODE_PKT_QUEUE:
+ pktio_param.out_mode = ODP_PKTOUT_MODE_QUEUE;
+ break;
+ case APPL_MODE_PKT_TM:
+ clib_error ("Traffic Manager mode not supported!\n");
+ pktio_param.out_mode = ODP_PKTOUT_MODE_TM;
+ break;
default:
- clib_warning ("Invalid mode\n");
+ clib_warning ("Invalid TX mode\n");
}
/* Open a packet IO instance */
@@ -115,28 +133,29 @@ create_pktio (const char *dev, odp_pool_t pool, u32 mode,
odp_pktin_queue_param_init (&pktin_param);
pktin_param.op_mode = ODP_PKTIO_OP_MT_UNSAFE;
- if (oif->rx_queues > capa.max_input_queues)
+ if (oif->m.num_rx_queues > capa.max_input_queues)
{
- oif->rx_queues = capa.max_input_queues;
- clib_warning ("Number of RX queues limited to %d\n", oif->rx_queues);
+ oif->m.num_rx_queues = capa.max_input_queues;
+ clib_warning ("pktio %s: Number of RX queues limited to %d\n",
+ dev, oif->m.num_rx_queues);
}
- if (oif->rx_queues > 1)
+ if (oif->m.num_rx_queues > 1)
{
- if (oif->rx_queues > MAX_QUEUES)
- oif->rx_queues = MAX_QUEUES;
+ if (oif->m.num_rx_queues > MAX_QUEUES)
+ oif->m.num_rx_queues = MAX_QUEUES;
pktin_param.classifier_enable = 0;
pktin_param.hash_enable = 1;
- pktin_param.num_queues = oif->rx_queues;
+ pktin_param.num_queues = oif->m.num_rx_queues;
pktin_param.hash_proto.proto.ipv4_udp = 1;
pktin_param.hash_proto.proto.ipv4_tcp = 1;
pktin_param.hash_proto.proto.ipv4 = 1;
}
else
- oif->rx_queues = 1;
+ oif->m.num_rx_queues = 1;
- if (mode == APPL_MODE_PKT_SCHED)
+ if (oif->m.rx_mode == APPL_MODE_PKT_SCHED)
pktin_param.queue_param.sched.sync = ODP_SCHED_SYNC_ATOMIC;
if (odp_pktin_queue_config (pktio, &pktin_param))
@@ -145,15 +164,16 @@ create_pktio (const char *dev, odp_pool_t pool, u32 mode,
}
odp_pktout_queue_param_init (&pktout_param);
- if (capa.max_output_queues >= tm->n_vlib_mains)
+ if ((capa.max_output_queues >= tm->n_vlib_mains) &&
+ (oif->m.num_tx_queues == 0))
{
pktout_param.op_mode = ODP_PKTIO_OP_MT_UNSAFE;
pktout_param.num_queues = tm->n_vlib_mains;
- oif->tx_queues = tm->n_vlib_mains;
+ oif->m.num_tx_queues = tm->n_vlib_mains;
}
else
{
- oif->tx_queues = 1;
+ oif->m.num_tx_queues = 1;
}
if (odp_pktout_queue_config (pktio, &pktout_param))
@@ -172,7 +192,7 @@ create_pktio (const char *dev, odp_pool_t pool, u32 mode,
u32
odp_packet_create_if (vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set,
- u32 * sw_if_index, u32 mode, u32 rx_queues)
+ u32 * sw_if_index, odp_if_mode_t * mode)
{
odp_packet_main_t *om = odp_packet_main;
int ret = 0, j;
@@ -182,7 +202,6 @@ odp_packet_create_if (vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set,
vnet_sw_interface_t *sw;
vnet_main_t *vnm = vnet_get_main ();
uword *p;
- u8 *host_if_name_dup = vec_dup (host_if_name);
vlib_thread_main_t *tm = vlib_get_thread_main ();
p = mhash_get (&om->if_index_by_host_if_name, host_if_name);
@@ -191,17 +210,21 @@ odp_packet_create_if (vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set,
pool_get (om->interfaces, oif);
oif->if_index = oif - om->interfaces;
- oif->host_if_name = host_if_name_dup;
+ oif->host_if_name = vec_dup (host_if_name);
oif->per_interface_next_index = ~0;
+ oif->m = *mode;
- if (mode == APPL_MODE_PKT_SCHED)
- oif->rx_queues = tm->n_vlib_mains - 1;
- else
- oif->rx_queues = rx_queues;
+ if (mode->rx_mode == APPL_MODE_PKT_SCHED)
+ oif->m.num_rx_queues = tm->n_vlib_mains - 1;
/* Create a pktio instance */
- oif->pktio = create_pktio ((char *) host_if_name, om->pool, mode, oif);
- oif->mode = mode;
+ oif->pktio = create_pktio ((char *) host_if_name, om->pool, oif);
+ if (oif->pktio == 0)
+ {
+ ret = VNET_API_ERROR_INVALID_INTERFACE;
+ goto error;
+ }
+
om->if_count++;
if (tm->n_vlib_mains > 1)
@@ -211,22 +234,21 @@ odp_packet_create_if (vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set,
memset ((void *) oif->lockp, 0, CLIB_CACHE_LINE_BYTES);
}
- if ((mode == APPL_MODE_PKT_BURST) || (mode == APPL_MODE_PKT_SCHED))
- {
- odp_pktin_queue (oif->pktio, oif->inq, oif->rx_queues);
- odp_pktout_queue (oif->pktio, oif->outq, oif->tx_queues);
- }
- else if (mode == APPL_MODE_PKT_QUEUE)
- {
- odp_pktin_event_queue (oif->pktio, oif->rxq, oif->rx_queues);
- odp_pktout_event_queue (oif->pktio, oif->txq, oif->tx_queues);
- }
+ if (mode->rx_mode == APPL_MODE_PKT_BURST)
+ odp_pktin_queue (oif->pktio, oif->inq, oif->m.num_rx_queues);
+ else if (mode->rx_mode == APPL_MODE_PKT_QUEUE)
+ odp_pktin_event_queue (oif->pktio, oif->rxq, oif->m.num_rx_queues);
+ if (mode->tx_mode == APPL_MODE_PKT_BURST)
+ odp_pktout_queue (oif->pktio, oif->outq, oif->m.num_tx_queues);
+ else if (mode->tx_mode == APPL_MODE_PKT_QUEUE)
+ odp_pktout_event_queue (oif->pktio, oif->txq, oif->m.num_tx_queues);
- /*use configured or generate random MAC address */
+ /* Use configured MAC or read MAC from DPDK */
if (hw_addr_set)
clib_memcpy (hw_addr, hw_addr_set, 6);
- else
+ else if (odp_pktio_mac_addr (oif->pktio, hw_addr, sizeof (hw_addr)) < 6)
{
+ /* Failed to read MAC from driver, set random MAC */
f64 now = vlib_time_now (vm);
u32 rnd;
rnd = (u32) (now * 1e6);
@@ -244,8 +266,6 @@ odp_packet_create_if (vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set,
if (error)
{
- memset (oif, 0, sizeof (*oif));
- pool_put (om->interfaces, oif);
clib_error_report (error);
ret = VNET_API_ERROR_SYSCALL_ERROR_1;
goto error;
@@ -259,15 +279,15 @@ odp_packet_create_if (vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set,
vnet_hw_interface_set_flags (vnm, oif->hw_if_index,
VNET_HW_INTERFACE_FLAG_LINK_UP);
- mhash_set_mem (&om->if_index_by_host_if_name, host_if_name_dup,
+ mhash_set_mem (&om->if_index_by_host_if_name, oif->host_if_name,
&oif->if_index, 0);
if (sw_if_index)
*sw_if_index = oif->sw_if_index;
/* Assign queues of the new interface to first available worker thread */
- for (j = 0; j < oif->rx_queues; j++)
+ for (j = 0; j < oif->m.num_rx_queues; j++)
{
- if (mode == APPL_MODE_PKT_SCHED)
+ if (mode->rx_mode == APPL_MODE_PKT_SCHED)
vnet_hw_interface_assign_rx_thread (vnm, oif->hw_if_index, 0, j + 1);
else
vnet_hw_interface_assign_rx_thread (vnm, oif->hw_if_index, j, -1);
@@ -276,7 +296,9 @@ odp_packet_create_if (vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set,
return 0;
error:
- vec_free (host_if_name_dup);
+ vec_free (oif->host_if_name);
+ memset (oif, 0, sizeof (*oif));
+ pool_put (om->interfaces, oif);
return ret;
}
@@ -326,6 +348,191 @@ odp_packet_delete_if (vlib_main_t * vm, u8 * host_if_name)
}
static clib_error_t *
+odp_device_config (char *name, unformat_input_t * input)
+{
+ odp_if_mode_t mode;
+ odp_if_config_t *config;
+ char *val;
+ u32 num;
+ u8 set_hw_addr = 0;
+ u8 hw_addr[6];
+
+ mode = def_if_mode;
+
+ if (input)
+ {
+ unformat_skip_white_space (input);
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "rx-mode %s", &val))
+ {
+ if (!strcmp (val, "burst") || !strcmp (val, "0"))
+ mode.rx_mode = APPL_MODE_PKT_BURST;
+ else if (!strcmp (val, "queue") || !strcmp (val, "1"))
+ mode.rx_mode = APPL_MODE_PKT_QUEUE;
+ else if (!strcmp (val, "sched") || !strcmp (val, "2"))
+ mode.rx_mode = APPL_MODE_PKT_SCHED;
+ vec_free (val);
+ }
+ else if (unformat (input, "tx-mode %s", &val))
+ {
+ if (!strcmp (val, "burst") || !strcmp (val, "0"))
+ mode.tx_mode = APPL_MODE_PKT_BURST;
+ else if (!strcmp (val, "queue") || !strcmp (val, "1"))
+ mode.tx_mode = APPL_MODE_PKT_QUEUE;
+ else if (!strcmp (val, "tm") || !strcmp (val, "2"))
+ mode.tx_mode = APPL_MODE_PKT_TM;
+ vec_free (val);
+ }
+ else if (unformat (input, "num-rx-queues %u", &num))
+ mode.num_rx_queues = num;
+ else if (unformat (input, "num-tx-queues %u", &num))
+ mode.num_tx_queues = num;
+ else if (unformat (input, "num-tx-queues %s", &val))
+ {
+ if (!strcmp (val, "max"))
+ mode.num_tx_queues = 0;
+ vec_free (val);
+ }
+ else if (unformat (input, "hw-addr %U", unformat_ethernet_address,
+ hw_addr))
+ set_hw_addr = 1;
+ else if (unformat (input, "%s", &val))
+ {
+ clib_warning ("%s: Unknown option %s\n", __func__, val);
+ vec_free (val);
+ }
+ }
+ }
+
+ if (!name)
+ {
+ def_if_mode = mode;
+ return 0;
+ }
+
+ /* Save configuration */
+ pool_get (if_config, config);
+ config->name = (u8 *) vec_dup (name);
+ config->mode = mode;
+ clib_memcpy (config->hw_addr, hw_addr, 6);
+ config->set_hw_addr = set_hw_addr;
+
+ return 0;
+}
+
+static clib_error_t *
+odp_config (vlib_main_t * vm, unformat_input_t * input)
+{
+ char *param = NULL;
+ u32 num;
+ unformat_input_t sub_input;
+ unformat_input_t line_input;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "platform-params %U",
+ unformat_vlib_cli_sub_input, &sub_input))
+ {
+ unformat_skip_white_space (&sub_input);
+ while (unformat_check_input (&sub_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (&sub_input, "memory %u", &num))
+ platform_params.memory = num;
+ else if (unformat (&sub_input, "cmdline %U",
+ unformat_vlib_cli_sub_input, &line_input))
+ {
+ unformat (&line_input, "%U", unformat_line, &param);
+ platform_params.cmdline = param;
+ unformat_free (&line_input);
+ }
+ else if (unformat (&sub_input, "%s", &param))
+ {
+ clib_warning ("%s: Unknown platform option %s\n", __func__,
+ param);
+ vec_free (param);
+ }
+ }
+ unformat_free (&sub_input);
+ }
+ else if (unformat (input, "rx-sched-wait %u", &rx_sched_wait))
+ ;
+ else if (unformat (input, "tx-burst-size %u", &tx_burst_size))
+ ;
+ else if (unformat (input, "num-pkts-in-pool %u", &num_pkts_in_pool))
+ ;
+ else if (unformat (input, "default %U", unformat_vlib_cli_sub_input,
+ &sub_input))
+ {
+ odp_device_config (NULL, &sub_input);
+ unformat_free (&sub_input);
+ }
+ else if (unformat (input, "dev %s %U", &param,
+ unformat_vlib_cli_sub_input, &sub_input))
+ {
+ odp_device_config (param, &sub_input);
+ vec_free (param);
+ unformat_free (&sub_input);
+ }
+ else if (unformat (input, "dev %s", &param))
+ {
+ odp_device_config (param, NULL);
+ vec_free (param);
+ }
+ else if (unformat (input, "%s", &param))
+ {
+ clib_warning ("%s: Unknown option %s\n", __func__, param);
+ vec_free (param);
+ }
+ }
+
+ return 0;
+}
+
+VLIB_EARLY_CONFIG_FUNCTION (odp_config, "odp");
+
+static uword
+odp_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
+{
+ u32 i, ret;
+ odp_if_config_t *config;
+ vlib_thread_main_t *tm = vlib_get_thread_main ();
+
+ /* Create interfaces defined in startup configuration file */
+ for (i = 0; i < pool_len (if_config); i++)
+ {
+ config = pool_elt_at_index (if_config, i);
+ ret = odp_packet_create_if (vm, config->name,
+ (config->set_hw_addr ? config->hw_addr :
+ NULL), NULL, &config->mode);
+ vec_free (config->name);
+
+ if (ret == VNET_API_ERROR_SYSCALL_ERROR_1)
+ clib_warning ("%s (errno %d)", strerror (errno), errno);
+
+ if (ret == VNET_API_ERROR_INVALID_INTERFACE)
+ clib_warning ("Invalid interface name");
+
+ if (ret == VNET_API_ERROR_SUBIF_ALREADY_EXISTS)
+ clib_warning ("Interface already exists");
+ }
+ pool_free (if_config);
+
+ /* Initialization complete and worker threads can start */
+ tm->worker_thread_release = 1;
+
+ return 0;
+}
+
+/* *INDENT-OFF* */
+VLIB_REGISTER_NODE (odp_process_node,static) = {
+ .function = odp_process,
+ .type = VLIB_NODE_TYPE_PROCESS,
+ .name = "odp-process",
+};
+/* *INDENT-ON* */
+
+static clib_error_t *
odp_packet_init (vlib_main_t * vm)
{
odp_packet_main_t *om;
@@ -333,17 +540,19 @@ odp_packet_init (vlib_main_t * vm)
vlib_thread_registration_t *tr;
vlib_physmem_main_t *vpm = &vm->physmem_main;
uword *p;
- odp_platform_init_t platform_params;
odp_pool_param_t params;
odp_pool_capability_t capa;
odp_shm_t shm;
odp_instance_t instance;
- memset (&platform_params, 0, sizeof (platform_params));
- platform_params.memory = 100;
+ if (platform_params.memory == 0)
+ {
+ platform_params.memory = 50 + num_pkts_in_pool * 4 / 1024;
+ clib_warning ("Warning: Platform 'memory' parameter not configured!");
+ }
if (odp_init_global (&instance, NULL, &platform_params))
- clib_warning ("Error:ODP global init failed");
+ clib_warning ("Error: ODP global init failed");
if (odp_init_local (instance, ODP_THREAD_CONTROL) != 0)
{
@@ -379,7 +588,7 @@ odp_packet_init (vlib_main_t * vm)
params.pkt.seg_len = SHM_PKT_POOL_BUF_SIZE;
params.pkt.len = SHM_PKT_POOL_BUF_SIZE;
params.type = ODP_POOL_PACKET;
- params.pkt.num = SHM_PKT_POOL_NB_PKTS;
+ params.pkt.num = num_pkts_in_pool;
params.pkt.uarea_size = sizeof (vlib_buffer_t) - VLIB_BUFFER_PRE_DATA_SIZE;
om->pool = odp_pool_create (SHM_PKT_POOL_NAME, &params);
@@ -405,9 +614,6 @@ odp_packet_init (vlib_main_t * vm)
vpm->virtual.end = params.pool_end;
vpm->virtual.size = params.pool_size;
- /* Initialization complete and worker threads do not need to sync */
- tm->worker_thread_release = 1;
-
return 0;
}
diff --git a/src/plugins/odp/odp_packet.h b/src/plugins/odp/odp_packet.h
index 81b4a8e2..a80ab326 100755
--- a/src/plugins/odp/odp_packet.h
+++ b/src/plugins/odp/odp_packet.h
@@ -14,12 +14,29 @@
#define APPL_MODE_PKT_BURST 0
#define APPL_MODE_PKT_QUEUE 1
#define APPL_MODE_PKT_SCHED 2
+#define APPL_MODE_PKT_TM 3
#define MAX_WORKERS 32
#define MAX_QUEUES (MAX_WORKERS + 1)
typedef struct
{
+ u16 num_tx_queues;
+ u16 num_rx_queues;
+ u8 tx_mode;
+ u8 rx_mode;
+} odp_if_mode_t;
+
+typedef struct
+{
+ u8 *name;
+ odp_if_mode_t mode;
+ u8 hw_addr[6];
+ u8 set_hw_addr;
+} odp_if_config_t;
+
+typedef struct
+{
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
u8 *host_if_name;
volatile u32 *lockp;
@@ -31,13 +48,11 @@ typedef struct
u32 next_tx_frame;
u32 per_interface_next_index;
u8 is_admin_up;
- u32 mode;
odp_queue_t rxq[MAX_QUEUES];
odp_pktin_queue_t inq[MAX_QUEUES];
odp_pktout_queue_t outq[MAX_QUEUES];
odp_queue_t txq[MAX_QUEUES];
- u16 rx_queues;
- u16 tx_queues;
+ odp_if_mode_t m;
} odp_packet_if_t;
typedef struct
@@ -58,10 +73,14 @@ typedef struct
extern odp_packet_main_t *odp_packet_main;
extern vnet_device_class_t odp_packet_device_class;
extern vlib_node_registration_t odp_packet_input_node;
+extern u32 rx_sched_wait;
+extern u32 tx_burst_size;
+extern u32 num_pkts_in_pool;
+extern odp_if_mode_t def_if_mode;
u32 odp_packet_create_if (vlib_main_t * vm, u8 * host_if_name,
- u8 * hw_addr_set, u32 * sw_if_index, u32 mode,
- u32 rx_queues);
+ u8 * hw_addr_set, u32 * sw_if_index,
+ odp_if_mode_t * mode);
u32 odp_packet_delete_if (vlib_main_t * vm, u8 * host_if_name);
u32 drop_err_pkts (odp_packet_t pkt_tbl[], u32 len);
diff --git a/src/vpp/conf/startup.conf b/src/vpp/conf/startup.conf
index f671439b..6438f770 100644
--- a/src/vpp/conf/startup.conf
+++ b/src/vpp/conf/startup.conf
@@ -98,6 +98,42 @@ cpu {
# socket-mem 2048,2048
# }
+# odp {
+ # platform-params {
+ # memory 100
+ # }
+
+ ## Number of packets in allocated pool
+ # num-pkts-in-pool 10240
+
+ ## Delay in microseconds between calls to odp_schedule_multi
+ # rx-sched-wait 0
+
+ ## Limit of output burst size. May increase performance.
+ # tx-burst-size 32
+
+ ## Default configuration for all ODP devices.
+ ## rx-mode can be set to burst, queue or sched
+ ## tx-mode can be burst, queue or tm (traffic manager)
+ ## num-rx-queues can be set to more than 1 to enable RSS
+ ## num-tx-queues can be 'max' (separate queue for each thread) or 1
+ # default {
+ # rx-mode burst
+ # tx-mode burst
+ # num-rx-queues 1
+ # num-tx-queues max
+ # }
+
+ ## Defined ODP devices are created automatically at startup.
+ ## dev (DPDK port number) [{ options }]
+ ## hw-addr - if not specified, MAC will be read from hardware
+ # dev 0 {
+ # rx-mode queue
+ # num-rx-queues 2
+ # hw-addr 3c:fd:fe:a4:37:99
+ # }
+# }
+
# Adjusting the plugin path depending on where the VPP plugins are:
#plugins
#{