static bool delete_flag;
static bool dump_socket_mem_flag;
static bool enable_fwd;
+static bool unique_data;
static struct rte_mempool *mbuf_mp;
static uint32_t nb_lcores;
struct multi_cores_pool {
uint32_t cores_count;
uint32_t rules_count;
- struct used_cpu_time create_meter;
- struct used_cpu_time create_flow;
+ struct used_cpu_time meters_record;
+ struct used_cpu_time flows_record;
int64_t last_alloc[RTE_MAX_LCORE];
int64_t current_alloc[RTE_MAX_LCORE];
} __rte_cache_aligned;
printf(" --enable-fwd: To enable packets forwarding"
" after insertion\n");
printf(" --portmask=N: hexadecimal bitmask of ports used\n");
+ printf(" --unique-data: flag to set using unique data for all"
+ " actions that support data, such as header modify and encap actions\n");
printf("To set flow attributes:\n");
printf(" --ingress: set ingress attribute in flows\n");
{ "deletion-rate", 0, 0, 0 },
{ "dump-socket-mem", 0, 0, 0 },
{ "enable-fwd", 0, 0, 0 },
+ { "unique-data", 0, 0, 0 },
{ "portmask", 1, 0, 0 },
{ "cores", 1, 0, 0 },
/* Attributes */
case 0:
if (strcmp(lgopts[opt_idx].name, "help") == 0) {
usage(argv[0]);
- rte_exit(EXIT_SUCCESS, "Displayed help\n");
+ exit(EXIT_SUCCESS);
}
if (strcmp(lgopts[opt_idx].name, "group") == 0) {
if (n >= 0)
flow_group = n;
else
- rte_exit(EXIT_SUCCESS,
+ rte_exit(EXIT_FAILURE,
"flow group should be >= 0\n");
printf("group %d / ", flow_group);
}
if (n > 0)
hairpin_queues_num = n;
else
- rte_exit(EXIT_SUCCESS,
+ rte_exit(EXIT_FAILURE,
"Hairpin queues should be > 0\n");
flow_actions[actions_idx++] =
if (n > 0)
hairpin_queues_num = n;
else
- rte_exit(EXIT_SUCCESS,
+ rte_exit(EXIT_FAILURE,
"Hairpin queues should be > 0\n");
flow_actions[actions_idx++] =
break;
}
/* Reached last item with no match */
- if (i == (RTE_DIM(flow_options) - 1)) {
- fprintf(stderr, "Invalid encap item: %s\n", token);
- usage(argv[0]);
- rte_exit(EXIT_SUCCESS, "Invalid encap item\n");
- }
+ if (i == (RTE_DIM(flow_options) - 1))
+ rte_exit(EXIT_FAILURE,
+ "Invalid encap item: %s\n", token);
}
token = strtok(NULL, ",");
}
for (i = 0; i < RTE_DIM(flow_options); i++) {
if (strcmp(flow_options[i].str, token) == 0) {
printf("%s,", token);
- encap_data |= flow_options[i].mask;
+ decap_data |= flow_options[i].mask;
break;
}
/* Reached last item with no match */
- if (i == (RTE_DIM(flow_options) - 1)) {
- fprintf(stderr, "Invalid decap item: %s\n", token);
- usage(argv[0]);
- rte_exit(EXIT_SUCCESS, "Invalid decap item\n");
- }
+ if (i == (RTE_DIM(flow_options) - 1))
+ rte_exit(EXIT_FAILURE,
+ "Invalid decap item %s\n", token);
}
token = strtok(NULL, ",");
}
if (n >= DEFAULT_RULES_BATCH)
rules_batch = n;
else {
- printf("\n\nrules_batch should be >= %d\n",
+ rte_exit(EXIT_FAILURE,
+ "rules_batch should be >= %d\n",
DEFAULT_RULES_BATCH);
- rte_exit(EXIT_SUCCESS, " ");
}
}
if (strcmp(lgopts[opt_idx].name,
if (n >= (int) rules_batch)
rules_count = n;
else {
- printf("\n\nrules_count should be >= %d\n",
+ rte_exit(EXIT_FAILURE,
+ "rules_count should be >= %d\n",
rules_batch);
}
}
if (strcmp(lgopts[opt_idx].name,
"dump-iterations") == 0)
dump_iterations = true;
+ if (strcmp(lgopts[opt_idx].name,
+ "unique-data") == 0)
+ unique_data = true;
if (strcmp(lgopts[opt_idx].name,
"deletion-rate") == 0)
delete_flag = true;
if (strcmp(lgopts[opt_idx].name, "cores") == 0) {
n = atoi(optarg);
if ((int) rte_lcore_count() <= n) {
- printf("\nError: you need %d cores to run on multi-cores\n"
+ rte_exit(EXIT_FAILURE,
+ "Error: you need %d cores to run on multi-cores\n"
"Existing cores are: %d\n", n, rte_lcore_count());
- rte_exit(EXIT_FAILURE, " ");
}
if (n <= RTE_MAX_LCORE && n > 0)
mc_pool.cores_count = n;
else {
- printf("Error: cores count must be > 0 "
- " and < %d\n", RTE_MAX_LCORE);
- rte_exit(EXIT_FAILURE, " ");
+ rte_exit(EXIT_FAILURE,
+ "Error: cores count must be > 0 and < %d\n",
+ RTE_MAX_LCORE);
}
}
break;
default:
- fprintf(stderr, "Invalid option: %s\n", argv[optind]);
usage(argv[0]);
- rte_exit(EXIT_SUCCESS, "Invalid option\n");
+ rte_exit(EXIT_FAILURE, "Invalid option: %s\n",
+ argv[optind]);
break;
}
}
/*create meter*/
params.meter_profile_id = default_prof_id;
- params.action[RTE_COLOR_GREEN] =
- MTR_POLICER_ACTION_COLOR_GREEN;
- params.action[RTE_COLOR_YELLOW] =
- MTR_POLICER_ACTION_COLOR_YELLOW;
- params.action[RTE_COLOR_RED] =
- MTR_POLICER_ACTION_DROP;
-
ret = rte_mtr_create(port_id, counter, ¶ms, 1, &error);
if (ret != 0) {
printf("Port %u create meter idx(%d) error(%d) message: %s\n",
port_id, counter, error.type,
error.message ? error.message : "(no stated reason)");
- rte_exit(EXIT_FAILURE, "error in creating meter");
+ rte_exit(EXIT_FAILURE, "Error in creating meter\n");
}
}
printf("Port %u destroy meter(%d) error(%d) message: %s\n",
port_id, counter, error.type,
error.message ? error.message : "(no stated reason)");
- rte_exit(EXIT_FAILURE, "Error in deleting meter rule");
+ rte_exit(EXIT_FAILURE, "Error in deleting meter rule\n");
}
}
end_counter = (core_id + 1) * rules_count_per_core;
cpu_time_used = 0;
- start_batch = rte_rdtsc();
+ start_batch = rte_get_timer_cycles();
for (counter = start_counter; counter < end_counter; counter++) {
if (ops == METER_CREATE)
create_meter_rule(port_id, counter);
if (!((counter + 1) % rules_batch)) {
rules_batch_idx = ((counter + 1) / rules_batch) - 1;
cpu_time_per_batch[rules_batch_idx] =
- ((double)(rte_rdtsc() - start_batch))
- / rte_get_tsc_hz();
+ ((double)(rte_get_timer_cycles() - start_batch))
+ / rte_get_timer_hz();
cpu_time_used += cpu_time_per_batch[rules_batch_idx];
- start_batch = rte_rdtsc();
+ start_batch = rte_get_timer_cycles();
}
}
cpu_time_used, insertion_rate);
if (ops == METER_CREATE)
- mc_pool.create_meter.insertion[port_id][core_id]
+ mc_pool.meters_record.insertion[port_id][core_id]
= cpu_time_used;
else
- mc_pool.create_meter.deletion[port_id][core_id]
+ mc_pool.meters_record.deletion[port_id][core_id]
= cpu_time_used;
}
if (flow_group > 0 && core_id == 0)
rules_count_per_core++;
- start_batch = rte_rdtsc();
+ start_batch = rte_get_timer_cycles();
for (i = 0; i < (uint32_t) rules_count_per_core; i++) {
if (flows_list[i] == 0)
break;
memset(&error, 0x33, sizeof(error));
if (rte_flow_destroy(port_id, flows_list[i], &error)) {
print_flow_error(error);
- rte_exit(EXIT_FAILURE, "Error in deleting flow");
+ rte_exit(EXIT_FAILURE, "Error in deleting flow\n");
}
/*
* for this batch.
*/
if (!((i + 1) % rules_batch)) {
- end_batch = rte_rdtsc();
+ end_batch = rte_get_timer_cycles();
delta = (double) (end_batch - start_batch);
rules_batch_idx = ((i + 1) / rules_batch) - 1;
- cpu_time_per_batch[rules_batch_idx] = delta / rte_get_tsc_hz();
+ cpu_time_per_batch[rules_batch_idx] = delta / rte_get_timer_hz();
cpu_time_used += cpu_time_per_batch[rules_batch_idx];
- start_batch = rte_rdtsc();
+ start_batch = rte_get_timer_cycles();
}
}
printf(":: Port %d :: Core %d :: The time for deleting %d rules is %f seconds\n",
port_id, core_id, rules_count_per_core, cpu_time_used);
- mc_pool.create_flow.deletion[port_id][core_id] = cpu_time_used;
+ mc_pool.flows_record.deletion[port_id][core_id] = cpu_time_used;
}
static struct rte_flow **
struct rte_flow **flows_list;
struct rte_flow_error error;
clock_t start_batch, end_batch;
+ double first_flow_latency;
double cpu_time_used;
double insertion_rate;
double cpu_time_per_batch[MAX_BATCHES_COUNT] = { 0 };
flows_list = rte_zmalloc("flows_list",
(sizeof(struct rte_flow *) * rules_count_per_core) + 1, 0);
if (flows_list == NULL)
- rte_exit(EXIT_FAILURE, "No Memory available!");
+ rte_exit(EXIT_FAILURE, "No Memory available!\n");
cpu_time_used = 0;
flow_index = 0;
*/
flow = generate_flow(port_id, 0, flow_attrs,
global_items, global_actions,
- flow_group, 0, 0, 0, 0, core_id, &error);
+ flow_group, 0, 0, 0, 0, core_id, unique_data, &error);
if (flow == NULL) {
print_flow_error(error);
- rte_exit(EXIT_FAILURE, "error in creating flow");
+ rte_exit(EXIT_FAILURE, "Error in creating flow\n");
}
flows_list[flow_index++] = flow;
}
- start_batch = rte_rdtsc();
+ start_batch = rte_get_timer_cycles();
for (counter = start_counter; counter < end_counter; counter++) {
flow = generate_flow(port_id, flow_group,
flow_attrs, flow_items, flow_actions,
JUMP_ACTION_TABLE, counter,
hairpin_queues_num,
encap_data, decap_data,
- core_id, &error);
+ core_id, unique_data, &error);
+
+ if (!counter) {
+ first_flow_latency = (double) (rte_get_timer_cycles() - start_batch);
+ first_flow_latency /= rte_get_timer_hz();
+ /* In millisecond */
+ first_flow_latency *= 1000;
+ printf(":: First Flow Latency :: Port %d :: First flow "
+ "installed in %f milliseconds\n",
+ port_id, first_flow_latency);
+ }
if (force_quit)
counter = end_counter;
if (!flow) {
print_flow_error(error);
- rte_exit(EXIT_FAILURE, "error in creating flow");
+ rte_exit(EXIT_FAILURE, "Error in creating flow\n");
}
flows_list[flow_index++] = flow;
* for this batch.
*/
if (!((counter + 1) % rules_batch)) {
- end_batch = rte_rdtsc();
+ end_batch = rte_get_timer_cycles();
delta = (double) (end_batch - start_batch);
rules_batch_idx = ((counter + 1) / rules_batch) - 1;
- cpu_time_per_batch[rules_batch_idx] = delta / rte_get_tsc_hz();
+ cpu_time_per_batch[rules_batch_idx] = delta / rte_get_timer_hz();
cpu_time_used += cpu_time_per_batch[rules_batch_idx];
- start_batch = rte_rdtsc();
+ start_batch = rte_get_timer_cycles();
}
}
printf(":: Port %d :: Core %d :: The time for creating %d in rules %f seconds\n",
port_id, core_id, rules_count_per_core, cpu_time_used);
- mc_pool.create_flow.insertion[port_id][core_id] = cpu_time_used;
+ mc_pool.flows_record.insertion[port_id][core_id] = cpu_time_used;
return flows_list;
}
rte_eal_mp_wait_lcore();
RTE_ETH_FOREACH_DEV(port) {
+ /* If port outside portmask */
+ if (!((ports_mask >> port) & 0x1))
+ continue;
if (has_meter())
dump_used_cpu_time("Meters:",
- port, &mc_pool.create_meter);
+ port, &mc_pool.meters_record);
dump_used_cpu_time("Flows:",
- port, &mc_pool.create_flow);
+ port, &mc_pool.flows_record);
dump_used_mem(port);
}
old = rte_zmalloc("old",
sizeof(struct lcore_info) * RTE_MAX_LCORE, 0);
if (old == NULL)
- rte_exit(EXIT_FAILURE, "No Memory available!");
+ rte_exit(EXIT_FAILURE, "No Memory available!\n");
memcpy(old, lcore_infos,
sizeof(struct lcore_info) * RTE_MAX_LCORE);
delete_flag = false;
dump_socket_mem_flag = false;
flow_group = DEFAULT_GROUP;
+ unique_data = false;
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
if (nb_lcores <= 1)
rte_exit(EXIT_FAILURE, "This app needs at least two cores\n");
-
printf(":: Flows Count per port: %d\n\n", rules_count);
if (has_meter())