X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=backend.c;h=9deef284e36b81be3012f837b7a3bfdd53d242c8;hp=c1c8f96774850a755681dffa710d0ee1550fe16b;hb=435228488ffd062f4eac710aaa862e04cd20dfee;hpb=49cba9b3e5fa6b30f0fdff52eaf83427ec1baa3f diff --git a/backend.c b/backend.c index c1c8f967..9deef284 100644 --- a/backend.c +++ b/backend.c @@ -204,7 +204,11 @@ static int __check_min_rate(struct thread_data *td, struct timeval *now, td->o.name, rate_iops); return 1; } else { - rate = ((iops - td->rate_blocks[ddir]) * 1000) / spent; + if (spent) + rate = ((iops - td->rate_blocks[ddir]) * 1000) / spent; + else + rate = 0; + if (rate < rate_iops_min || iops < td->rate_blocks[ddir]) { log_err("%s: min iops rate %u not met," @@ -641,7 +645,7 @@ static unsigned int exceeds_number_ios(struct thread_data *td) static int io_bytes_exceeded(struct thread_data *td) { - unsigned long long bytes; + unsigned long long bytes, limit; if (td_rw(td)) bytes = td->this_io_bytes[DDIR_READ] + td->this_io_bytes[DDIR_WRITE]; @@ -652,7 +656,12 @@ static int io_bytes_exceeded(struct thread_data *td) else bytes = td->this_io_bytes[DDIR_TRIM]; - return bytes >= td->o.size || exceeds_number_ios(td); + if (td->o.io_limit) + limit = td->o.io_limit; + else + limit = td->o.size; + + return bytes >= limit || exceeds_number_ios(td); } /* @@ -1114,13 +1123,14 @@ static int switch_ioscheduler(struct thread_data *td) /* * Read back and check that the selected scheduler is now the default. */ - memset(tmp, 0, sizeof(tmp)); - ret = fread(tmp, 1, sizeof(tmp) - 1, f); + ret = fread(tmp, sizeof(tmp), 1, f); if (ferror(f) || ret < 0) { td_verror(td, errno, "fread"); fclose(f); return 1; } + tmp[sizeof(tmp) - 1] = '\0'; + sprintf(tmp2, "[%s]", td->o.ioscheduler); if (!strstr(tmp, tmp2)) { @@ -1136,6 +1146,8 @@ static int switch_ioscheduler(struct thread_data *td) static int keep_running(struct thread_data *td) { + unsigned long long limit; + if (td->done) return 0; if (td->o.time_based) @@ -1147,14 +1159,19 @@ static int keep_running(struct thread_data *td) if (exceeds_number_ios(td)) return 0; - if (td->o.size != -1ULL && ddir_rw_sum(td->io_bytes) < td->o.size) { + if (td->o.io_limit) + limit = td->o.io_limit; + else + limit = td->o.size; + + if (limit != -1ULL && ddir_rw_sum(td->io_bytes) < limit) { uint64_t diff; /* * If the difference is less than the minimum IO size, we * are done. */ - diff = td->o.size - ddir_rw_sum(td->io_bytes); + diff = limit - ddir_rw_sum(td->io_bytes); if (diff < td_max_bs(td)) return 0; @@ -1322,6 +1339,7 @@ static void *thread_main(void *data) #ifdef CONFIG_LIBNUMA /* numa node setup */ if (o->numa_cpumask_set || o->numa_memmask_set) { + struct bitmask *mask; int ret; if (numa_available() < 0) { @@ -1330,7 +1348,9 @@ static void *thread_main(void *data) } if (o->numa_cpumask_set) { - ret = numa_run_on_node_mask(o->numa_cpunodesmask); + mask = numa_parse_nodestring(o->numa_cpunodes); + ret = numa_run_on_node_mask(mask); + numa_free_nodemask(mask); if (ret == -1) { td_verror(td, errno, \ "numa_run_on_node_mask failed\n"); @@ -1340,12 +1360,16 @@ static void *thread_main(void *data) if (o->numa_memmask_set) { + mask = NULL; + if (o->numa_memnodes) + mask = numa_parse_nodestring(o->numa_memnodes); + switch (o->numa_mem_mode) { case MPOL_INTERLEAVE: - numa_set_interleave_mask(o->numa_memnodesmask); + numa_set_interleave_mask(mask); break; case MPOL_BIND: - numa_set_membind(o->numa_memnodesmask); + numa_set_membind(mask); break; case MPOL_LOCAL: numa_set_localalloc(); @@ -1358,6 +1382,9 @@ static void *thread_main(void *data) break; } + if (mask) + numa_free_nodemask(mask); + } } #endif