Example #1
0
/**
 * 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;
}
Example #2
0
static int ipc_second_process(void)
{
	odp_pktio_t ipc_pktio;
	odp_pool_param_t params;
	odp_pool_t pool;
	odp_packet_t pkt_tbl[MAX_PKT_BURST];
	odp_packet_t alloc_pkt;
	int pkts;
	int ret;
	int i;
	odp_time_t start_cycle;
	odp_time_t cycle;
	odp_time_t diff;
	odp_time_t wait;
	uint64_t stat_pkts = 0;
	odp_pktin_queue_t pktin;

	/* Create packet pool */
	memset(&params, 0, sizeof(params));
	params.pkt.seg_len = SHM_PKT_POOL_BUF_SIZE;
	params.pkt.len     = SHM_PKT_POOL_BUF_SIZE;
	params.pkt.num     = SHM_PKT_POOL_SIZE;
	params.type        = ODP_POOL_PACKET;

	pool = odp_pool_create("packet_pool2", &params);
	if (pool == ODP_POOL_INVALID) {
		EXAMPLE_ERR("Error: packet pool create failed.\n");
		exit(EXIT_FAILURE);
	}

	ipc_pktio = create_pktio(pool);

	wait = odp_time_local_from_ns(run_time_sec * ODP_TIME_SEC_IN_NS);
	start_cycle = odp_time_local();

	if (odp_pktin_queue(ipc_pktio, &pktin, 1) != 1) {
		EXAMPLE_ERR("no input queue\n");
		return -1;
	}

	/* start ipc pktio, i.e. wait until other process connects */
	for (;;) {
		/* 1. exit loop if time specified */
		if (run_time_sec) {
			cycle = odp_time_local();
			diff = odp_time_diff(cycle, start_cycle);
			if (odp_time_cmp(wait, diff) < 0) {
				printf("timeout exit, run_time_sec %d\n",
				       run_time_sec);
				goto not_started;
			}
		}

		ret = odp_pktio_start(ipc_pktio);
		if (!ret)
			break;
	}

	for (;;) {
		/* exit loop if time specified */
		if (run_time_sec) {
			cycle = odp_time_local();
			diff = odp_time_diff(cycle, start_cycle);
			if (odp_time_cmp(wait, diff) < 0) {
				EXAMPLE_DBG("exit after %d seconds\n",
					    run_time_sec);
				break;
			}
		}

		/* recv some packets and change MAGIC to MAGIC_2 */
		pkts = odp_pktin_recv(pktin, pkt_tbl, MAX_PKT_BURST);
		if (pkts <= 0)
			continue;

		for (i = 0; i < pkts; i++) {
			odp_packet_t pkt = pkt_tbl[i];
			pkt_head_t head;
			size_t off;

			off = odp_packet_l4_offset(pkt);
			if (off ==  ODP_PACKET_OFFSET_INVALID)
				EXAMPLE_ABORT("invalid l4 offset\n");

			off += ODPH_UDPHDR_LEN;
			ret = odp_packet_copy_to_mem(pkt, off, sizeof(head),
						     &head);
			if (ret)
				EXAMPLE_ABORT("unable copy out head data");

			if (head.magic != TEST_SEQ_MAGIC)
				EXAMPLE_ABORT("Wrong head magic!");

			/* Modify magic number in packet */
			head.magic = TEST_SEQ_MAGIC_2;
			ret = odp_packet_copy_from_mem(pkt, off, sizeof(head),
						       &head);
			if (ret)
				EXAMPLE_ABORT("unable to copy in head data");
		}

		/* send all packets back */
		ret = ipc_odp_packet_send_or_free(ipc_pktio, pkt_tbl, pkts);
		if (ret < 0)
			EXAMPLE_ABORT("can not send packets\n");

		stat_pkts += ret;

		/* alloc packet from local pool, set magic to ALLOC_MAGIC,
		 * and send it.*/
		alloc_pkt = odp_packet_alloc(pool, SHM_PKT_POOL_BUF_SIZE);
		if (alloc_pkt != ODP_PACKET_INVALID) {
			pkt_head_t head;
			size_t off;

			odp_packet_l4_offset_set(alloc_pkt, 30);

			head.magic = TEST_ALLOC_MAGIC;

			off = odp_packet_l4_offset(alloc_pkt);
			off += ODPH_UDPHDR_LEN;
			ret = odp_packet_copy_from_mem(alloc_pkt, off,
						       sizeof(head),
						       &head);
			if (ret)
				EXAMPLE_ABORT("unable to copy in head data");

			pkt_tbl[0] = alloc_pkt;
			ret = ipc_odp_packet_send_or_free(ipc_pktio,
							  pkt_tbl, 1);
			if (ret < 0)
				EXAMPLE_ABORT("can not send packets\n");
			stat_pkts += 1;
		}
	}

	/* cleanup and exit */
	ret = odp_pktio_stop(ipc_pktio);
	if (ret) {
		EXAMPLE_DBG("ipc2: odp_pktio_stop error %d\n", ret);
		return -1;
	}

not_started:
	ret = odp_pktio_close(ipc_pktio);
	if (ret) {
		EXAMPLE_DBG("ipc2: odp_pktio_close error %d\n", ret);
		return -1;
	}

	ret = odp_pool_destroy(pool);
	if (ret)
		EXAMPLE_DBG("ipc2: pool_destroy error %d\n", ret);

	return stat_pkts > 1000 ? 0 : -1;
}
Example #3
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, &params);

	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]), &params);

	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;
}