static int register_for_notification(struct loopback_test *t) { char buf[MAX_SYSFS_PATH]; int i; t->inotify_fd = inotify_init(); if (t->inotify_fd < 0) { fprintf(stderr, "inotify_init fail %s\n", strerror(errno)); abort(); } for (i = 0; i < t->device_count; i++) { if (!device_enabled(t, i)) continue; snprintf(buf, sizeof(buf), "%s%s", t->devices[i].sysfs_entry, "iteration_count"); t->devices[i].inotify_wd = inotify_add_watch(t->inotify_fd, buf, IN_MODIFY); if (t->devices[i].inotify_wd < 0) { fprintf(stderr, "inotify_add_watch %s fail %s\n", buf, strerror(errno)); close(t->inotify_fd); abort(); } } return 0; }
static int log_results(struct loopback_test *t) { int fd, i, len, ret; struct tm tm; time_t local_time; mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; char file_name[MAX_SYSFS_PATH]; char data[CSV_MAX_LINE]; local_time = time(NULL); tm = *localtime(&local_time); /* * file name will test_name_size_iteration_max.csv * every time the same test with the same parameters is run we will then * append to the same CSV with datestamp - representing each test * dataset. */ if (t->file_output && !t->porcelain) { snprintf(file_name, sizeof(file_name), "%s_%d_%d.csv", t->test_name, t->size, t->iteration_max); fd = open(file_name, O_WRONLY | O_CREAT | O_APPEND, mode); if (fd < 0) { fprintf(stderr, "unable to open %s for appendation\n", file_name); abort(); } } for (i = 0; i < t->device_count; i++) { if (!device_enabled(t, i)) continue; len = format_output(t, &t->devices[i].results, t->devices[i].name, data, sizeof(data), &tm); if (t->file_output && !t->porcelain) { ret = write(fd, data, len); if (ret == -1) fprintf(stderr, "unable to write %d bytes to csv.\n", len); } } if (t->aggregate_output) { len = format_output(t, &t->aggregate_results, "aggregate", data, sizeof(data), &tm); if (t->file_output && !t->porcelain) { ret = write(fd, data, len); if (ret == -1) fprintf(stderr, "unable to write %d bytes to csv.\n", len); } } if (t->file_output && !t->porcelain) close(fd); return 0; }
static void stop_tests(struct loopback_test *t) { int i; for (i = 0; i < t->device_count; i++) { if (!device_enabled(t, i)) continue; write_sysfs_val(t->devices[i].sysfs_entry, "type", 0); } }
static void prepare_devices(struct loopback_test *t) { int i; /* * Cancel any running tests on enabled devices. If * stop_all option is given, stop test on all devices. */ for (i = 0; i < t->device_count; i++) if (t->stop_all || device_enabled(t, i)) write_sysfs_val(t->devices[i].sysfs_entry, "type", 0); for (i = 0; i < t->device_count; i++) { if (!device_enabled(t, i)) continue; write_sysfs_val(t->devices[i].sysfs_entry, "us_wait", t->us_wait); /* Set operation size */ write_sysfs_val(t->devices[i].sysfs_entry, "size", t->size); /* Set iterations */ write_sysfs_val(t->devices[i].sysfs_entry, "iteration_max", t->iteration_max); if (t->use_async) { write_sysfs_val(t->devices[i].sysfs_entry, "async", 1); write_sysfs_val(t->devices[i].sysfs_entry, "timeout", t->async_timeout); write_sysfs_val(t->devices[i].sysfs_entry, "outstanding_operations_max", t->async_outstanding_operations); } else write_sysfs_val(t->devices[i].sysfs_entry, "async", 0); } }
static int start(struct loopback_test *t) { int i; /* the test starts by writing test_id to the type file. */ for (i = 0; i < t->device_count; i++) { if (!device_enabled(t, i)) continue; write_sysfs_val(t->devices[i].sysfs_entry, "type", t->test_id); } return 0; }
static int is_complete(struct loopback_test *t) { int iteration_count; int i; for (i = 0; i < t->device_count; i++) { if (!device_enabled(t, i)) continue; iteration_count = read_sysfs_int(t->devices[i].sysfs_entry, "iteration_count"); /* at least one device did not finish yet */ if (iteration_count != t->iteration_max) return 0; } return 1; }
static int unregister_for_notification(struct loopback_test *t) { int i; int ret = 0; for (i = 0; i < t->device_count; i++) { if (!device_enabled(t, i)) continue; ret = inotify_rm_watch(t->inotify_fd, t->devices[i].inotify_wd); if (ret) { fprintf(stderr, "inotify_rm_watch error.\n"); return ret; } } close(t->inotify_fd); return 0; }
static int sanity_check(struct loopback_test *t) { int i; if (t->device_count == 0) { fprintf(stderr, "No loopback devices found\n"); return -1; } for (i = 0; i < MAX_NUM_DEVICES; i++) { if (!device_enabled(t, i)) continue; if (t->mask && !strcmp(t->devices[i].name, "")) { fprintf(stderr, "Bad device mask %x\n", (1 << i)); return -1; } } return 0; }
static int open_poll_files(struct loopback_test *t) { struct loopback_device *dev; char buf[MAX_STR_LEN]; char dummy; int fds_idx = 0; int i; for (i = 0; i < t->device_count; i++) { dev = &t->devices[i]; if (!device_enabled(t, i)) continue; snprintf(buf, sizeof(buf), "%s%s", dev->sysfs_entry, "iteration_count"); t->fds[fds_idx].fd = open(buf, O_RDONLY); if (t->fds[fds_idx].fd < 0) { fprintf(stderr, "Error opening poll file!\n"); goto err; } read(t->fds[fds_idx].fd, &dummy, 1); t->fds[fds_idx].events = POLLERR|POLLPRI; t->fds[fds_idx].revents = 0; fds_idx++; } t->poll_count = fds_idx; return 0; err: for (i = 0; i < fds_idx; i++) close(t->fds[i].fd); return -1; }
static int get_results(struct loopback_test *t) { struct loopback_device *d; struct loopback_results *r; int i; for (i = 0; i < t->device_count; i++) { if (!device_enabled(t, i)) continue; d = &t->devices[i]; r = &d->results; r->error = read_sysfs_int(d->sysfs_entry, "error"); r->request_min = read_sysfs_int(d->sysfs_entry, "requests_per_second_min"); r->request_max = read_sysfs_int(d->sysfs_entry, "requests_per_second_max"); r->request_avg = read_sysfs_float(d->sysfs_entry, "requests_per_second_avg"); r->latency_min = read_sysfs_int(d->sysfs_entry, "latency_min"); r->latency_max = read_sysfs_int(d->sysfs_entry, "latency_max"); r->latency_avg = read_sysfs_float(d->sysfs_entry, "latency_avg"); r->throughput_min = read_sysfs_int(d->sysfs_entry, "throughput_min"); r->throughput_max = read_sysfs_int(d->sysfs_entry, "throughput_max"); r->throughput_avg = read_sysfs_float(d->sysfs_entry, "throughput_avg"); r->apbridge_unipro_latency_min = read_sysfs_int(d->sysfs_entry, "apbridge_unipro_latency_min"); r->apbridge_unipro_latency_max = read_sysfs_int(d->sysfs_entry, "apbridge_unipro_latency_max"); r->apbridge_unipro_latency_avg = read_sysfs_float(d->sysfs_entry, "apbridge_unipro_latency_avg"); r->gbphy_firmware_latency_min = read_sysfs_int(d->sysfs_entry, "gbphy_firmware_latency_min"); r->gbphy_firmware_latency_max = read_sysfs_int(d->sysfs_entry, "gbphy_firmware_latency_max"); r->gbphy_firmware_latency_avg = read_sysfs_float(d->sysfs_entry, "gbphy_firmware_latency_avg"); r->request_jitter = r->request_max - r->request_min; r->latency_jitter = r->latency_max - r->latency_min; r->throughput_jitter = r->throughput_max - r->throughput_min; r->apbridge_unipro_latency_jitter = r->apbridge_unipro_latency_max - r->apbridge_unipro_latency_min; r->gbphy_firmware_latency_jitter = r->gbphy_firmware_latency_max - r->gbphy_firmware_latency_min; } /*calculate the aggregate results of all enabled devices */ if (t->aggregate_output) { r = &t->aggregate_results; r->request_min = get_request_min_aggregate(t); r->request_max = get_request_max_aggregate(t); r->request_avg = get_request_avg_aggregate(t); r->latency_min = get_latency_min_aggregate(t); r->latency_max = get_latency_max_aggregate(t); r->latency_avg = get_latency_avg_aggregate(t); r->throughput_min = get_throughput_min_aggregate(t); r->throughput_max = get_throughput_max_aggregate(t); r->throughput_avg = get_throughput_avg_aggregate(t); r->apbridge_unipro_latency_min = get_apbridge_unipro_latency_min_aggregate(t); r->apbridge_unipro_latency_max = get_apbridge_unipro_latency_max_aggregate(t); r->apbridge_unipro_latency_avg = get_apbridge_unipro_latency_avg_aggregate(t); r->gbphy_firmware_latency_min = get_gbphy_firmware_latency_min_aggregate(t); r->gbphy_firmware_latency_max = get_gbphy_firmware_latency_max_aggregate(t); r->gbphy_firmware_latency_avg = get_gbphy_firmware_latency_avg_aggregate(t); r->request_jitter = r->request_max - r->request_min; r->latency_jitter = r->latency_max - r->latency_min; r->throughput_jitter = r->throughput_max - r->throughput_min; r->apbridge_unipro_latency_jitter = r->apbridge_unipro_latency_max - r->apbridge_unipro_latency_min; r->gbphy_firmware_latency_jitter = r->gbphy_firmware_latency_max - r->gbphy_firmware_latency_min; } return 0; }