X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=VNFs%2FDPPD-PROX%2Fhandle_gen.c;h=9bb34fc73e54bb47f386dbe22559ea41d333702c;hb=26f14f6f6f11892fbed6d6e199c5d73f3d1ce70a;hp=f8c99ee5bdfdf8b4b37f1a5de533f60385769204;hpb=516aad7ecf88e968940d384a1f56dca4e42a279b;p=samplevnf.git diff --git a/VNFs/DPPD-PROX/handle_gen.c b/VNFs/DPPD-PROX/handle_gen.c index f8c99ee5..9bb34fc7 100644 --- a/VNFs/DPPD-PROX/handle_gen.c +++ b/VNFs/DPPD-PROX/handle_gen.c @@ -122,6 +122,7 @@ struct task_gen { struct ether_addr src_mac; uint8_t flags; uint8_t cksum_offload; + struct prox_port_cfg *port; } __rte_cache_aligned; static inline uint8_t ipv4_get_hdr_len(struct ipv4_hdr *ip) @@ -790,31 +791,45 @@ static int check_all_pkt_size(struct task_gen *task, int do_panic) return 0; } -static void check_fields_in_bounds(struct task_gen *task) +static int check_fields_in_bounds(struct task_gen *task, uint32_t pkt_size, int do_panic) { - const uint32_t pkt_size = task->pkt_template[0].len; - if (task->lat_enabled) { uint32_t pos_beg = task->lat_pos; uint32_t pos_end = task->lat_pos + 3U; - PROX_PANIC(pkt_size <= pos_end, "Writing latency at %u-%u, but packet size is %u bytes\n", + if (do_panic) + PROX_PANIC(pkt_size <= pos_end, "Writing latency at %u-%u, but packet size is %u bytes\n", pos_beg, pos_end, pkt_size); + else if (pkt_size <= pos_end) { + plog_err("Writing latency at %u-%u, but packet size is %u bytes\n", pos_beg, pos_end, pkt_size); + return -1; + } } if (task->packet_id_pos) { uint32_t pos_beg = task->packet_id_pos; uint32_t pos_end = task->packet_id_pos + 4U; - PROX_PANIC(pkt_size <= pos_end, "Writing packet at %u-%u, but packet size is %u bytes\n", + if (do_panic) + PROX_PANIC(pkt_size <= pos_end, "Writing packet at %u-%u, but packet size is %u bytes\n", pos_beg, pos_end, pkt_size); + else if (pkt_size <= pos_end) { + plog_err("Writing packet at %u-%u, but packet size is %u bytes\n", pos_beg, pos_end, pkt_size); + return -1; + } } if (task->accur_pos) { uint32_t pos_beg = task->accur_pos; uint32_t pos_end = task->accur_pos + 3U; - PROX_PANIC(pkt_size <= pos_end, "Writing accuracy at %u%-u, but packet size is %u bytes\n", + if (do_panic) + PROX_PANIC(pkt_size <= pos_end, "Writing accuracy at %u%-u, but packet size is %u bytes\n", pos_beg, pos_end, pkt_size); + else if (pkt_size <= pos_end) { + plog_err("Writing accuracy at %u%-u, but packet size is %u bytes\n", pos_beg, pos_end, pkt_size); + return -1; + } } + return 0; } static void task_gen_pkt_template_recalc_metadata(struct task_gen *task) @@ -919,7 +934,7 @@ static void task_init_gen_load_pkt_inline(struct task_gen *task, struct task_arg task->pkt_template_orig[0].len = targ->pkt_size; task_gen_reset_pkt_templates(task); check_all_pkt_size(task, 1); - check_fields_in_bounds(task); + check_fields_in_bounds(task, task->pkt_template[0].len, 1); } static void task_init_gen_load_pcap(struct task_gen *task, struct task_args *targ) @@ -976,10 +991,11 @@ int task_gen_set_pkt_size(struct task_base *tbase, uint32_t pkt_size) struct task_gen *task = (struct task_gen *)tbase; int rc; - task->pkt_template[0].len = pkt_size; - if ((rc = check_all_pkt_size(task, 0)) != 0) + if ((rc = check_pkt_size(task, pkt_size, 0)) != 0) + return rc; + if ((rc = check_fields_in_bounds(task, pkt_size, 0)) != 0) return rc; - check_fields_in_bounds(task); + task->pkt_template[0].len = pkt_size; return rc; } @@ -1129,6 +1145,12 @@ static void start(struct task_base *tbase) if (tbase->l3.tmaster) { register_all_ip_to_ctrl_plane(task); } + if (task->port && task->port->link_speed) { + // task->port->link->speed reports the link speed in Mbps e.g. 40k for a 40 Gbps NIC + // task->link_speed reported link speed in Bytes per sec. + task->link_speed = task->port->link_speed * 125000L; + plog_info("\tGenerating at %ld Mbps\n", 8 * task->link_speed / 1000000); + } /* TODO Handle the case when two tasks transmit to the same port and one of them is stopped. In that case ARP (requests or replies) @@ -1152,7 +1174,8 @@ static void init_task_gen_early(struct task_args *targ) uint8_t *generator_count = prox_sh_find_system("generator_count"); if (generator_count == NULL) { - generator_count = prox_zmalloc(sizeof(*generator_count), 0); + generator_count = prox_zmalloc(sizeof(*generator_count), rte_lcore_to_socket_id(targ->lconf->id)); + PROX_PANIC(generator_count == NULL, "Failed to allocate generator count\n"); prox_sh_add_system("generator_count", generator_count); } targ->generator_id = *generator_count; @@ -1175,9 +1198,16 @@ static void init_task_gen(struct task_base *tbase, struct task_args *targ) task->sig = targ->sig; task->new_rate_bps = targ->rate_bps; + /* + * For tokens, use 10 Gbps as base rate + * Scripts can then use speed command, with speed=100 as 10 Gbps and speed=400 as 40 Gbps + * Script can query prox "port info" command to find out the port link speed to know + * at which rate to start. Note that virtio running on OVS returns 10 Gbps, so a script has + * probably also to check the driver (as returned by the same "port info" command. + */ struct token_time_cfg tt_cfg = token_time_cfg_create(1250000000, rte_get_tsc_hz(), -1); - token_time_init(&task->token_time, &tt_cfg); + init_task_gen_seeds(task); task->min_bulk_size = targ->min_bulk_size; @@ -1195,9 +1225,8 @@ static void init_task_gen(struct task_base *tbase, struct task_args *targ) PROX_PANIC((task->lat_pos || task->accur_pos) && !task->lat_enabled, "lat not enabled by lat pos or accur pos configured\n"); task->generator_id = targ->generator_id; + plog_info("\tGenerator id = %d\n", task->generator_id); task->link_speed = UINT64_MAX; - if (targ->nb_txrings == 0 && targ->nb_txports == 1) - task->link_speed = 1250000000; if (!strcmp(targ->pcap_file, "")) { plog_info("\tUsing inline definition of a packet\n"); @@ -1222,6 +1251,7 @@ static void init_task_gen(struct task_base *tbase, struct task_args *targ) struct prox_port_cfg *port = find_reachable_port(targ); if (port) { task->cksum_offload = port->capabilities.tx_offload_cksum; + task->port = port; } } @@ -1230,6 +1260,7 @@ static struct task_init task_init_gen = { .init = init_task_gen, .handle = handle_gen_bulk, .start = start, + .early_init = init_task_gen_early, #ifdef SOFT_CRC // For SOFT_CRC, no offload is needed. If both NOOFFLOADS and NOMULTSEGS flags are set the // vector mode is used by DPDK, resulting (theoretically) in higher performance. @@ -1246,6 +1277,7 @@ static struct task_init task_init_gen_l3 = { .init = init_task_gen, .handle = handle_gen_bulk, .start = start, + .early_init = init_task_gen_early, #ifdef SOFT_CRC // For SOFT_CRC, no offload is needed. If both NOOFFLOADS and NOMULTSEGS flags are set the // vector mode is used by DPDK, resulting (theoretically) in higher performance. @@ -1262,6 +1294,7 @@ static struct task_init task_init_gen_pcap = { .init = init_task_gen_pcap, .handle = handle_gen_pcap_bulk, .start = start_pcap, + .early_init = init_task_gen_early, #ifdef SOFT_CRC .flag_features = TASK_FEATURE_NEVER_DISCARDS | TASK_FEATURE_NO_RX | TASK_FEATURE_TXQ_FLAGS_NOOFFLOADS | TASK_FEATURE_TXQ_FLAGS_NOMULTSEGS, #else