@@ -25,11 +25,25 @@ static const char * const route_str[] = {
"2.1.1.0/24:fm1-mac2:00.e0.0c.00.85.01",
};
+#define MAX_NB_WORKER 8
+#define MAX_NB_PKTIO 4
+
+struct l3fwd_pktio_s {
+ odp_pktio_t pktio;
+ odp_pktin_queue_t ifin;
+ odp_pktout_queue_t ifout;
+};
+
+struct thread_arg_s {
+ uint32_t if_idx;
+};
+
struct {
- odp_pktio_t if0, if1;
- odp_pktin_queue_t if0in, if1in;
- odp_pktout_queue_t if0out, if1out;
- odph_ethaddr_t src, dst;
+ struct l3fwd_pktio_s l3fwd_pktios[MAX_NB_PKTIO];
+ odph_linux_pthread_t l3fwd_workers[MAX_NB_WORKER];
+ struct thread_arg_s worker_args[MAX_NB_WORKER];
+ uint32_t nb_pktio; /* effective pktios */
+ uint32_t nb_worker; /* effective workers */
} global;
static odp_pktio_t create_pktio(const char *name, odp_pool_t pool,
@@ -77,30 +91,28 @@ static odp_pktio_t create_pktio(const char *name, odp_pool_t pool,
return pktio;
}
-static void *run_worker(void *arg ODP_UNUSED)
+static void *run_worker(void *arg)
{
odp_packet_t pkt_tbl[MAX_PKT_BURST];
odp_packet_t pkt_tbl_drop[MAX_PKT_BURST];
- int pkts, i;
+ uint32_t pkts, i;
+ struct l3fwd_pktio_s *port;
- if (odp_pktio_start(global.if0)) {
- printf("unable to start input interface\n");
- exit(1);
- }
- printf("started input interface\n");
- if (odp_pktio_start(global.if1)) {
- printf("unable to start output interface\n");
+ i = ((struct thread_arg_s *)arg)->if_idx;
+ port = &global.l3fwd_pktios[i];
+
+ if (odp_pktio_start(port->pktio)) {
+ printf("unable to start interface: %d\n", i);
exit(1);
}
- printf("started output interface\n");
- printf("started all\n");
+ printf("start interface: %d\n", i);
for (;;) {
int need_to_drop = 0;
memset(pkt_tbl, 0, sizeof(pkt_tbl_drop));
- pkts = odp_pktin_recv(global.if0in, pkt_tbl, MAX_PKT_BURST);
+ pkts = odp_pktin_recv(port->ifin, pkt_tbl, MAX_PKT_BURST);
if (odp_unlikely(pkts <= 0))
continue;
for (i = 0; i < pkts; i++) {
@@ -164,10 +176,9 @@ int main(int argc, char **argv)
odp_pool_t pool;
odp_pool_param_t params;
odp_cpumask_t cpumask;
- odph_linux_pthread_t thd;
odp_instance_t instance;
odph_linux_thr_params_t thr_params;
- size_t i;
+ uint32_t cpu, i;
uint8_t mac[ODPH_ETHADDR_LEN];
if (argc != 3) {
@@ -187,6 +198,9 @@ int main(int argc, char **argv)
exit(1);
}
+ /* Clear global argument */
+ memset(&global, 0, sizeof(global));
+
/* Init l3fwd tale */
init_fwd_db();
@@ -212,24 +226,41 @@ int main(int argc, char **argv)
exit(1);
}
- global.if0 = create_pktio(argv[1], pool, &global.if0in, &global.if0out);
- global.if1 = create_pktio(argv[2], pool, &global.if1in, &global.if1out);
-
- /* resolve route table */
- odp_pktio_mac_addr(global.if0, mac, ODPH_ETHADDR_LEN);
- resolve_fwd_db(argv[1], global.if0, mac);
- odp_pktio_mac_addr(global.if1, mac, ODPH_ETHADDR_LEN);
- resolve_fwd_db(argv[2], global.if1, mac);
-
- odp_cpumask_default_worker(&cpumask, 1);
+ /* TODO: parse cmdline to get pktio number, name */
+ global.nb_pktio = 2;
+ for (i = 0; i < global.nb_pktio; i++) {
+ struct l3fwd_pktio_s *port;
+ char *ifname = argv[i + 1];
+
+ port = &global.l3fwd_pktios[i];
+ port->pktio = create_pktio(ifname, pool, &port->ifin,
+ &port->ifout);
+ odp_pktio_mac_addr(port->pktio, mac, ODPH_ETHADDR_LEN);
+ resolve_fwd_db(ifname, port->pktio, mac);
+ }
+ global.nb_worker = 2;
memset(&thr_params, 0, sizeof(thr_params));
thr_params.start = run_worker;
- thr_params.arg = NULL;
thr_params.thr_type = ODP_THREAD_WORKER;
thr_params.instance = instance;
- odph_linux_pthread_create(&thd, &cpumask, &thr_params);
- odph_linux_pthread_join(&thd, 1);
+ odp_cpumask_default_worker(&cpumask, global.nb_worker);
+ cpu = odp_cpumask_first(&cpumask);
+ for (i = 0; i < global.nb_worker; i++) {
+ struct thread_arg_s *arg;
+ odp_cpumask_t thr_mask;
+
+ odp_cpumask_zero(&thr_mask);
+ odp_cpumask_set(&thr_mask, cpu);
+ arg = &global.worker_args[i];
+ arg->if_idx = i;
+ thr_params.arg = arg;
+ odph_linux_pthread_create(&global.l3fwd_workers[i], &thr_mask,
+ &thr_params);
+ cpu = odp_cpumask_next(&cpumask, cpu);
+ }
+ odph_linux_pthread_join(&global.l3fwd_workers[0], global.nb_worker);
+
return 0;
}