2 * Loopback test application
4 * Copyright 2015 Google Inc.
5 * Copyright 2015 Linaro Ltd.
7 * Provided under the three clause BSD license found in the LICENSE file.
16 #include <sys/types.h>
22 #define MAX_NUM_DEVICES 10
23 #define MAX_SYSFS_PREFIX 0x80
24 #define MAX_SYSFS_PATH 0x200
25 #define CSV_MAX_LINE 0x1000
26 #define SYSFS_MAX_INT 0x20
27 #define MAX_STR_LEN 255
28 #define DEFAULT_ASYNC_TIMEOUT 200000
35 static struct dict dict[] = {
39 {NULL,} /* list termination */
42 struct loopback_results {
46 uint32_t latency_jitter;
51 uint32_t request_jitter;
54 uint32_t throughput_max;
55 uint32_t throughput_min;
56 uint32_t throughput_jitter;
58 float apbridge_unipro_latency_avg;
59 uint32_t apbridge_unipro_latency_max;
60 uint32_t apbridge_unipro_latency_min;
61 uint32_t apbridge_unipro_latency_jitter;
63 float gbphy_firmware_latency_avg;
64 uint32_t gbphy_firmware_latency_max;
65 uint32_t gbphy_firmware_latency_min;
66 uint32_t gbphy_firmware_latency_jitter;
71 struct loopback_device {
72 char name[MAX_STR_LEN];
73 char sysfs_entry[MAX_SYSFS_PATH];
74 char debugfs_entry[MAX_SYSFS_PATH];
75 struct loopback_results results;
78 struct loopback_test {
92 int async_outstanding_operations;
97 char test_name[MAX_STR_LEN];
98 char sysfs_prefix[MAX_SYSFS_PREFIX];
99 char debugfs_prefix[MAX_SYSFS_PREFIX];
100 struct timespec poll_timeout;
101 struct loopback_device devices[MAX_NUM_DEVICES];
102 struct loopback_results aggregate_results;
103 struct pollfd fds[MAX_NUM_DEVICES];
106 struct loopback_test t;
108 /* Helper macros to calculate the aggregate results for all devices */
109 static inline int device_enabled(struct loopback_test *t, int dev_idx);
111 #define GET_MAX(field) \
112 static int get_##field##_aggregate(struct loopback_test *t) \
116 for (i = 0; i < t->device_count; i++) { \
117 if (!device_enabled(t, i)) \
119 if (t->devices[i].results.field > max) \
120 max = t->devices[i].results.field; \
125 #define GET_MIN(field) \
126 static int get_##field##_aggregate(struct loopback_test *t) \
130 for (i = 0; i < t->device_count; i++) { \
131 if (!device_enabled(t, i)) \
133 if (t->devices[i].results.field < min) \
134 min = t->devices[i].results.field; \
139 #define GET_AVG(field) \
140 static int get_##field##_aggregate(struct loopback_test *t) \
143 uint32_t count = 0; \
145 for (i = 0; i < t->device_count; i++) { \
146 if (!device_enabled(t, i)) \
149 val += t->devices[i].results.field; \
156 GET_MAX(throughput_max);
157 GET_MAX(request_max);
158 GET_MAX(latency_max);
159 GET_MAX(apbridge_unipro_latency_max);
160 GET_MAX(gbphy_firmware_latency_max);
161 GET_MIN(throughput_min);
162 GET_MIN(request_min);
163 GET_MIN(latency_min);
164 GET_MIN(apbridge_unipro_latency_min);
165 GET_MIN(gbphy_firmware_latency_min);
166 GET_AVG(throughput_avg);
167 GET_AVG(request_avg);
168 GET_AVG(latency_avg);
169 GET_AVG(apbridge_unipro_latency_avg);
170 GET_AVG(gbphy_firmware_latency_avg);
179 fprintf(stderr, "Usage: loopback_test TEST [SIZE] ITERATIONS [SYSPATH] [DBGPATH]\n\n"
180 " Run TEST for a number of ITERATIONS with operation data SIZE bytes\n"
181 " TEST may be \'ping\' \'transfer\' or \'sink\'\n"
182 " SIZE indicates the size of transfer <= greybus max payload bytes\n"
183 " ITERATIONS indicates the number of times to execute TEST at SIZE bytes\n"
184 " Note if ITERATIONS is set to zero then this utility will\n"
185 " initiate an infinite (non terminating) test and exit\n"
186 " without logging any metrics data\n"
187 " SYSPATH indicates the sysfs path for the loopback greybus entries e.g.\n"
188 " /sys/bus/greybus/devices\n"
189 " DBGPATH indicates the debugfs path for the loopback greybus entries e.g.\n"
190 " /sys/kernel/debug/gb_loopback/\n"
191 " Mandatory arguments\n"
192 " -t must be one of the test names - sink, transfer or ping\n"
193 " -i iteration count - the number of iterations to run the test over\n"
194 " Optional arguments\n"
195 " -S sysfs location - location for greybus 'endo' entires default /sys/bus/greybus/devices/\n"
196 " -D debugfs location - location for loopback debugfs entries default /sys/kernel/debug/gb_loopback/\n"
197 " -s size of data packet to send during test - defaults to zero\n"
198 " -m mask - a bit mask of connections to include example: -m 8 = 4th connection -m 9 = 1st and 4th connection etc\n"
199 " default is zero which means broadcast to all connections\n"
200 " -v verbose output\n"
202 " -r raw data output - when specified the full list of latency values are included in the output CSV\n"
203 " -p porcelain - when specified printout is in a user-friendly non-CSV format. This option suppresses writing to CSV file\n"
204 " -a aggregate - show aggregation of all enabled devices\n"
205 " -l list found loopback devices and exit\n"
206 " -x Async - Enable async transfers\n"
207 " -o Async Timeout - Timeout in uSec for async operations\n"
208 " -O Poll loop time out in seconds(max time a test is expected to last, default: 30sec)\n"
209 " -c Max number of outstanding operations for async operations\n"
210 " -w Wait in uSec between operations\n"
211 " -z Enable output to a CSV file (incompatible with -p)\n"
212 " -f When starting new loopback test, stop currently running tests on all devices\n"
214 " Send 10000 transfers with a packet size of 128 bytes to all active connections\n"
215 " loopback_test -t transfer -s 128 -i 10000 -S /sys/bus/greybus/devices/ -D /sys/kernel/debug/gb_loopback/\n"
216 " loopback_test -t transfer -s 128 -i 10000 -m 0\n"
217 " Send 10000 transfers with a packet size of 128 bytes to connection 1 and 4\n"
218 " loopback_test -t transfer -s 128 -i 10000 -m 9\n"
219 " loopback_test -t ping -s 0 128 -i -S /sys/bus/greybus/devices/ -D /sys/kernel/debug/gb_loopback/\n"
220 " loopback_test -t sink -s 2030 -i 32768 -S /sys/bus/greybus/devices/ -D /sys/kernel/debug/gb_loopback/\n");
224 static inline int device_enabled(struct loopback_test *t, int dev_idx)
226 if (!t->mask || (t->mask & (1 << dev_idx)))
232 static void show_loopback_devices(struct loopback_test *t)
236 if (t->device_count == 0) {
237 printf("No loopback devices.\n");
241 for (i = 0; i < t->device_count; i++)
242 printf("device[%d] = %s\n", i, t->devices[i].name);
246 int open_sysfs(const char *sys_pfx, const char *node, int flags)
249 char path[MAX_SYSFS_PATH];
251 snprintf(path, sizeof(path), "%s%s", sys_pfx, node);
252 fd = open(path, flags);
254 fprintf(stderr, "unable to open %s\n", path);
260 int read_sysfs_int_fd(int fd, const char *sys_pfx, const char *node)
262 char buf[SYSFS_MAX_INT];
264 if (read(fd, buf, sizeof(buf)) < 0) {
265 fprintf(stderr, "unable to read from %s%s %s\n", sys_pfx, node,
273 float read_sysfs_float_fd(int fd, const char *sys_pfx, const char *node)
275 char buf[SYSFS_MAX_INT];
277 if (read(fd, buf, sizeof(buf)) < 0) {
279 fprintf(stderr, "unable to read from %s%s %s\n", sys_pfx, node,
287 int read_sysfs_int(const char *sys_pfx, const char *node)
291 fd = open_sysfs(sys_pfx, node, O_RDONLY);
292 val = read_sysfs_int_fd(fd, sys_pfx, node);
297 float read_sysfs_float(const char *sys_pfx, const char *node)
302 fd = open_sysfs(sys_pfx, node, O_RDONLY);
303 val = read_sysfs_float_fd(fd, sys_pfx, node);
308 void write_sysfs_val(const char *sys_pfx, const char *node, int val)
311 char buf[SYSFS_MAX_INT];
313 fd = open_sysfs(sys_pfx, node, O_RDWR);
314 len = snprintf(buf, sizeof(buf), "%d", val);
315 if (write(fd, buf, len) < 0) {
316 fprintf(stderr, "unable to write to %s%s %s\n", sys_pfx, node,
324 static int get_results(struct loopback_test *t)
326 struct loopback_device *d;
327 struct loopback_results *r;
330 for (i = 0; i < t->device_count; i++) {
331 if (!device_enabled(t, i))
337 r->error = read_sysfs_int(d->sysfs_entry, "error");
338 r->request_min = read_sysfs_int(d->sysfs_entry, "requests_per_second_min");
339 r->request_max = read_sysfs_int(d->sysfs_entry, "requests_per_second_max");
340 r->request_avg = read_sysfs_float(d->sysfs_entry, "requests_per_second_avg");
342 r->latency_min = read_sysfs_int(d->sysfs_entry, "latency_min");
343 r->latency_max = read_sysfs_int(d->sysfs_entry, "latency_max");
344 r->latency_avg = read_sysfs_float(d->sysfs_entry, "latency_avg");
346 r->throughput_min = read_sysfs_int(d->sysfs_entry, "throughput_min");
347 r->throughput_max = read_sysfs_int(d->sysfs_entry, "throughput_max");
348 r->throughput_avg = read_sysfs_float(d->sysfs_entry, "throughput_avg");
350 r->apbridge_unipro_latency_min =
351 read_sysfs_int(d->sysfs_entry, "apbridge_unipro_latency_min");
352 r->apbridge_unipro_latency_max =
353 read_sysfs_int(d->sysfs_entry, "apbridge_unipro_latency_max");
354 r->apbridge_unipro_latency_avg =
355 read_sysfs_float(d->sysfs_entry, "apbridge_unipro_latency_avg");
357 r->gbphy_firmware_latency_min =
358 read_sysfs_int(d->sysfs_entry, "gbphy_firmware_latency_min");
359 r->gbphy_firmware_latency_max =
360 read_sysfs_int(d->sysfs_entry, "gbphy_firmware_latency_max");
361 r->gbphy_firmware_latency_avg =
362 read_sysfs_float(d->sysfs_entry, "gbphy_firmware_latency_avg");
364 r->request_jitter = r->request_max - r->request_min;
365 r->latency_jitter = r->latency_max - r->latency_min;
366 r->throughput_jitter = r->throughput_max - r->throughput_min;
367 r->apbridge_unipro_latency_jitter =
368 r->apbridge_unipro_latency_max - r->apbridge_unipro_latency_min;
369 r->gbphy_firmware_latency_jitter =
370 r->gbphy_firmware_latency_max - r->gbphy_firmware_latency_min;
374 /*calculate the aggregate results of all enabled devices */
375 if (t->aggregate_output) {
376 r = &t->aggregate_results;
378 r->request_min = get_request_min_aggregate(t);
379 r->request_max = get_request_max_aggregate(t);
380 r->request_avg = get_request_avg_aggregate(t);
382 r->latency_min = get_latency_min_aggregate(t);
383 r->latency_max = get_latency_max_aggregate(t);
384 r->latency_avg = get_latency_avg_aggregate(t);
386 r->throughput_min = get_throughput_min_aggregate(t);
387 r->throughput_max = get_throughput_max_aggregate(t);
388 r->throughput_avg = get_throughput_avg_aggregate(t);
390 r->apbridge_unipro_latency_min =
391 get_apbridge_unipro_latency_min_aggregate(t);
392 r->apbridge_unipro_latency_max =
393 get_apbridge_unipro_latency_max_aggregate(t);
394 r->apbridge_unipro_latency_avg =
395 get_apbridge_unipro_latency_avg_aggregate(t);
397 r->gbphy_firmware_latency_min =
398 get_gbphy_firmware_latency_min_aggregate(t);
399 r->gbphy_firmware_latency_max =
400 get_gbphy_firmware_latency_max_aggregate(t);
401 r->gbphy_firmware_latency_avg =
402 get_gbphy_firmware_latency_avg_aggregate(t);
404 r->request_jitter = r->request_max - r->request_min;
405 r->latency_jitter = r->latency_max - r->latency_min;
406 r->throughput_jitter = r->throughput_max - r->throughput_min;
407 r->apbridge_unipro_latency_jitter =
408 r->apbridge_unipro_latency_max - r->apbridge_unipro_latency_min;
409 r->gbphy_firmware_latency_jitter =
410 r->gbphy_firmware_latency_max - r->gbphy_firmware_latency_min;
417 void log_csv_error(int len, int err)
419 fprintf(stderr, "unable to write %d bytes to csv %s\n", len,
423 int format_output(struct loopback_test *t,
424 struct loopback_results *r,
425 const char *dev_name,
426 char *buf, int buf_len,
431 memset(buf, 0x00, buf_len);
432 len = snprintf(buf, buf_len, "%u-%u-%u %u:%u:%u",
433 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
434 tm->tm_hour, tm->tm_min, tm->tm_sec);
437 len += snprintf(&buf[len], buf_len - len,
438 "\n test:\t\t\t%s\n path:\t\t\t%s\n size:\t\t\t%u\n iterations:\t\t%u\n errors:\t\t%u\n async:\t\t\t%s\n",
444 t->use_async ? "Enabled" : "Disabled");
446 len += snprintf(&buf[len], buf_len - len,
447 " requests per-sec:\tmin=%u, max=%u, average=%f, jitter=%u\n",
453 len += snprintf(&buf[len], buf_len - len,
454 " ap-throughput B/s:\tmin=%u max=%u average=%f jitter=%u\n",
458 r->throughput_jitter);
459 len += snprintf(&buf[len], buf_len - len,
460 " ap-latency usec:\tmin=%u max=%u average=%f jitter=%u\n",
465 len += snprintf(&buf[len], buf_len - len,
466 " apbridge-latency usec:\tmin=%u max=%u average=%f jitter=%u\n",
467 r->apbridge_unipro_latency_min,
468 r->apbridge_unipro_latency_max,
469 r->apbridge_unipro_latency_avg,
470 r->apbridge_unipro_latency_jitter);
472 len += snprintf(&buf[len], buf_len - len,
473 " gbphy-latency usec:\tmin=%u max=%u average=%f jitter=%u\n",
474 r->gbphy_firmware_latency_min,
475 r->gbphy_firmware_latency_max,
476 r->gbphy_firmware_latency_avg,
477 r->gbphy_firmware_latency_jitter);
480 len += snprintf(&buf[len], buf_len- len, ",%s,%s,%u,%u,%u",
481 t->test_name, dev_name, t->size, t->iteration_max,
484 len += snprintf(&buf[len], buf_len - len, ",%u,%u,%f,%u",
490 len += snprintf(&buf[len], buf_len - len, ",%u,%u,%f,%u",
496 len += snprintf(&buf[len], buf_len - len, ",%u,%u,%f,%u",
500 r->throughput_jitter);
502 len += snprintf(&buf[len], buf_len - len, ",%u,%u,%f,%u",
503 r->apbridge_unipro_latency_min,
504 r->apbridge_unipro_latency_max,
505 r->apbridge_unipro_latency_avg,
506 r->apbridge_unipro_latency_jitter);
508 len += snprintf(&buf[len], buf_len - len, ",%u,%u,%f,%u",
509 r->gbphy_firmware_latency_min,
510 r->gbphy_firmware_latency_max,
511 r->gbphy_firmware_latency_avg,
512 r->gbphy_firmware_latency_jitter);
515 printf("\n%s\n", buf);
520 static int log_results(struct loopback_test *t)
525 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
526 char file_name[MAX_SYSFS_PATH];
527 char data[CSV_MAX_LINE];
529 local_time = time(NULL);
530 tm = *localtime(&local_time);
533 * file name will test_name_size_iteration_max.csv
534 * every time the same test with the same parameters is run we will then
535 * append to the same CSV with datestamp - representing each test
538 if (t->file_output && !t->porcelain) {
539 snprintf(file_name, sizeof(file_name), "%s_%d_%d.csv",
540 t->test_name, t->size, t->iteration_max);
542 fd = open(file_name, O_WRONLY | O_CREAT | O_APPEND, mode);
544 fprintf(stderr, "unable to open %s for appendation\n", file_name);
549 for (i = 0; i < t->device_count; i++) {
550 if (!device_enabled(t, i))
553 len = format_output(t, &t->devices[i].results,
555 data, sizeof(data), &tm);
556 if (t->file_output && !t->porcelain) {
557 ret = write(fd, data, len);
559 fprintf(stderr, "unable to write %d bytes to csv.\n", len);
565 if (t->aggregate_output) {
566 len = format_output(t, &t->aggregate_results, "aggregate",
567 data, sizeof(data), &tm);
568 if (t->file_output && !t->porcelain) {
569 ret = write(fd, data, len);
571 fprintf(stderr, "unable to write %d bytes to csv.\n", len);
575 if (t->file_output && !t->porcelain)
581 int is_loopback_device(const char *path, const char *node)
583 char file[MAX_SYSFS_PATH];
585 snprintf(file, MAX_SYSFS_PATH, "%s%s/iteration_count", path, node);
586 if (access(file, F_OK) == 0)
591 int find_loopback_devices(struct loopback_test *t)
593 struct dirent **namelist;
596 struct loopback_device *d;
598 n = scandir(t->sysfs_prefix, &namelist, NULL, alphasort);
605 /* Don't include '.' and '..' */
611 for (i = 0; i < n; i++) {
612 ret = sscanf(namelist[i]->d_name, "gb_loopback%u", &dev_id);
616 if (!is_loopback_device(t->sysfs_prefix, namelist[i]->d_name))
619 if (t->device_count == MAX_NUM_DEVICES) {
620 fprintf(stderr, "max number of devices reached!\n");
624 d = &t->devices[t->device_count++];
625 snprintf(d->name, MAX_STR_LEN, "gb_loopback%u", dev_id);
627 snprintf(d->sysfs_entry, MAX_SYSFS_PATH, "%s%s/",
628 t->sysfs_prefix, d->name);
630 snprintf(d->debugfs_entry, MAX_SYSFS_PATH, "%sraw_latency_%s",
631 t->debugfs_prefix, d->name);
634 printf("add %s %s\n", d->sysfs_entry,
640 for (i = 0; i < n; i++)
647 static int open_poll_files(struct loopback_test *t)
649 struct loopback_device *dev;
650 char buf[MAX_SYSFS_PATH + MAX_STR_LEN];
655 for (i = 0; i < t->device_count; i++) {
656 dev = &t->devices[i];
658 if (!device_enabled(t, i))
661 snprintf(buf, sizeof(buf), "%s%s", dev->sysfs_entry, "iteration_count");
662 t->fds[fds_idx].fd = open(buf, O_RDONLY);
663 if (t->fds[fds_idx].fd < 0) {
664 fprintf(stderr, "Error opening poll file!\n");
667 read(t->fds[fds_idx].fd, &dummy, 1);
668 t->fds[fds_idx].events = POLLERR|POLLPRI;
669 t->fds[fds_idx].revents = 0;
673 t->poll_count = fds_idx;
678 for (i = 0; i < fds_idx; i++)
679 close(t->fds[fds_idx].fd);
684 static int close_poll_files(struct loopback_test *t)
687 for (i = 0; i < t->poll_count; i++)
692 static int is_complete(struct loopback_test *t)
697 for (i = 0; i < t->device_count; i++) {
698 if (!device_enabled(t, i))
701 iteration_count = read_sysfs_int(t->devices[i].sysfs_entry,
704 /* at least one device did not finish yet */
705 if (iteration_count != t->iteration_max)
712 static void stop_tests(struct loopback_test *t)
716 for (i = 0; i < t->device_count; i++) {
717 if (!device_enabled(t, i))
719 write_sysfs_val(t->devices[i].sysfs_entry, "type", 0);
723 static void handler(int sig) { /* do nothing */ }
725 static int wait_for_complete(struct loopback_test *t)
727 int number_of_events = 0;
731 struct timespec *ts = NULL;
733 sigset_t mask_old, mask;
736 sigemptyset(&mask_old);
737 sigaddset(&mask, SIGINT);
738 sigprocmask(SIG_BLOCK, &mask, &mask_old);
740 sa.sa_handler = handler;
742 sigemptyset(&sa.sa_mask);
743 if (sigaction(SIGINT, &sa, NULL) == -1) {
744 fprintf(stderr, "sigaction error\n");
748 if (t->poll_timeout.tv_sec != 0)
749 ts = &t->poll_timeout;
753 ret = ppoll(t->fds, t->poll_count, ts, &mask_old);
756 fprintf(stderr, "Poll exit with errno %d\n", errno);
760 for (i = 0; i < t->poll_count; i++) {
761 if (t->fds[i].revents & POLLPRI) {
762 /* Dummy read to clear the event */
763 read(t->fds[i].fd, &dummy, 1);
768 if (number_of_events == t->poll_count)
772 if (!is_complete(t)) {
773 fprintf(stderr, "Iteration count did not finish!\n");
780 static void prepare_devices(struct loopback_test *t)
784 /* Cancel any running tests on enabled devices. If
785 * stop_all option is given, stop test on all devices.
787 for (i = 0; i < t->device_count; i++)
788 if (t->stop_all || device_enabled(t, i))
789 write_sysfs_val(t->devices[i].sysfs_entry, "type", 0);
792 for (i = 0; i < t->device_count; i++) {
793 if (!device_enabled(t, i))
796 write_sysfs_val(t->devices[i].sysfs_entry, "us_wait",
799 /* Set operation size */
800 write_sysfs_val(t->devices[i].sysfs_entry, "size", t->size);
803 write_sysfs_val(t->devices[i].sysfs_entry, "iteration_max",
807 write_sysfs_val(t->devices[i].sysfs_entry,
809 write_sysfs_val(t->devices[i].sysfs_entry,
810 "timeout", t->async_timeout);
811 write_sysfs_val(t->devices[i].sysfs_entry,
812 "outstanding_operations_max",
813 t->async_outstanding_operations);
815 write_sysfs_val(t->devices[i].sysfs_entry,
820 static int start(struct loopback_test *t)
824 /* the test starts by writing test_id to the type file. */
825 for (i = 0; i < t->device_count; i++) {
826 if (!device_enabled(t, i))
829 write_sysfs_val(t->devices[i].sysfs_entry, "type", t->test_id);
836 void loopback_run(struct loopback_test *t)
841 for (i = 0; dict[i].name != NULL; i++) {
842 if (strstr(dict[i].name, t->test_name))
843 t->test_id = dict[i].type;
846 fprintf(stderr, "invalid test %s\n", t->test_name);
853 ret = open_poll_files(t);
859 ret = wait_for_complete(t);
872 printf("Error running test\n");
876 static int sanity_check(struct loopback_test *t)
880 if (t->device_count == 0) {
881 fprintf(stderr, "No loopback devices found\n");
885 for (i = 0; i < MAX_NUM_DEVICES; i++) {
886 if (!device_enabled(t, i))
889 if (t->mask && !strcmp(t->devices[i].name, "")) {
890 fprintf(stderr, "Bad device mask %x\n", (1 << i));
900 int main(int argc, char *argv[])
903 char *sysfs_prefix = "/sys/class/gb_loopback/";
904 char *debugfs_prefix = "/sys/kernel/debug/gb_loopback/";
906 memset(&t, 0, sizeof(t));
908 while ((o = getopt(argc, argv,
909 "t:s:i:S:D:m:v::d::r::p::a::l::x::o:O:c:w:z::f::")) != -1) {
912 snprintf(t.test_name, MAX_STR_LEN, "%s", optarg);
915 t.size = atoi(optarg);
918 t.iteration_max = atoi(optarg);
921 snprintf(t.sysfs_prefix, MAX_SYSFS_PREFIX, "%s", optarg);
924 snprintf(t.debugfs_prefix, MAX_SYSFS_PREFIX, "%s", optarg);
927 t.mask = atol(optarg);
942 t.aggregate_output = 1;
951 t.async_timeout = atoi(optarg);
954 t.poll_timeout.tv_sec = atoi(optarg);
957 t.async_outstanding_operations = atoi(optarg);
960 t.us_wait = atoi(optarg);
974 if (!strcmp(t.sysfs_prefix, ""))
975 snprintf(t.sysfs_prefix, MAX_SYSFS_PREFIX, "%s", sysfs_prefix);
977 if (!strcmp(t.debugfs_prefix, ""))
978 snprintf(t.debugfs_prefix, MAX_SYSFS_PREFIX, "%s", debugfs_prefix);
980 ret = find_loopback_devices(&t);
983 ret = sanity_check(&t);
987 if (t.list_devices) {
988 show_loopback_devices(&t);
992 if (t.test_name[0] == '\0' || t.iteration_max == 0)
995 if (t.async_timeout == 0)
996 t.async_timeout = DEFAULT_ASYNC_TIMEOUT;