diff --git a/man/perftest.1 b/man/perftest.1 index a170a0fe..dd437e95 100644 --- a/man/perftest.1 +++ b/man/perftest.1 @@ -481,7 +481,7 @@ many different options and modes. Not relevant for raw_ethernet_fs_rate. System support required. .TP -.B --flow_label +.B --flow_label= IPv6 flow label. Not relevant for raw_ethernet_fs_rate. .TP diff --git a/src/perftest_parameters.c b/src/perftest_parameters.c index d13a81a5..78bbe17a 100755 --- a/src/perftest_parameters.c +++ b/src/perftest_parameters.c @@ -114,6 +114,47 @@ static int parse_ethertype_from_str(char *ether_str, uint16_t *ethertype_val) return SUCCESS; } +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; +} + /****************************************************************************** parse_ip_from_str. * @@ -569,8 +610,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()) { @@ -889,7 +930,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; @@ -3011,9 +3052,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; @@ -3427,6 +3466,7 @@ int parser(struct perftest_parameters *user_param,char *argv[], int argc) return 0; } + /****************************************************************************** * ******************************************************************************/ diff --git a/src/perftest_parameters.h b/src/perftest_parameters.h index 918cdaf6..73ed42fd 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 02fffa66..9d80b967 100755 --- a/src/perftest_resources.c +++ b/src/perftest_resources.c @@ -2681,7 +2681,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);