* [PATCH] xfstests: update aio-stress.c, with copyright information intact
@ 2009-06-05 16:20 Eric Sandeen
2009-06-05 19:10 ` Christoph Hellwig
0 siblings, 1 reply; 2+ messages in thread
From: Eric Sandeen @ 2009-06-05 16:20 UTC (permalink / raw)
To: xfs mailing list
Pulled from:
http://ltp.cvs.sourceforge.net/viewvc/ltp/ltp/testcases/kernel/io/ltp-aiodio/aio-stress.c
revision 1.8
There are a couple new options, but the main motivator is to
get the license text intact again.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---
iff --git a/ltp/aio-stress.c b/ltp/aio-stress.c
index 6ebe082..ab9e006 100644
--- a/ltp/aio-stress.c
+++ b/ltp/aio-stress.c
@@ -1,7 +1,45 @@
/*
+ * Copyright (c) 2004 SuSE, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ *
+ * aio-stress
+ *
+ * will open or create each file on the command line, and start a series
+ * of aio to it.
+ *
+ * aio is done in a rotating loop. first file1 gets 8 requests, then
+ * file2, then file3 etc. As each file finishes writing, it is switched
+ * to reads
+ *
+ * io buffers are aligned in case you want to do raw io
+ *
+ * compile with gcc -Wall -laio -lpthread -o aio-stress aio-stress.c
+ *
+ * run aio-stress -h to see the options
+ *
+ * Please mail Chris Mason (mason@suse.com) with bug reports or patches
*/
#define _FILE_OFFSET_BITS 64
-#define PROG_VERSION "0.18"
+#define PROG_VERSION "0.21"
#define NEW_GETEVENTS
#include <stdio.h>
@@ -50,6 +88,7 @@ unsigned long page_size_mask;
int o_direct = 0;
int o_sync = 0;
int latency_stats = 0;
+int completion_latency_stats = 0;
int io_iter = 8;
int iterations = RUN_FOREVER;
int max_io_submit = 0;
@@ -67,6 +106,7 @@ int padded_reclen = 0;
int stonewall = 1;
int verify = 0;
char *verify_buf = NULL;
+int unlink_files = 0;
struct io_unit;
struct thread_info;
@@ -164,6 +204,8 @@ struct io_unit {
long res;
struct io_unit *next;
+
+ struct timeval io_start_time; /* time of io_submit */
};
struct thread_info {
@@ -203,15 +245,20 @@ struct thread_info {
/* how much io this thread did in the last stage */
double stage_mb_trans;
+
+ /* latency completion stats i/o time from io_submit until io_getevents */
+ struct io_latency io_completion_latency;
};
-static double time_since(struct timeval *tv) {
+/*
+ * return seconds between start_tv and stop_tv in double precision
+ */
+static double time_since(struct timeval *start_tv, struct timeval *stop_tv)
+{
double sec, usec;
double ret;
- struct timeval stop;
- gettimeofday(&stop, NULL);
- sec = stop.tv_sec - tv->tv_sec;
- usec = stop.tv_usec - tv->tv_usec;
+ sec = stop_tv->tv_sec - start_tv->tv_sec;
+ usec = stop_tv->tv_usec - start_tv->tv_usec;
if (sec > 0 && usec < 0) {
sec--;
usec += 1000000;
@@ -222,11 +269,25 @@ static double time_since(struct timeval *tv) {
return ret;
}
-static void calc_latency(struct timeval *tv, struct io_latency *lat)
+/*
+ * return seconds between start_tv and now in double precision
+ */
+static double time_since_now(struct timeval *start_tv)
+{
+ struct timeval stop_time;
+ gettimeofday(&stop_time, NULL);
+ return time_since(start_tv, &stop_time);
+}
+
+/*
+ * Add latency info to latency struct
+ */
+static void calc_latency(struct timeval *start_tv, struct timeval *stop_tv,
+ struct io_latency *lat)
{
double delta;
int i;
- delta = time_since(tv);
+ delta = time_since(start_tv, stop_tv);
delta = delta * 1000;
if (delta > lat->max)
@@ -344,20 +405,19 @@ static void print_time(struct io_oper *oper) {
double tput;
double mb;
- runtime = time_since(&oper->start_time);
+ runtime = time_since_now(&oper->start_time);
mb = oper_mb_trans(oper);
tput = mb / runtime;
fprintf(stderr, "%s on %s (%.2f MB/s) %.2f MB in %.2fs\n",
stage_name(oper->rw), oper->file_name, tput, mb, runtime);
}
-static void print_latency(struct thread_info *t) {
- struct io_latency *lat = &t->io_submit_latency;
+static void print_lat(char *str, struct io_latency *lat) {
double avg = lat->total_lat / lat->total_io;
int i;
double total_counted = 0;
- fprintf(stderr, "latency min %.2f avg %.2f max %.2f\n\t",
- lat->min, avg, lat->max);
+ fprintf(stderr, "%s min %.2f avg %.2f max %.2f\n\t",
+ str, lat->min, avg, lat->max);
for (i = 0 ; i < DEVIATIONS ; i++) {
fprintf(stderr, " %.0f < %d", lat->deviations[i], deviations[i]);
@@ -366,16 +426,30 @@ static void print_latency(struct thread_info *t) {
if (total_counted && lat->total_io - total_counted)
fprintf(stderr, " < %.0f", lat->total_io - total_counted);
fprintf(stderr, "\n");
- memset(&t->io_submit_latency, 0, sizeof(t->io_submit_latency));
+ memset(lat, 0, sizeof(*lat));
+}
+
+static void print_latency(struct thread_info *t)
+{
+ struct io_latency *lat = &t->io_submit_latency;
+ print_lat("latency", lat);
+}
+
+static void print_completion_latency(struct thread_info *t)
+{
+ struct io_latency *lat = &t->io_completion_latency;
+ print_lat("completion latency", lat);
}
/*
* updates the fields in the io operation struct that belongs to this
* io unit, and make the io unit reusable again
*/
-void finish_io(struct thread_info *t, struct io_unit *io, long result) {
+void finish_io(struct thread_info *t, struct io_unit *io, long result,
+ struct timeval *tv_now) {
struct io_oper *oper = io->io_oper;
+ calc_latency(&io->io_start_time, tv_now, &t->io_completion_latency);
io->res = result;
io->busy = IO_FREE;
io->next = t->free_ious;
@@ -396,6 +470,7 @@ int read_some_events(struct thread_info *t) {
int nr;
int i;
int min_nr = io_iter;
+ struct timeval stop_time;
if (t->num_global_pending < io_iter)
min_nr = t->num_global_pending;
@@ -408,10 +483,11 @@ int read_some_events(struct thread_info *t) {
if (nr <= 0)
return nr;
+ gettimeofday(&stop_time, NULL);
for (i = 0 ; i < nr ; i++) {
event = t->events + i;
event_io = (struct io_unit *)((unsigned long)event->obj);
- finish_io(t, event_io, event->res);
+ finish_io(t, event_io, event->res, &stop_time);
}
return nr;
}
@@ -465,9 +541,11 @@ static int io_oper_wait(struct thread_info *t, struct io_oper *oper) {
#else
while(io_getevents(t->io_ctx, 1, &event, NULL) > 0) {
#endif
+ struct timeval tv_now;
event_io = (struct io_unit *)((unsigned long)event.obj);
- finish_io(t, event_io, event.res);
+ gettimeofday(&tv_now, NULL);
+ finish_io(t, event_io, event.res, &tv_now);
if (oper->num_pending == 0)
break;
@@ -641,7 +719,8 @@ int build_oper(struct thread_info *t, struct io_oper *oper, int num_ios,
* runs through the iocbs in the array provided and updates
* counters in the associated oper struct
*/
-static void update_iou_counters(struct iocb **my_iocbs, int nr)
+static void update_iou_counters(struct iocb **my_iocbs, int nr,
+ struct timeval *tv_now)
{
struct io_unit *io;
int i;
@@ -649,6 +728,7 @@ static void update_iou_counters(struct iocb **my_iocbs, int nr)
io = (struct io_unit *)(my_iocbs[i]);
io->io_oper->num_pending++;
io->io_oper->started_ios++;
+ io->io_start_time = *tv_now; /* set time of io_submit */
}
}
@@ -657,15 +737,18 @@ int run_built(struct thread_info *t, int num_ios, struct iocb **my_iocbs)
{
int ret;
struct timeval start_time;
+ struct timeval stop_time;
resubmit:
gettimeofday(&start_time, NULL);
ret = io_submit(t->io_ctx, num_ios, my_iocbs);
- calc_latency(&start_time, &t->io_submit_latency);
+ gettimeofday(&stop_time, NULL);
+ calc_latency(&start_time, &stop_time, &t->io_submit_latency);
+
if (ret != num_ios) {
/* some ios got through */
if (ret > 0) {
- update_iou_counters(my_iocbs, ret);
+ update_iou_counters(my_iocbs, ret, &stop_time);
my_iocbs += ret;
t->num_global_pending += ret;
num_ios -= ret;
@@ -675,15 +758,19 @@ resubmit:
* retry
*/
if (ret > 0 || ret == -EAGAIN) {
+ int old_ret = ret;
if ((ret = read_some_events(t) > 0)) {
goto resubmit;
+ } else {
+ fprintf(stderr, "ret was %d and now is %d\n", ret, old_ret);
+ abort();
}
}
fprintf(stderr, "ret %d (%s) on io_submit\n", ret, strerror(-ret));
return -1;
}
- update_iou_counters(my_iocbs, ret);
+ update_iou_counters(my_iocbs, ret, &stop_time);
t->num_global_pending += ret;
return 0;
}
@@ -972,7 +1059,7 @@ free_buffers:
*/
void global_thread_throughput(struct thread_info *t, char *this_stage) {
int i;
- double runtime = time_since(&global_stage_start_time);
+ double runtime = time_since_now(&global_stage_start_time);
double total_mb = 0;
double min_trans = 0;
@@ -1013,121 +1100,109 @@ int worker(struct thread_info *t)
aio_setup(&t->io_ctx, 512);
restart:
- printf("Starting %s iter:%d \n", __FUNCTION__,iteration);
if (num_threads > 1) {
- printf("num_threads %d \n", num_threads);
pthread_mutex_lock(&stage_mutex);
- threads_starting++;
- if (threads_starting == num_threads) {
- threads_ending = 0;
- gettimeofday(&global_stage_start_time, NULL);
- pthread_cond_broadcast(&stage_cond);
- }
- while (threads_starting != num_threads)
- pthread_cond_wait(&stage_cond, &stage_mutex);
+ threads_starting++;
+ if (threads_starting == num_threads) {
+ threads_ending = 0;
+ gettimeofday(&global_stage_start_time, NULL);
+ pthread_cond_broadcast(&stage_cond);
+ }
+ while (threads_starting != num_threads)
+ pthread_cond_wait(&stage_cond, &stage_mutex);
pthread_mutex_unlock(&stage_mutex);
}
if (t->active_opers) {
-// printf("active_opers %p line:%d\n", t->active_opers, __LINE__);
this_stage = stage_name(t->active_opers->rw);
- gettimeofday(&stage_time, NULL);
- t->stage_mb_trans = 0;
+ gettimeofday(&stage_time, NULL);
+ t->stage_mb_trans = 0;
}
+
cnt = 0;
/* first we send everything through aio */
-// printf("cnt:%d max_iterations:%d oper:%p\n",cnt, iterations,oper);
-
- while (t->active_opers && (cnt < iterations || iterations == RUN_FOREVER)) {
-// printf("active_opers %p line:%d cnt:%d ", t->active_opers,__LINE__,cnt);
- if (stonewall && threads_ending) {
- oper = t->active_opers;
- oper->stonewalled = 1;
- oper_list_del(oper, &t->active_opers);
- oper_list_add(oper, &t->finished_opers);
-// printf(" if branch\n");
- } else {
- run_active_list(t, io_iter, max_io_submit);
-// printf(" else branch\n");
+ while(t->active_opers && (cnt < iterations || iterations == RUN_FOREVER)) {
+ if (stonewall && threads_ending) {
+ oper = t->active_opers;
+ oper->stonewalled = 1;
+ oper_list_del(oper, &t->active_opers);
+ oper_list_add(oper, &t->finished_opers);
+ } else {
+ run_active_list(t, io_iter, max_io_submit);
}
- cnt++;
+ cnt++;
}
-
if (latency_stats)
print_latency(t);
+ if (completion_latency_stats)
+ print_completion_latency(t);
+
/* then we wait for all the operations to finish */
oper = t->finished_opers;
-// printf("line:%d oper:%p\n", __LINE__, oper);
do {
- io_oper_wait(t, oper);
- if (oper != NULL) {
- oper = oper->next;
- }
- } while (oper != t->finished_opers);
-// printf("finished_opers %p line:%d\n", t->finished_opers,__LINE__);
+ if (!oper)
+ break;
+ io_oper_wait(t, oper);
+ oper = oper->next;
+ } while(oper != t->finished_opers);
/* then we do an fsync to get the timing for any future operations
* right, and check to see if any of these need to get restarted
*/
oper = t->finished_opers;
-// printf("oper %p line:%d\n", oper,__LINE__);
- while (oper) {
- if (fsync_stages)
+ while(oper) {
+ if (fsync_stages)
fsync(oper->fd);
- t->stage_mb_trans += oper_mb_trans(oper);
- if (restart_oper(oper)) {
- oper_list_del(oper, &t->finished_opers);
- oper_list_add(oper, &t->active_opers);
- oper = t->finished_opers;
- continue;
- }
- oper = oper->next;
- if (oper == t->finished_opers)
- break;
+ t->stage_mb_trans += oper_mb_trans(oper);
+ if (restart_oper(oper)) {
+ oper_list_del(oper, &t->finished_opers);
+ oper_list_add(oper, &t->active_opers);
+ oper = t->finished_opers;
+ continue;
+ }
+ oper = oper->next;
+ if (oper == t->finished_opers)
+ break;
}
if (t->stage_mb_trans && t->num_files > 0) {
-// printf("num_files %d line:%d\n", t->num_files,__LINE__);
- double seconds = time_since(&stage_time);
- fprintf(stderr, "thread %d %s totals (%.2f MB/s) %.2f MB in %.2fs\n",
- t - global_thread_info, this_stage, t->stage_mb_trans/seconds,
- t->stage_mb_trans, seconds);
+ double seconds = time_since_now(&stage_time);
+ fprintf(stderr, "thread %d %s totals (%.2f MB/s) %.2f MB in %.2fs\n",
+ t - global_thread_info, this_stage, t->stage_mb_trans/seconds,
+ t->stage_mb_trans, seconds);
}
if (num_threads > 1) {
-// printf("num_threads %d line:%d\n", num_threads,__LINE__);
- pthread_mutex_lock(&stage_mutex);
- threads_ending++;
- if (threads_ending == num_threads) {
- threads_starting = 0;
- pthread_cond_broadcast(&stage_cond);
- global_thread_throughput(t, this_stage);
- }
-// printf("threads_ending %d line:%d\n", threads_ending,__LINE__);
- while (threads_ending != num_threads)
- pthread_cond_wait(&stage_cond, &stage_mutex);
- pthread_mutex_unlock(&stage_mutex);
+ pthread_mutex_lock(&stage_mutex);
+ threads_ending++;
+ if (threads_ending == num_threads) {
+ threads_starting = 0;
+ pthread_cond_broadcast(&stage_cond);
+ global_thread_throughput(t, this_stage);
+ }
+ while(threads_ending != num_threads)
+ pthread_cond_wait(&stage_cond, &stage_mutex);
+ pthread_mutex_unlock(&stage_mutex);
}
-
+
/* someone got restarted, go back to the beginning */
if (t->active_opers && (cnt < iterations || iterations == RUN_FOREVER)) {
- iteration++;
+ iteration++;
goto restart;
}
/* finally, free all the ram */
-// printf("finished_opers %p line:%d\n", t->finished_opers,__LINE__);
- while (t->finished_opers) {
- oper = t->finished_opers;
- oper_list_del(oper, &t->finished_opers);
- status = finish_oper(t, oper);
+ while(t->finished_opers) {
+ oper = t->finished_opers;
+ oper_list_del(oper, &t->finished_opers);
+ status = finish_oper(t, oper);
}
if (t->num_global_pending) {
fprintf(stderr, "global num pending is %d\n", t->num_global_pending);
}
io_queue_release(t->io_ctx);
-
+
return status;
}
@@ -1138,7 +1213,6 @@ int run_workers(struct thread_info *t, int num_threads)
int thread_ret;
int i;
-// printf("%s num_threads %d line:%d\n", __FUNCTION__,num_threads,__LINE__);
for(i = 0 ; i < num_threads ; i++) {
ret = pthread_create(&t[i].tid, NULL, (start_routine)worker, t + i);
if (ret) {
@@ -1178,6 +1252,10 @@ off_t parse_size(char *size_arg, off_t mult) {
case 'K':
mult = 1024;
break;
+ case 'b':
+ case 'B':
+ mult = 1;
+ break;
}
ret = mult * num;
return ret;
@@ -1205,7 +1283,9 @@ void print_usage(void) {
printf("\t-m shmfs mmap a file in /dev/shm for io buffers\n");
printf("\t-n no fsyncs between write stage and read stage\n");
printf("\t-l print io_submit latencies after each stage\n");
+ printf("\t-L print io completion latencies after each stage\n");
printf("\t-t number of threads to run\n");
+ printf("\t-u unlink files after completion\n");
printf("\t-v verification of bytes written\n");
printf("\t-x turn off thread stonewalling\n");
printf("\t-h this message\n");
@@ -1232,7 +1312,7 @@ int main(int ac, char **av)
page_size_mask = getpagesize() - 1;
while(1) {
- c = getopt(ac, av, "a:b:c:C:m:s:r:d:i:I:o:t:lnhOSxv");
+ c = getopt(ac, av, "a:b:c:C:m:s:r:d:i:I:o:t:lLnhOSxvu");
if (c < 0)
break;
@@ -1270,6 +1350,9 @@ int main(int ac, char **av)
case 'l':
latency_stats = 1;
break;
+ case 'L':
+ completion_latency_stats = 1;
+ break;
case 'm':
if (!strcmp(optarg, "shm")) {
fprintf(stderr, "using ipc shm\n");
@@ -1296,6 +1379,9 @@ int main(int ac, char **av)
case 'x':
stonewall = 0;
break;
+ case 'u':
+ unlink_files = 1;
+ break;
case 'v':
verify = 1;
break;
@@ -1379,7 +1465,6 @@ int main(int ac, char **av)
for (j = 0 ; j < num_contexts ; j++) {
thread_index = open_fds % num_threads;
open_fds++;
-// fprintf(stderr, "adding file %s thread %d\n", av[i], thread_index);
rwfd = open(av[i], O_CREAT | O_RDWR | o_direct | o_sync, 0600);
assert(rwfd != -1);
@@ -1407,25 +1492,21 @@ int main(int ac, char **av)
if (num_threads > 1){
printf("Running multi thread version num_threads:%d\n", num_threads);
run_workers(t, num_threads);
- }
- else {
+ } else {
printf("Running single thread version \n");
- status = worker(t);
+ status = worker(t);
}
-
-
- for (i = optind ; i < ac ; i++) {
- printf("Cleaning up file %s \n", av[i]);
- unlink(av[i]);
+ if (unlink_files) {
+ for (i = optind ; i < ac ; i++) {
+ printf("Cleaning up file %s \n", av[i]);
+ unlink(av[i]);
+ }
}
if (status) {
- printf("non zero return %d \n", status);
- }
- else{
- printf("aio-stress Completed successfully %d \n", status);
+ exit(1);
}
-
- exit(0);
+ return status;
}
+
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] xfstests: update aio-stress.c, with copyright information intact
2009-06-05 16:20 [PATCH] xfstests: update aio-stress.c, with copyright information intact Eric Sandeen
@ 2009-06-05 19:10 ` Christoph Hellwig
0 siblings, 0 replies; 2+ messages in thread
From: Christoph Hellwig @ 2009-06-05 19:10 UTC (permalink / raw)
To: Eric Sandeen; +Cc: xfs mailing list
On Fri, Jun 05, 2009 at 11:20:44AM -0500, Eric Sandeen wrote:
> Pulled from:
> http://ltp.cvs.sourceforge.net/viewvc/ltp/ltp/testcases/kernel/io/ltp-aiodio/aio-stress.c
> revision 1.8
>
> There are a couple new options, but the main motivator is to
> get the license text intact again.
>
> Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Looks good,
Reviewed-by: Christoph Hellwig <hch@lst.de>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-06-05 19:10 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-05 16:20 [PATCH] xfstests: update aio-stress.c, with copyright information intact Eric Sandeen
2009-06-05 19:10 ` Christoph Hellwig
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.