/*---------------------------------------------------------------------------*/ int run_client_test(struct perf_parameters *user_param) { struct session_data sess_data; struct perf_comm *comm; struct thread_data *tdata; char url[256]; int i = 0; int max_cpus; pthread_t statistics_thread_id; struct perf_command command; int size_log2; int max_size_log2 = 24; /* client session attributes */ struct xio_session_attr attr = { &ses_ops, NULL, 0 }; xio_init(); g_mhz = get_cpu_mhz(0); max_cpus = sysconf(_SC_NPROCESSORS_ONLN); threads_iter = 1; size_log2 = 0; tdata = calloc(user_param->threads_num, sizeof(*tdata)); if (tdata == NULL) { fprintf(fd, "malloc failed\n"); return -1; } comm = create_comm_struct(user_param); if (establish_connection(comm)) { fprintf(stderr, "failed to establish connection\n"); free(tdata); destroy_comm_struct(comm); return -1; } if (user_param->output_file) { fd = fopen(user_param->output_file, "w"); if (fd == NULL) { fprintf(fd, "file open failed. %s\n", user_param->output_file); free(sess_data.tdata); destroy_comm_struct(comm); return -1; } fprintf(fd, "size, threads, tps, bw[Mbps], lat[usec]\n"); fflush(fd); } printf("%s", RESULT_FMT); printf("%s", RESULT_LINE); while (threads_iter <= user_param->threads_num) { data_len = (uint64_t)1 << size_log2; memset(&sess_data, 0, sizeof(sess_data)); memset(tdata, 0, user_param->threads_num*sizeof(*tdata)); sess_data.tdata = tdata; command.test_param.machine_type = user_param->machine_type; command.test_param.test_type = user_param->test_type; command.test_param.verb = user_param->verb; command.test_param.data_len = data_len; command.command = GetTestParams; ctx_write_data(comm, &command, sizeof(command)); sprintf(url, "rdma://%s:%d", user_param->server_addr, user_param->server_port); sess_data.session = xio_session_create(XIO_SESSION_CLIENT, &attr, url, 0, 0, &sess_data); if (sess_data.session == NULL) { int error = xio_errno(); fprintf(stderr, "session creation failed. reason %d - (%s)\n", error, xio_strerror(error)); goto cleanup; } pthread_create(&statistics_thread_id, NULL, statistics_thread_cb, &sess_data); /* spawn threads to handle connection */ for (i = 0; i < threads_iter; i++) { sess_data.tdata[i].affinity = ((user_param->cpu + i) % max_cpus); sess_data.tdata[i].cid = i; sess_data.tdata[i].sdata = &sess_data; sess_data.tdata[i].user_param = user_param; sess_data.tdata[i].data_len = data_len; /* all threads are working on the same session */ sess_data.tdata[i].session = sess_data.session; pthread_create(&sess_data.tdata[i].thread_id, NULL, worker_thread, &sess_data.tdata[i]); } pthread_join(statistics_thread_id, NULL); /* join the threads */ for (i = 0; i < threads_iter; i++) pthread_join(sess_data.tdata[i].thread_id, NULL); /* close the session */ xio_session_destroy(sess_data.session); if (sess_data.abort) { fprintf(stderr, "program aborted\n"); goto cleanup; } /* send result to server */ command.results.bytes = data_len; command.results.threads = threads_iter; command.results.tps = sess_data.tps; command.results.avg_bw = sess_data.avg_bw; command.results.avg_lat = sess_data.avg_lat_us; command.results.min_lat = sess_data.min_lat_us; command.results.max_lat = sess_data.max_lat_us; command.command = GetTestResults; /* sync point */ ctx_write_data(comm, &command, sizeof(command)); printf(REPORT_FMT, data_len, threads_iter, sess_data.tps, sess_data.avg_bw, sess_data.avg_lat_us, sess_data.min_lat_us, sess_data.max_lat_us); if (fd) fprintf(fd, "%lu, %d, %lu, %.2lf, %.2lf\n", data_len, threads_iter, sess_data.tps, sess_data.avg_bw, sess_data.avg_lat_us); fflush(fd); /* sync point */ ctx_read_data(comm, NULL, 0, NULL); if (++size_log2 < max_size_log2) continue; threads_iter++; size_log2 = 0; } printf("%s", RESULT_LINE); cleanup: if (fd) fclose(fd); ctx_hand_shake(comm); ctx_close_connection(comm); destroy_comm_struct(comm); free(tdata); xio_shutdown(); return 0; }
/*---------------------------------------------------------------------------*/ int run_server_test(struct perf_parameters *user_param) { struct server_data server_data; struct perf_command command; int i, len, retval; int max_cpus; uint64_t cpusmask; int cpusnr; int cpu; xio_init(); max_cpus = sysconf(_SC_NPROCESSORS_ONLN); i = intf_name_best_cpus(user_param->intf_name, &cpusmask, &cpusnr); if (i == 0) { printf("best cpus [%d] %s\n", cpusnr, intf_cpusmask_str(cpusmask, cpusnr, user_param->intf_name)); } server_data.my_test_param.machine_type = user_param->machine_type; server_data.my_test_param.test_type = user_param->test_type; server_data.my_test_param.verb = user_param->verb; server_data.my_test_param.data_len = 0; server_data.tdata = calloc(user_param->threads_num, sizeof(*server_data.tdata)); /* spawn portals */ for (i = 0, cpu = 0; i < user_param->threads_num; i++, cpu++) { while (1) { if (cpusmask_test_bit(cpu, &cpusmask)) break; if (++cpu == max_cpus) cpu = 0; } server_data.tdata[i].affinity = cpu; server_data.tdata[i].portal_index = (i % user_param->portals_arr_len); server_data.tdata[i].user_param = user_param; pthread_create(&server_data.tdata[i].thread_id, NULL, portal_server_cb, &server_data.tdata[i]); } server_data.user_param = user_param; pthread_create(&server_data.thread_id, NULL, balancer_server_cb, &server_data); server_data.comm = create_comm_struct(user_param); if (establish_connection(server_data.comm)) { fprintf(stderr, "failed to establish connection\n"); goto cleanup; } printf("%s", RESULT_FMT); printf("%s", RESULT_LINE); while (1) { /* sync test parameters */ retval = ctx_read_data(server_data.comm, &command, sizeof(command), &len); if (retval) { /* disconnection */ fprintf(stderr, "program aborted\n"); break; } if (len == 0) { /* handshake */ ctx_write_data(server_data.comm, NULL, 0); break; } switch (command.command) { case GetTestResults: on_test_results(&command.results); ctx_write_data(server_data.comm, NULL, 0); break; case GetTestParams: break; default: fprintf(stderr, "unknown command %d\n", len); exit(0); break; }; } if (retval == 0) printf("%s", RESULT_LINE); /* normal exit phase */ ctx_close_connection(server_data.comm); cleanup: for (i = 0; i < user_param->threads_num; i++) xio_context_stop_loop(server_data.tdata[i].ctx, 0); destroy_comm_struct(server_data.comm); /* join the threads */ for (i = 0; i < user_param->threads_num; i++) pthread_join(server_data.tdata[i].thread_id, NULL); if (server_data.running) xio_context_stop_loop(server_data.ctx, 0); pthread_join(server_data.thread_id, NULL); free(server_data.tdata); xio_shutdown(); return 0; }