/*---------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { struct ifaddrs *ifaddr, *ifa; char host[NI_MAXHOST] = {0}; char cpus_str[256]; char flags[1024]; uint64_t cpusmask = 0; int cpusnum; int retval = -1; int ec = EXIT_FAILURE; int numa_node; if (getifaddrs(&ifaddr) == -1) { perror("getifaddrs"); goto cleanup; } printf("%-10s %-16s %-30s %-5s %-10s %-40s\n", "interface", "host", "flags", "numa", "cpus mask", "cpus"); printf("---------------------------------------------------"); printf("-------------------------------------------------------\n"); for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) { switch (ifa->ifa_addr->sa_family) { case AF_INET: if (!(ifa->ifa_flags & IFF_UP)) continue; getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); break; case AF_PACKET: if (ifa->ifa_flags & IFF_MASTER) continue; if (ifa->ifa_flags & IFF_SLAVE) break; if (!(ifa->ifa_flags & IFF_UP)) break; continue; break; default: continue; break; } flags[0] = 0; if (ifa->ifa_flags & IFF_UP) sprintf(flags, "%s %s", flags, "UP"); else sprintf(flags, "%s %s", flags, "DOWN"); if (ifa->ifa_flags & IFF_LOOPBACK) sprintf(flags, "%s %s", flags, "LOOPBACK"); if (ifa->ifa_flags & IFF_RUNNING) sprintf(flags, "%s %s", flags, "RUNNING"); if (ifa->ifa_flags & IFF_SLAVE) { char master[256]; intf_master_name(ifa->ifa_name, master); sprintf(flags, "%s %s - [%s]", flags, "SLAVE", master); } if (ifa->ifa_flags & IFF_MASTER) sprintf(flags, "%s %s", flags, "MASTER"); numa_node = intf_numa_node(ifa->ifa_name); retval = intf_name_best_cpus(ifa->ifa_name, &cpusmask, &cpusnum); if (retval != 0) { /*perror("intf_name_best_cpus"); */ printf("%-10s %-16s %-30s %-5c 0x%-8lx %-4s[0]\n", ifa->ifa_name, host, flags, 0x20, 0UL, "cpus"); continue; } intf_cpusmask_str(cpusmask, cpusnum, cpus_str); printf("%-10s %-16s %-30s %-5d 0x%-8lx %-4s[%d] - %s\n", ifa->ifa_name, host, flags, numa_node, cpusmask, "cpus", cpusnum, cpus_str); } ec = EXIT_SUCCESS; freeifaddrs(ifaddr); cleanup: exit(ec); }
/*---------------------------------------------------------------------------*/ 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; }
/*---------------------------------------------------------------------------*/ int run_client_test(struct perf_parameters *user_param) { struct session_data sess_data; struct perf_comm *comm; struct thread_data *tdata; char str[512]; char url[256]; unsigned int i = 0; int cpu; int max_cpus; int cpusnr; uint64_t cpusmask; pthread_t statistics_thread_id; struct perf_command command; int size_log2; int max_size_log2 = 24; struct xio_session_params params; xio_init(); g_mhz = get_cpu_mhz(0); max_cpus = sysconf(_SC_NPROCESSORS_ONLN); threads_iter = 1; size_log2 = 0; tdata = (struct thread_data *) calloc(user_param->threads_num, sizeof(*tdata)); if (tdata == NULL) { fprintf(fd, "malloc failed\n"); goto cleanup1; } comm = create_comm_struct(user_param); if (establish_connection(comm)) { fprintf(stderr, "failed to establish connection\n"); goto cleanup2; } 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); goto cleanup2; } fprintf(fd, "size, threads, tps, bw[Mbps], lat[usec]\n"); fflush(fd); } 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, str)); } 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)); memset(¶ms, 0, sizeof(params)); 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, "%s://%s:%d", user_param->transport, user_param->server_addr, user_param->server_port); params.type = XIO_SESSION_CLIENT; params.ses_ops = &ses_ops; params.user_context = &sess_data; params.uri = url; sess_data.session = xio_session_create(¶ms); 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, cpu = 0; i < threads_iter; i++, cpu++) { while (1) { if (cpusmask_test_bit(cpu, &cpusmask)) break; if (++cpu == max_cpus) cpu = 0; } sess_data.tdata[i].affinity = cpu; sess_data.tdata[i].cid = 0; 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); cleanup2: destroy_comm_struct(comm); free(tdata); cleanup1: xio_shutdown(); return 0; }