aboutsummaryrefslogtreecommitdiff
path: root/example
diff options
context:
space:
mode:
authorBalakrishna Garapati <balakrishna.garapati@linaro.org>2016-12-14 12:55:15 +0100
committerBalakrishna Garapati <balakrishna.garapati@linaro.org>2016-12-14 12:55:15 +0100
commit13f93292274b8123f3bbed54ddf84cf304909db4 (patch)
tree0e385d519258b5b1e70bd3d149d1a93dc90b6ac0 /example
parent3385e3e1a36dbb37c6b121ef3162f94d1cc21ac5 (diff)
parent4cfe988cc6e0667928c23a4715eeac8a301396ac (diff)
Merge tag 'v1.12.0.0' into dpdk_v1.12.0.0
Signed-off-by: Balakrishna Garapati <balakrishna.garapati@linaro.org> Conflicts: configure.ac
Diffstat (limited to 'example')
-rw-r--r--example/Makefile.inc3
-rw-r--r--example/l3fwd/.gitignore2
-rw-r--r--example/l3fwd/odp_l3fwd.c222
3 files changed, 141 insertions, 86 deletions
diff --git a/example/Makefile.inc b/example/Makefile.inc
index d0bc8afb0..c7de6db64 100644
--- a/example/Makefile.inc
+++ b/example/Makefile.inc
@@ -7,6 +7,7 @@ AM_CFLAGS += \
-I$(top_srcdir)/platform/@with_platform@/include \
-I$(top_srcdir)/include/ \
-I$(top_srcdir)/helper/include \
- -I$(top_builddir)/platform/@with_platform@/include
+ -I$(top_builddir)/platform/@with_platform@/include \
+ -I$(top_builddir)/include
AM_LDFLAGS += -L$(LIB)
diff --git a/example/l3fwd/.gitignore b/example/l3fwd/.gitignore
index 74e501f9c..3411830e4 100644
--- a/example/l3fwd/.gitignore
+++ b/example/l3fwd/.gitignore
@@ -1 +1,3 @@
odp_l3fwd
+*.log
+*.trs
diff --git a/example/l3fwd/odp_l3fwd.c b/example/l3fwd/odp_l3fwd.c
index 44778b0aa..8919bd387 100644
--- a/example/l3fwd/odp_l3fwd.c
+++ b/example/l3fwd/odp_l3fwd.c
@@ -62,6 +62,7 @@ struct thread_arg_s {
uint64_t rx_drops;
uint64_t tx_drops;
struct {
+ int if_idx; /* interface index */
int nb_rxq; /* number of rxq this thread will access */
int rxq[MAX_NB_QUEUE]; /* rxq[i] is index in pktio.ifin[] */
int txq_idx; /* index in pktio.ifout[] */
@@ -80,6 +81,7 @@ typedef struct {
uint32_t duration; /* seconds to run */
uint8_t hash_mode; /* 1:hash, 0:lpm */
uint8_t dest_mac_changed[MAX_NB_PKTIO]; /* 1: dest mac from cmdline */
+ int error_check; /* Check packets for errors */
} app_args_t;
struct {
@@ -158,17 +160,32 @@ static void setup_fwd_db(void)
}
}
-static int l3fwd_pkt_hash(odp_packet_t pkt, int sif)
+/**
+ * Decrement TTL and incrementally update checksum
+ *
+ * @param ip IPv4 header
+ */
+static inline void ipv4_dec_ttl_csum_update(odph_ipv4hdr_t *ip)
+{
+ uint16_t a = ~odp_cpu_to_be_16(1 << 8);
+
+ ip->ttl--;
+ if (ip->chksum >= a)
+ ip->chksum -= a;
+ else
+ ip->chksum += odp_cpu_to_be_16(1 << 8);
+}
+
+static inline int l3fwd_pkt_hash(odp_packet_t pkt, int sif)
{
fwd_db_entry_t *entry;
ipv4_tuple5_t key;
odph_ethhdr_t *eth;
odph_udphdr_t *udp;
odph_ipv4hdr_t *ip;
- uint32_t len;
int dif;
- ip = odp_packet_l3_ptr(pkt, &len);
+ ip = odp_packet_l3_ptr(pkt, NULL);
key.dst_ip = odp_be_to_cpu_32(ip->dst_addr);
key.src_ip = odp_be_to_cpu_32(ip->src_addr);
key.proto = ip->proto;
@@ -186,8 +203,7 @@ static int l3fwd_pkt_hash(odp_packet_t pkt, int sif)
key.dst_port = 0;
}
entry = find_fwd_db_entry(&key);
- ip->ttl--;
- ip->chksum = odph_ipv4_csum_update(pkt);
+ ipv4_dec_ttl_csum_update(ip);
eth = odp_packet_l2_ptr(pkt, NULL);
if (entry) {
eth->src = entry->src_mac;
@@ -202,17 +218,15 @@ static int l3fwd_pkt_hash(odp_packet_t pkt, int sif)
return dif;
}
-static int l3fwd_pkt_lpm(odp_packet_t pkt, int sif)
+static inline int l3fwd_pkt_lpm(odp_packet_t pkt, int sif)
{
odph_ipv4hdr_t *ip;
odph_ethhdr_t *eth;
- uint32_t len;
int dif;
int ret;
- ip = odp_packet_l3_ptr(pkt, &len);
- ip->ttl--;
- ip->chksum = odph_ipv4_csum_update(pkt);
+ ip = odp_packet_l3_ptr(pkt, NULL);
+ ipv4_dec_ttl_csum_update(ip);
eth = odp_packet_l2_ptr(pkt, NULL);
/* network byte order maybe different from host */
@@ -227,10 +241,10 @@ static int l3fwd_pkt_lpm(odp_packet_t pkt, int sif)
}
/**
- * Drop packets which input parsing marked as containing errors.
+ * Drop unsupported packets and packets containing errors.
*
- * Frees packets with error and modifies pkt_tbl[] to only contain packets with
- * no detected errors.
+ * Frees packets with errors or unsupported protocol and modifies pkt_tbl[] to
+ * only contain valid packets.
*
* @param pkt_tbl Array of packets
* @param num Number of packets in pkt_tbl[]
@@ -242,12 +256,16 @@ static inline int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned num)
odp_packet_t pkt;
unsigned dropped = 0;
unsigned i, j;
+ int err;
for (i = 0, j = 0; i < num; ++i) {
pkt = pkt_tbl[i];
+ err = 0;
- if (odp_unlikely(odp_packet_has_error(pkt) ||
- !odp_packet_has_ipv4(pkt))) {
+ if (global.cmd_args.error_check)
+ err = odp_packet_has_error(pkt);
+
+ if (odp_unlikely(err || !odp_packet_has_ipv4(pkt))) {
odp_packet_free(pkt);
dropped++;
} else if (odp_unlikely(i != j++)) {
@@ -258,75 +276,87 @@ static inline int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned num)
return dropped;
}
-static void l3fwd_one_queue(uint32_t sif, int rxq_idx, void *thr_arg)
+static int run_worker(void *arg)
{
- odp_packet_t *tbl;
- odp_pktout_queue_t outq;
+ int if_idx;
+ struct thread_arg_s *thr_arg = arg;
odp_pktin_queue_t inq;
+ int input_ifs[thr_arg->nb_pktio];
+ odp_pktin_queue_t input_queues[thr_arg->nb_pktio];
+ odp_pktout_queue_t output_queues[global.cmd_args.if_count];
odp_packet_t pkt_tbl[MAX_PKT_BURST];
- struct thread_arg_s *arg;
+ odp_packet_t *tbl;
int pkts, drop, sent;
int dst_port, dif;
- int i;
+ int i, j;
+ int pktio = 0;
+ int num_pktio = 0;
- arg = thr_arg;
- inq = global.l3fwd_pktios[sif].ifin[rxq_idx];
- pkts = odp_pktin_recv(inq, pkt_tbl, MAX_PKT_BURST);
- if (pkts <= 0)
- return;
-
- arg->packets += pkts;
- drop = drop_err_pkts(pkt_tbl, pkts);
- pkts -= drop;
- arg->rx_drops += drop;
-
- dif = global.fwd_func(pkt_tbl[0], sif);
- tbl = &pkt_tbl[0];
- while (pkts) {
- int txq_idx;
-
- dst_port = dif;
- for (i = 1; i < pkts; i++) {
- dif = global.fwd_func(tbl[i], sif);
- if (dif != dst_port)
- break;
- }
+ /* Copy all required handles to local memory */
+ for (i = 0; i < global.cmd_args.if_count; i++) {
+ int txq_idx = thr_arg->pktio[i].txq_idx;
- txq_idx = arg->pktio[dst_port].txq_idx;
- outq = global.l3fwd_pktios[dst_port].ifout[txq_idx];
- sent = odp_pktout_send(outq, tbl, i);
- if (odp_unlikely(sent < i)) {
- sent = sent < 0 ? 0 : sent;
- odp_packet_free_multi(&tbl[sent], i - sent);
- arg->tx_drops += i - sent;
- }
+ output_queues[i] = global.l3fwd_pktios[i].ifout[txq_idx];
- if (i < pkts)
- tbl += i;
+ if_idx = thr_arg->pktio[i].if_idx;
+ for (j = 0; j < thr_arg->pktio[i].nb_rxq; j++) {
+ int rxq_idx = thr_arg->pktio[i].rxq[j];
- pkts -= i;
+ inq = global.l3fwd_pktios[if_idx].ifin[rxq_idx];
+ input_ifs[num_pktio] = if_idx;
+ input_queues[num_pktio] = inq;
+ num_pktio++;
+ }
}
-}
-static int run_worker(void *arg)
-{
- int if_idx, rxq, nb_rxq;
- struct thread_arg_s *thr_arg = arg;
+ if (num_pktio == 0)
+ LOG_ABORT("No pktio devices found\n");
+
+ if_idx = input_ifs[pktio];
+ inq = input_queues[pktio];
odp_barrier_wait(&barrier);
while (!exit_threads) {
- for (if_idx = 0; if_idx < thr_arg->nb_pktio; if_idx++) {
- nb_rxq = thr_arg->pktio[if_idx].nb_rxq;
- if (!nb_rxq || thr_arg->thr_idx == INVALID_ID)
- continue;
-
- for (rxq = 0; rxq < nb_rxq; rxq++) {
- int rxq_idx;
+ if (num_pktio > 1) {
+ if_idx = input_ifs[pktio];
+ inq = input_queues[pktio];
+ pktio++;
+ if (pktio == num_pktio)
+ pktio = 0;
+ }
- rxq_idx = thr_arg->pktio[if_idx].rxq[rxq];
- l3fwd_one_queue(if_idx, rxq_idx, arg);
+ pkts = odp_pktin_recv(inq, pkt_tbl, MAX_PKT_BURST);
+ if (pkts < 1)
+ continue;
+
+ thr_arg->packets += pkts;
+ drop = drop_err_pkts(pkt_tbl, pkts);
+ pkts -= drop;
+ thr_arg->rx_drops += drop;
+ if (odp_unlikely(pkts < 1))
+ continue;
+
+ dif = global.fwd_func(pkt_tbl[0], if_idx);
+ tbl = &pkt_tbl[0];
+ while (pkts) {
+ dst_port = dif;
+ for (i = 1; i < pkts; i++) {
+ dif = global.fwd_func(tbl[i], if_idx);
+ if (dif != dst_port)
+ break;
+ }
+ sent = odp_pktout_send(output_queues[dst_port], tbl, i);
+ if (odp_unlikely(sent < i)) {
+ sent = sent < 0 ? 0 : sent;
+ odp_packet_free_multi(&tbl[sent], i - sent);
+ thr_arg->tx_drops += i - sent;
}
+
+ if (i < pkts)
+ tbl += i;
+
+ pkts -= i;
}
}
@@ -461,6 +491,8 @@ static void print_usage(char *progname)
" -q, --queue Configure rx queue(s) for port\n"
" optional, format: [(port, queue, thread),...]\n"
" for example: -q '(0, 0, 1),(1,0,2)'\n"
+ " -e, --error_check 0: Don't check packet errors (default)\n"
+ " 1: Check packet errors\n"
" -h, --help Display help and exit.\n\n"
"\n", NO_PATH(progname), NO_PATH(progname)
);
@@ -477,16 +509,17 @@ static void parse_cmdline_args(int argc, char *argv[], app_args_t *args)
static struct option longopts[] = {
{"interface", required_argument, NULL, 'i'}, /* return 'i' */
{"route", required_argument, NULL, 'r'}, /* return 'r' */
- {"style", optional_argument, NULL, 's'}, /* return 's' */
- {"duration", optional_argument, NULL, 'd'}, /* return 'd' */
- {"thread", optional_argument, NULL, 't'}, /* return 't' */
- {"queue", optional_argument, NULL, 'q'}, /* return 'q' */
+ {"style", required_argument, NULL, 's'}, /* return 's' */
+ {"duration", required_argument, NULL, 'd'}, /* return 'd' */
+ {"thread", required_argument, NULL, 't'}, /* return 't' */
+ {"queue", required_argument, NULL, 'q'}, /* return 'q' */
+ {"error_check", required_argument, NULL, 'e'},
{"help", no_argument, NULL, 'h'}, /* return 'h' */
{NULL, 0, NULL, 0}
};
while (1) {
- opt = getopt_long(argc, argv, "+s:t:d:i:r:q:h",
+ opt = getopt_long(argc, argv, "+s:t:d:i:r:q:e:h",
longopts, &long_index);
if (opt == -1)
@@ -571,6 +604,10 @@ static void parse_cmdline_args(int argc, char *argv[], app_args_t *args)
args->route_str[route_index++] = local;
break;
+ case 'e':
+ args->error_check = atoi(optarg);
+ break;
+
case 'h':
print_usage(argv[0]);
exit(EXIT_SUCCESS);
@@ -651,7 +688,7 @@ static void print_info(char *progname, app_args_t *args)
*/
static void setup_worker_qconf(app_args_t *args)
{
- int nb_worker, if_count;
+ int nb_worker, if_count, pktio;
int i, j, rxq_idx;
struct thread_arg_s *arg;
struct l3fwd_pktio_s *port;
@@ -668,10 +705,11 @@ static void setup_worker_qconf(app_args_t *args)
arg->thr_idx = i;
j = i % if_count;
port = &global.l3fwd_pktios[j];
- rxq_idx = arg->pktio[j].nb_rxq;
- arg->pktio[j].rxq[rxq_idx] =
+ arg->pktio[0].rxq[0] =
port->rxq_idx % port->nb_rxq;
- arg->pktio[j].nb_rxq++;
+ arg->pktio[0].nb_rxq = 1;
+ arg->pktio[0].if_idx = j;
+ arg->nb_pktio = 1;
port->rxq_idx++;
}
} else {
@@ -681,9 +719,12 @@ static void setup_worker_qconf(app_args_t *args)
arg->thr_idx = j;
port = &global.l3fwd_pktios[i];
rxq_idx = arg->pktio[i].nb_rxq;
- arg->pktio[i].rxq[rxq_idx] =
+ pktio = arg->nb_pktio;
+ arg->pktio[pktio].rxq[rxq_idx] =
port->rxq_idx % port->nb_rxq;
- arg->pktio[i].nb_rxq++;
+ arg->pktio[pktio].nb_rxq++;
+ arg->pktio[pktio].if_idx = i;
+ arg->nb_pktio++;
port->rxq_idx++;
}
}
@@ -723,12 +764,21 @@ static void setup_worker_qconf(app_args_t *args)
/* put the queue into worker_args */
arg = &global.worker_args[q->core_idx];
- rxq_idx = arg->pktio[q->if_idx].nb_rxq;
- arg->pktio[q->if_idx].rxq[rxq_idx] = q->rxq_idx;
- arg->pktio[q->if_idx].nb_rxq++;
+
+ /* Check if interface already has queues configured */
+ for (j = 0; j < args->if_count; j++) {
+ if (arg->pktio[j].if_idx == q->if_idx)
+ break;
+ }
+ if (j == args->if_count)
+ j = arg->nb_pktio++;
+
+ rxq_idx = arg->pktio[j].nb_rxq;
+ arg->pktio[j].rxq[rxq_idx] = q->rxq_idx;
+ arg->pktio[j].nb_rxq++;
+ arg->pktio[j].if_idx = q->if_idx;
arg->thr_idx = q->core_idx;
}
-
/* distribute tx queues among threads */
for (i = 0; i < args->worker_count; i++) {
arg = &global.worker_args[i];
@@ -797,7 +847,7 @@ static void setup_worker_qconf(app_args_t *args)
static void print_qconf_table(app_args_t *args)
{
- int i, j, k, qid;
+ int i, j, k, qid, if_idx;
char buf[32];
struct thread_arg_s *thr_arg;
@@ -812,7 +862,9 @@ static void print_qconf_table(app_args_t *args)
if (!thr_arg->pktio[j].nb_rxq)
continue;
- snprintf(buf, 32, "%s/%d", args->if_names[j], j);
+ if_idx = thr_arg->pktio[j].if_idx;
+ snprintf(buf, 32, "%s/%d", args->if_names[if_idx],
+ if_idx);
for (k = 0; k < MAX_NB_QUEUE; k++) {
qid = thr_arg->pktio[j].rxq[k];
if (qid != INVALID_ID)
@@ -924,6 +976,7 @@ int main(int argc, char **argv)
for (j = 0; j < MAX_NB_PKTIO; j++) {
thr_arg->thr_idx = INVALID_ID;
thr_arg->pktio[j].txq_idx = INVALID_ID;
+ thr_arg->pktio[j].if_idx = INVALID_ID;
memset(thr_arg->pktio[j].rxq, INVALID_ID,
sizeof(thr_arg->pktio[j].rxq));
}
@@ -1045,7 +1098,6 @@ int main(int argc, char **argv)
odp_cpumask_t thr_mask;
arg = &global.worker_args[i];
- arg->nb_pktio = args->if_count;
odp_cpumask_zero(&thr_mask);
odp_cpumask_set(&thr_mask, cpu);
thr_params.arg = arg;