static odp_pktio_t create_pktio(int iface_idx, odp_pktio_input_mode_t imode, odp_pktio_output_mode_t omode) { odp_pktio_t pktio; odp_pktio_param_t pktio_param; const char *iface = iface_name[iface_idx]; odp_pktio_param_init(&pktio_param); pktio_param.in_mode = imode; pktio_param.out_mode = omode; pktio = odp_pktio_open(iface, pool[iface_idx], &pktio_param); if (pktio == ODP_PKTIO_INVALID) pktio = odp_pktio_lookup(iface); CU_ASSERT(pktio != ODP_PKTIO_INVALID); CU_ASSERT(odp_pktio_to_u64(pktio) != odp_pktio_to_u64(ODP_PKTIO_INVALID)); /* Print pktio debug info and test that the odp_pktio_print() function * is implemented. */ if (pktio != ODP_PKTIO_INVALID) odp_pktio_print(pktio); if (wait_for_network) spin_wait(ODP_TIME_SEC_IN_NS / 4); return pktio; }
/** * Create a pktio handle, optionally associating a default input queue. * * @param dev Name of device to open * @param pool Pool to associate with device for packet RX/TX * * @return The handle of the created pktio object. * @retval ODP_PKTIO_INVALID if the create fails. */ static odp_pktio_t create_pktio(const char *dev, odp_pool_t pool) { char inq_name[ODP_QUEUE_NAME_LEN]; odp_queue_param_t qparam; odp_queue_t inq_def; odp_pktio_t pktio; int ret; odp_pktio_param_t pktio_param; odp_schedule_sync_t sync_mode; odp_pktio_param_init(&pktio_param); if (gbl_args->appl.mode == DIRECT_RECV) pktio_param.in_mode = ODP_PKTIN_MODE_RECV; else pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; pktio = odp_pktio_open(dev, pool, &pktio_param); if (pktio == ODP_PKTIO_INVALID) { LOG_ERR("Error: failed to open %s\n", dev); return ODP_PKTIO_INVALID; } printf("created pktio %" PRIu64 " (%s)\n", odp_pktio_to_u64(pktio), dev); /* no further setup needed for direct receive mode */ if (gbl_args->appl.mode == DIRECT_RECV) return pktio; if (gbl_args->appl.mode == SCHED_ATOMIC) sync_mode = ODP_SCHED_SYNC_ATOMIC; else if (gbl_args->appl.mode == SCHED_ORDERED) sync_mode = ODP_SCHED_SYNC_ORDERED; else sync_mode = ODP_SCHED_SYNC_NONE; odp_queue_param_init(&qparam); qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; qparam.sched.sync = sync_mode; qparam.sched.group = ODP_SCHED_GROUP_ALL; snprintf(inq_name, sizeof(inq_name), "%" PRIu64 "-pktio_inq_def", odp_pktio_to_u64(pktio)); inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0'; inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN, &qparam); if (inq_def == ODP_QUEUE_INVALID) { LOG_ERR("Error: pktio queue creation failed\n"); return ODP_PKTIO_INVALID; } ret = odp_pktio_inq_setdef(pktio, inq_def); if (ret != 0) { LOG_ERR("Error: default input-Q setup\n"); return ODP_PKTIO_INVALID; } return pktio; }
/** * Create a pktio object * * @param dev Name of device to open * @param pool Pool to associate with device for packet RX/TX * * @return The handle of the created pktio object. * @warning This routine aborts if the create is unsuccessful. */ static odp_pktio_t create_pktio(const char *dev, odp_pool_t pool) { odp_queue_param_t qparam; char inq_name[ODP_QUEUE_NAME_LEN]; odp_pktio_t pktio; int ret; odp_queue_t inq_def; odp_pktio_param_t pktio_param; odp_pktio_param_init(&pktio_param); pktio_param.in_mode = ODP_PKTIN_MODE_DISABLED; /* Open a packet IO instance */ pktio = odp_pktio_open(dev, pool, &pktio_param); if (pktio == ODP_PKTIO_INVALID) EXAMPLE_ABORT("Error: pktio create failed for %s\n", dev); /* * Create and set the default INPUT queue associated with the 'pktio' * resource */ odp_queue_param_init(&qparam); qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC; qparam.sched.group = ODP_SCHED_GROUP_ALL; snprintf(inq_name, sizeof(inq_name), "%" PRIu64 "-pktio_inq_def", odp_pktio_to_u64(pktio)); inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0'; inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN, &qparam); if (inq_def == ODP_QUEUE_INVALID) EXAMPLE_ABORT("Error: pktio inq create failed for %s\n", dev); ret = odp_pktio_inq_setdef(pktio, inq_def); if (ret != 0) EXAMPLE_ABORT("Error: default input-Q setup for %s\n", dev); ret = odp_pktio_start(pktio); if (ret) EXAMPLE_ABORT("Error: unable to start %s\n", dev); printf(" created pktio:%02" PRIu64 ", dev:%s, queue mode (ATOMIC queues)\n" " default pktio%02" PRIu64 "-INPUT queue:%" PRIu64 "\n", odp_pktio_to_u64(pktio), dev, odp_pktio_to_u64(pktio), odp_queue_to_u64(inq_def)); return pktio; }
void pktio_test_open(void) { odp_pktio_t pktio; odp_pktio_param_t pktio_param; int i; /* test the sequence open->close->open->close() */ for (i = 0; i < 2; ++i) { pktio = create_pktio(0, ODP_PKTIN_MODE_SCHED, ODP_PKTOUT_MODE_SEND); CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); CU_ASSERT(odp_pktio_close(pktio) == 0); } odp_pktio_param_init(&pktio_param); pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; pktio = odp_pktio_open("nothere", default_pkt_pool, &pktio_param); CU_ASSERT(pktio == ODP_PKTIO_INVALID); }
void pktio_test_lookup(void) { odp_pktio_t pktio, pktio_inval; odp_pktio_param_t pktio_param; odp_pktio_param_init(&pktio_param); pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; pktio = odp_pktio_open(iface_name[0], default_pkt_pool, &pktio_param); CU_ASSERT(pktio != ODP_PKTIO_INVALID); CU_ASSERT(odp_pktio_lookup(iface_name[0]) == pktio); pktio_inval = odp_pktio_open(iface_name[0], default_pkt_pool, &pktio_param); CU_ASSERT(odp_errno() != 0); CU_ASSERT(pktio_inval == ODP_PKTIO_INVALID); CU_ASSERT(odp_pktio_close(pktio) == 0); CU_ASSERT(odp_pktio_lookup(iface_name[0]) == ODP_PKTIO_INVALID); }
/** * Initialize interface * * Initialize ODP pktio and queues, query MAC address and update * forwarding database. * * @param intf Interface name string */ static void initialize_intf(char *intf) { odp_pktio_t pktio; odp_pktout_queue_t pktout; odp_queue_t inq; int ret; uint8_t src_mac[ODPH_ETHADDR_LEN]; char src_mac_str[MAX_STRING]; odp_pktio_param_t pktio_param; odp_pktin_queue_param_t pktin_param; odp_pktio_param_init(&pktio_param); if (getenv("ODP_IPSEC_USE_POLL_QUEUES")) pktio_param.in_mode = ODP_PKTIN_MODE_QUEUE; else pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; /* * Open a packet IO instance for thread and get default output queue */ pktio = odp_pktio_open(intf, pkt_pool, &pktio_param); if (ODP_PKTIO_INVALID == pktio) { EXAMPLE_ERR("Error: pktio create failed for %s\n", intf); exit(EXIT_FAILURE); } odp_pktin_queue_param_init(&pktin_param); pktin_param.queue_param.sched.sync = ODP_SCHED_SYNC_ATOMIC; if (odp_pktin_queue_config(pktio, &pktin_param)) { EXAMPLE_ERR("Error: pktin config failed for %s\n", intf); exit(EXIT_FAILURE); } if (odp_pktout_queue_config(pktio, NULL)) { EXAMPLE_ERR("Error: pktout config failed for %s\n", intf); exit(EXIT_FAILURE); } if (odp_pktin_event_queue(pktio, &inq, 1) != 1) { EXAMPLE_ERR("Error: failed to get input queue for %s\n", intf); exit(EXIT_FAILURE); } if (odp_pktout_queue(pktio, &pktout, 1) != 1) { EXAMPLE_ERR("Error: failed to get pktout queue for %s\n", intf); exit(EXIT_FAILURE); } ret = odp_pktio_start(pktio); if (ret) { EXAMPLE_ERR("Error: unable to start %s\n", intf); exit(EXIT_FAILURE); } /* Read the source MAC address for this interface */ ret = odp_pktio_mac_addr(pktio, src_mac, sizeof(src_mac)); if (ret <= 0) { EXAMPLE_ERR("Error: failed during MAC address get for %s\n", intf); exit(EXIT_FAILURE); } printf("Created pktio:%02" PRIu64 ", queue mode (ATOMIC queues)\n" " default pktio%02" PRIu64 "-INPUT queue:%" PRIu64 "\n" " source mac address %s\n", odp_pktio_to_u64(pktio), odp_pktio_to_u64(pktio), odp_queue_to_u64(inq), mac_addr_str(src_mac_str, src_mac)); /* Resolve any routes using this interface for output */ resolve_fwd_db(intf, pktout, src_mac); }
/** * Initialize interface * * Initialize ODP pktio and queues, query MAC address and update * forwarding database. * * @param intf Interface name string */ static void initialize_intf(char *intf) { odp_pktio_t pktio; odp_queue_t outq_def; odp_queue_t inq_def; char inq_name[ODP_QUEUE_NAME_LEN]; odp_queue_param_t qparam; int ret; uint8_t src_mac[ODPH_ETHADDR_LEN]; char src_mac_str[MAX_STRING]; odp_pktio_param_t pktio_param; odp_pktio_param_init(&pktio_param); if (getenv("ODP_IPSEC_USE_POLL_QUEUES")) pktio_param.in_mode = ODP_PKTIN_MODE_QUEUE; else pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; /* * Open a packet IO instance for thread and get default output queue */ pktio = odp_pktio_open(intf, pkt_pool, &pktio_param); if (ODP_PKTIO_INVALID == pktio) { EXAMPLE_ERR("Error: pktio create failed for %s\n", intf); exit(EXIT_FAILURE); } outq_def = odp_pktio_outq_getdef(pktio); /* * Create and set the default INPUT queue associated with the 'pktio' * resource */ odp_queue_param_init(&qparam); qparam.type = ODP_QUEUE_TYPE_PKTIN; qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC; qparam.sched.group = ODP_SCHED_GROUP_ALL; snprintf(inq_name, sizeof(inq_name), "%" PRIu64 "-pktio_inq_def", odp_pktio_to_u64(pktio)); inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0'; inq_def = queue_create(inq_name, &qparam); if (ODP_QUEUE_INVALID == inq_def) { EXAMPLE_ERR("Error: pktio queue creation failed for %s\n", intf); exit(EXIT_FAILURE); } ret = odp_pktio_inq_setdef(pktio, inq_def); if (ret) { EXAMPLE_ERR("Error: default input-Q setup for %s\n", intf); exit(EXIT_FAILURE); } ret = odp_pktio_start(pktio); if (ret) { EXAMPLE_ERR("Error: unable to start %s\n", intf); exit(EXIT_FAILURE); } /* Read the source MAC address for this interface */ ret = odp_pktio_mac_addr(pktio, src_mac, sizeof(src_mac)); if (ret <= 0) { EXAMPLE_ERR("Error: failed during MAC address get for %s\n", intf); exit(EXIT_FAILURE); } printf("Created pktio:%02" PRIu64 ", queue mode (ATOMIC queues)\n" " default pktio%02" PRIu64 "-INPUT queue:%" PRIu64 "\n" " source mac address %s\n", odp_pktio_to_u64(pktio), odp_pktio_to_u64(pktio), odp_queue_to_u64(inq_def), mac_addr_str(src_mac_str, src_mac)); /* Resolve any routes using this interface for output */ resolve_fwd_db(intf, outq_def, src_mac); }
static int run_test(void) { int ret; int i; odp_cpumask_t txmask, rxmask; test_status_t status = { .pps_curr = gbl_args->args.pps, .pps_pass = 0, .pps_fail = 0, .warmup = 1, }; ret = setup_txrx_masks(&txmask, &rxmask); if (ret) return ret; printf("Starting test with params:\n"); printf("\tTransmit workers: \t%d\n", odp_cpumask_count(&txmask)); printf("\tReceive workers: \t%d\n", odp_cpumask_count(&rxmask)); printf("\tDuration (seconds): \t%d\n", gbl_args->args.duration); printf("\tTransmit batch length:\t%" PRIu32 "\n", gbl_args->args.tx_batch_len); printf("\tReceive batch length: \t%" PRIu32 "\n", gbl_args->args.rx_batch_len); printf("\tPacket receive method:\t%s\n", gbl_args->args.schedule ? "schedule" : "plain"); printf("\tInterface(s): \t"); for (i = 0; i < gbl_args->args.num_ifaces; ++i) printf("%s ", gbl_args->args.ifaces[i]); printf("\n"); /* first time just run the test but throw away the results */ run_test_single(&txmask, &rxmask, &status); status.warmup = 0; while (1) { ret = run_test_single(&txmask, &rxmask, &status); if (ret <= 0) break; } return ret; } static odp_pktio_t create_pktio(const char *iface, int schedule) { odp_pool_t pool; odp_pktio_t pktio; char pool_name[ODP_POOL_NAME_LEN]; odp_pool_param_t params; odp_pktio_param_t pktio_param; odp_pool_param_init(¶ms); params.pkt.len = PKT_HDR_LEN + gbl_args->args.pkt_len; params.pkt.seg_len = params.pkt.len; params.pkt.num = PKT_BUF_NUM; params.type = ODP_POOL_PACKET; snprintf(pool_name, sizeof(pool_name), "pkt_pool_%s", iface); pool = odp_pool_create(pool_name, ¶ms); if (pool == ODP_POOL_INVALID) return ODP_PKTIO_INVALID; odp_pktio_param_init(&pktio_param); if (schedule) pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; else pktio_param.in_mode = ODP_PKTIN_MODE_QUEUE; pktio = odp_pktio_open(iface, pool, &pktio_param); return pktio; }
/** * Create a pktio handle * * @param dev Name of device to open * @param index Pktio index * @param num_rx Number of RX queues * @param num_tx Number of TX queues * @param pool Pool to associate with device for packet RX/TX * * @retval 0 on success * @retval -1 on failure */ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, odp_pool_t pool) { odp_pktio_t pktio; odp_pktio_param_t pktio_param; odp_pktio_capability_t capa; odp_pktin_queue_param_t pktin_param; odp_pktout_queue_param_t pktout_param; odp_pktio_op_mode_t mode_rx; odp_pktio_op_mode_t mode_tx; odp_pktio_param_init(&pktio_param); pktio = odp_pktio_open(dev, pool, &pktio_param); if (pktio == ODP_PKTIO_INVALID) { printf("Error: failed to open %s\n", dev); return -1; } printf("created pktio %" PRIu64 " (%s)\n", odp_pktio_to_u64(pktio), dev); if (odp_pktio_capability(pktio, &capa)) { printf("Error: capability query failed %s\n", dev); return -1; } odp_pktin_queue_param_init(&pktin_param); odp_pktout_queue_param_init(&pktout_param); mode_tx = ODP_PKTIO_OP_MT_UNSAFE; mode_rx = ODP_PKTIO_OP_MT_UNSAFE; if (num_rx > (int)capa.max_input_queues) { printf("Sharing %i input queues between %i workers\n", capa.max_input_queues, num_rx); num_rx = capa.max_input_queues; mode_rx = ODP_PKTIO_OP_MT; } if (num_tx > (int)capa.max_output_queues) { printf("Sharing %i output queues between %i workers\n", capa.max_output_queues, num_tx); num_tx = capa.max_output_queues; mode_tx = ODP_PKTIO_OP_MT; } pktin_param.hash_enable = 1; pktin_param.hash_proto.proto.ipv4 = 1; pktin_param.hash_proto.proto.ipv4_tcp = 1; pktin_param.hash_proto.proto.ipv4_udp = 1; pktin_param.num_queues = num_rx; pktin_param.op_mode = mode_rx; pktout_param.op_mode = mode_tx; pktout_param.num_queues = num_tx; if (odp_pktin_queue_config(pktio, &pktin_param)) { printf("Error: input queue config failed %s\n", dev); return -1; } if (odp_pktout_queue_config(pktio, &pktout_param)) { printf("Error: output queue config failed %s\n", dev); return -1; } if (odp_pktin_queue(pktio, gbl_args->pktios[idx].pktin, num_rx) != num_rx) { printf("Error: pktin queue query failed %s\n", dev); return -1; } if (odp_pktout_queue(pktio, gbl_args->pktios[idx].pktout, num_tx) != num_tx) { printf("Error: pktout queue query failed %s\n", dev); return -1; } printf("created %i input and %i output queues on (%s)\n", num_rx, num_tx, dev); gbl_args->pktios[idx].num_rx_queue = num_rx; gbl_args->pktios[idx].num_tx_queue = num_tx; gbl_args->pktios[idx].pktio = pktio; return 0; }
/** main() Application entry point * * @param argc int * @param argv[] char* * @return int * */ int main(int argc, char *argv[]) { odph_linux_pthread_t thread_tbl[MAX_WORKERS], dispatcher_thread; appl_args_t params; int core_count, num_workers; odp_cpumask_t cpu_mask; int first_cpu, i; struct pktio_thr_arg pktio_thr_args[MAX_WORKERS]; odp_pktio_param_t pktio_param; odp_pktin_queue_param_t pktin_param; odp_pktout_queue_param_t pktout_param; odp_pktio_t pktio; int port, queue_id; odph_linux_thr_params_t thr_params; odp_instance_t instance; struct pktin_table_s { int num_in_queue; odp_pktin_queue_t in_queue[OFP_PKTIN_QUEUE_MAX]; } pktin_table[OFP_FP_INTERFACE_MAX]; /* Parse and store the application arguments */ parse_args(argc, argv, ¶ms); if (params.if_count > OFP_FP_INTERFACE_MAX) { printf("Error: Invalid number of interfaces: maximum %d\n", OFP_FP_INTERFACE_MAX); exit(EXIT_FAILURE); } if (odp_init_global(&instance, NULL, NULL)) { OFP_ERR("Error: ODP global init failed.\n"); exit(EXIT_FAILURE); } if (odp_init_local(instance, ODP_THREAD_CONTROL)) { OFP_ERR("Error: ODP local init failed.\n"); exit(EXIT_FAILURE); } /* Print both system and application information */ print_info(NO_PATH(argv[0]), ¶ms); core_count = odp_cpu_count(); num_workers = core_count; if (params.core_count && params.core_count < core_count) num_workers = params.core_count; if (num_workers > MAX_WORKERS) num_workers = MAX_WORKERS; /* * By default core #0 runs Linux kernel background tasks. * Start mapping thread from core #1 */ if (num_workers > 1) { num_workers--; first_cpu = 1; } else { OFP_ERR("Burst mode requires multiple cores.\n"); exit(EXIT_FAILURE); } if (num_workers < params.if_count) { OFP_ERR("At least %u fastpath cores required.\n", params.if_count); exit(EXIT_FAILURE); } printf("Num worker threads: %i\n", num_workers); printf("first CPU: %i\n", first_cpu); memset(&app_init_params, 0, sizeof(app_init_params)); app_init_params.linux_core_id = 0; if (ofp_init_global(instance, &app_init_params)) { OFP_ERR("Error: OFP global init failed.\n"); exit(EXIT_FAILURE); } if (ofp_init_local()) { OFP_ERR("Error: OFP local init failed.\n"); exit(EXIT_FAILURE); } odp_pktio_param_init(&pktio_param); pktio_param.in_mode = ODP_PKTIN_MODE_DIRECT; pktio_param.out_mode = ODP_PKTOUT_MODE_DIRECT; odp_pktin_queue_param_init(&pktin_param); pktin_param.op_mode = ODP_PKTIO_OP_MT; pktin_param.hash_enable = 0; pktin_param.hash_proto.all_bits = 0; pktin_param.num_queues = 1; odp_pktout_queue_param_init(&pktout_param); pktout_param.num_queues = 1; pktout_param.op_mode = ODP_PKTIO_OP_MT; for (i = 0; i < params.if_count; i++) { if (ofp_ifnet_create(instance, params.if_names[i], &pktio_param, &pktin_param, &pktout_param) < 0) { OFP_ERR("Failed to init interface %s", params.if_names[i]); exit(EXIT_FAILURE); } pktio = odp_pktio_lookup(params.if_names[i]); if (pktio == ODP_PKTIO_INVALID) { OFP_ERR("Failed locate pktio %s", params.if_names[i]); exit(EXIT_FAILURE); } pktin_table[i].num_in_queue = odp_pktin_queue(pktio, pktin_table[i].in_queue, OFP_PKTIN_QUEUE_MAX); if (pktin_table[i].num_in_queue < 0) { OFP_ERR("Failed get input queues for %s", params.if_names[i]); exit(EXIT_FAILURE); } } memset(thread_tbl, 0, sizeof(thread_tbl)); memset(pktio_thr_args, 0, sizeof(pktio_thr_args)); for (i = 0; i < num_workers; ++i) { pktio_thr_args[i].pkt_func = ofp_eth_vlan_processing; port = i % params.if_count; queue_id = (i / params.if_count) % pktin_table[port].num_in_queue; pktio_thr_args[i].pktin = pktin_table[port].in_queue[queue_id]; odp_cpumask_zero(&cpu_mask); odp_cpumask_set(&cpu_mask, first_cpu + i); thr_params.start = pkt_io_recv; thr_params.arg = &pktio_thr_args[i]; thr_params.thr_type = ODP_THREAD_WORKER; thr_params.instance = instance; odph_linux_pthread_create(&thread_tbl[i], &cpu_mask, &thr_params); } odp_cpumask_zero(&cpu_mask); odp_cpumask_set(&cpu_mask, app_init_params.linux_core_id); thr_params.start = event_dispatcher; thr_params.arg = NULL; thr_params.thr_type = ODP_THREAD_WORKER; thr_params.instance = instance; odph_linux_pthread_create(&dispatcher_thread, &cpu_mask, &thr_params); /* Start CLI */ ofp_start_cli_thread(instance, app_init_params.linux_core_id, params.conf_file); odph_linux_pthread_join(thread_tbl, num_workers); printf("End Main()\n"); return 0; }