diff --git a/src/perftest_parameters.c b/src/perftest_parameters.c index 766adfa4..14b87f78 100755 --- a/src/perftest_parameters.c +++ b/src/perftest_parameters.c @@ -559,8 +559,8 @@ static void usage(const char *argv0, VerbType verb, TestType tst, int connection printf(" Set the Traffic Class in GRH (if GRH is in use)\n"); if (connection_type != RawEth) { - printf(" --flow_label= "); - printf(" Set the flow_label in GRH (if GRH is in use)\n"); + printf(" --flow_label= "); + printf(" Set the flow_label in GRH for each qp in roundrobin method(if GRH is in use)\n"); } if (cuda_memory_supported()) { @@ -874,7 +874,7 @@ static void init_perftest_params(struct perftest_parameters *user_param) user_param->mr_per_qp = 0; user_param->dlid = 0; user_param->traffic_class = 0; - user_param->flow_label = 0; + user_param->flow_label = NULL; user_param->flows = DEF_FLOWS; user_param->flows_burst = 1; user_param->perform_warm_up = 0; @@ -2955,9 +2955,7 @@ int parser(struct perftest_parameters *user_param,char *argv[], int argc) use_mlu_flag = 0; } if (flow_label_flag) { - CHECK_VALUE(user_param->flow_label,int,"flow label",not_int_ptr); - if (user_param->connection_type == RawEth && user_param->flow_label < 0) { - fprintf(stderr," flow label must be non-negative for RawEth\n"); + if (parse_flow_label_from_str(user_param, optarg)) { return FAILURE; } flow_label_flag = 0; @@ -3355,6 +3353,48 @@ int parser(struct perftest_parameters *user_param,char *argv[], int argc) return 0; } +static int parse_flow_label_from_str(struct perftest_parameters *user_param, char *flow_label_str) +{ + int fl_cnt = 1; + const char* sep = NULL; + + sep = strchr(flow_label_str, ','); + if (sep != NULL) + do { + fl_cnt++; + sep = strchr(sep + 1, ','); + } while (sep); + + int *flow_label = calloc(fl_cnt + 2, sizeof(int)); + flow_label[0] = fl_cnt; + flow_label[1] = 0; + flow_label[2] = strtol(flow_label_str, NULL, 0); + sep = strchr(flow_label_str, ','); + + for (int i = 3; i < fl_cnt + 2; i++) { + flow_label[i] = strtol(sep + 1, NULL, 0); + sep = strchr(sep + 1, ','); + } + + if (user_param->connection_type == RawEth) { + for (int i = 2; i < fl_cnt + 2; i++) { + if (flow_label[i] < 0) { + fprintf(stderr," flow label must be non-negative for RawEth\n"); + return -1; + } + } + } + + if (user_param->flow_label) { + free(user_param->flow_label); + } + + user_param->flow_label = flow_label; + + return 0; +} + + /****************************************************************************** * ******************************************************************************/ diff --git a/src/perftest_parameters.h b/src/perftest_parameters.h index 5a774f0c..6ba21ca0 100755 --- a/src/perftest_parameters.h +++ b/src/perftest_parameters.h @@ -604,7 +604,7 @@ struct perftest_parameters { char *out_json_file_name; struct cpu_util_data cpu_util_data; int latency_gap; - int flow_label; + int* flow_label; int retry_count; int dont_xchg_versions; int ipv6; diff --git a/src/perftest_resources.c b/src/perftest_resources.c index 26532075..df750a08 100755 --- a/src/perftest_resources.c +++ b/src/perftest_resources.c @@ -2642,7 +2642,10 @@ static int ctx_modify_qp_to_rtr(struct ibv_qp *qp, attr->ah_attr.grh.sgid_index = (attr->ah_attr.port_num == user_param->ib_port) ? user_param->gid_index : user_param->gid_index2; attr->ah_attr.grh.hop_limit = 0xFF; attr->ah_attr.grh.traffic_class = user_param->traffic_class; - attr->ah_attr.grh.flow_label = user_param->flow_label; + if (user_param->flow_label) { + attr->ah_attr.grh.flow_label = user_param->flow_label[user_param->flow_label[1] % user_param->flow_label[0] + 2]; + user_param->flow_label[1] = user_param->flow_label[1] + 1; + } } if (user_param->connection_type != UD && user_param->connection_type != SRD) { if (user_param->connection_type == DC) { diff --git a/src/raw_ethernet_resources.c b/src/raw_ethernet_resources.c index 087dfad5..71603fdc 100755 --- a/src/raw_ethernet_resources.c +++ b/src/raw_ethernet_resources.c @@ -732,9 +732,10 @@ static void fill_ip_common(struct ibv_flow_spec* spec_info, } if (user_param->flow_label) { ipv6_spec->val.flow_label = - htonl(user_param->flow_label); + htonl(user_param->flow_label[user_param->flow_label[1] % user_param->flow_label[0] + 2]); ipv6_spec->mask.flow_label = htonl(0xfffff); + user_param->flow_label[1] = user_param->flow_label[1] + 1; } memcpy((void*)&ipv6_spec->mask.dst_ip, ipv6_mask, 16); memcpy((void*)&ipv6_spec->mask.src_ip, ipv6_mask, 16);