1f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu#include <math.h> 2f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu#include "json.h" 3f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu#include "idletime.h" 4f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 5f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liustatic volatile struct idle_prof_common ipc; 6f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 7680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe/* 8680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe * Get time to complete an unit work on a particular cpu. 9f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu * The minimum number in CALIBRATE_RUNS runs is returned. 10f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu */ 11f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liustatic double calibrate_unit(unsigned char *data) 12f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu{ 13f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu unsigned long t, i, j, k; 14f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct timeval tps; 15f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu double tunit = 0.0; 16f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 17680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe for (i = 0; i < CALIBRATE_RUNS; i++) { 18f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 19f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu fio_gettime(&tps, NULL); 20f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* scale for less variance */ 21680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe for (j = 0; j < CALIBRATE_SCALE; j++) { 22f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* unit of work */ 23f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu for (k=0; k < page_size; k++) { 24680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe data[(k + j) % page_size] = k % 256; 25680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe /* 26680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe * we won't see STOP here. this is to match 27f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu * the same statement in the profiling loop. 28f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu */ 29f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.status == IDLE_PROF_STATUS_PROF_STOP) 30f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return 0.0; 31f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 32f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 33f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 34f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu t = utime_since_now(&tps); 35f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (!t) 36f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu continue; 37f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 38f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* get the minimum time to complete CALIBRATE_SCALE units */ 39680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe if ((i == 0) || ((double)t < tunit)) 40f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu tunit = (double)t; 41f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 42f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 43680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe return tunit / CALIBRATE_SCALE; 44f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu} 45f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 4659358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboestatic int set_cpu_affinity(struct idle_prof_thread *ipt) 4759358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe{ 4859358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe#if defined(FIO_HAVE_CPU_AFFINITY) 4959358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe os_cpu_mask_t cpu_mask; 5059358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe 5159358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe memset(&cpu_mask, 0, sizeof(cpu_mask)); 5259358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe fio_cpu_set(&cpu_mask, ipt->cpu); 5359358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe 5459358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe if (fio_setaffinity(gettid(), cpu_mask)) { 5559358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe log_err("fio: fio_setaffinity failed\n"); 5659358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe return -1; 5759358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe } 5859358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe 5959358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe return 0; 6059358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe#else 6159358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe log_err("fio: fio_setaffinity not supported\n"); 6259358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe return -1; 6359358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe#endif 6459358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe} 6559358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe 66f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liustatic void *idle_prof_thread_fn(void *data) 67f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu{ 68f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu int retval; 69f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu unsigned long j, k; 70f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct idle_prof_thread *ipt = data; 71f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 72f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* wait for all threads are spawned */ 73f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_lock(&ipt->init_lock); 74f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 75f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* exit if any other thread failed to start */ 76d5b351d483aabb0d0a0acd2930640428aa8e6339Jens Axboe if (ipc.status == IDLE_PROF_STATUS_ABORT) { 77d5b351d483aabb0d0a0acd2930640428aa8e6339Jens Axboe pthread_mutex_unlock(&ipt->init_lock); 78f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return NULL; 79d5b351d483aabb0d0a0acd2930640428aa8e6339Jens Axboe } 80f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 8159358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe retval = set_cpu_affinity(ipt); 82f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (retval == -1) { 83f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->state = TD_EXITED; 84f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_unlock(&ipt->init_lock); 85f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return NULL; 86f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 87f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 88f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->cali_time = calibrate_unit(ipt->data); 89f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 90f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* delay to set IDLE class till now for better calibration accuracy */ 917e09a9f10bb301635b6f9206b3144878a2710b0aJens Axboe#if defined(CONFIG_SCHED_IDLE) 92f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if ((retval = fio_set_sched_idle())) 93f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: fio_set_sched_idle failed\n"); 94f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu#else 95f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu retval = -1; 96f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: fio_set_sched_idle not supported\n"); 97f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu#endif 98f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (retval == -1) { 99f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->state = TD_EXITED; 100f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_unlock(&ipt->init_lock); 101f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return NULL; 102f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 103f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 104f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->state = TD_INITIALIZED; 105f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 106f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* signal the main thread that calibration is done */ 107f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_cond_signal(&ipt->cond); 108f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_unlock(&ipt->init_lock); 109f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 110f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* wait for other calibration to finish */ 111f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_lock(&ipt->start_lock); 112f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 113f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* exit if other threads failed to initialize */ 114735ed278a7ba6e3f1d5a0c08fc08149a2f435c37Jens Axboe if (ipc.status == IDLE_PROF_STATUS_ABORT) { 115735ed278a7ba6e3f1d5a0c08fc08149a2f435c37Jens Axboe pthread_mutex_unlock(&ipt->start_lock); 116f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return NULL; 117735ed278a7ba6e3f1d5a0c08fc08149a2f435c37Jens Axboe } 118f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 119f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* exit if we are doing calibration only */ 120735ed278a7ba6e3f1d5a0c08fc08149a2f435c37Jens Axboe if (ipc.status == IDLE_PROF_STATUS_CALI_STOP) { 121735ed278a7ba6e3f1d5a0c08fc08149a2f435c37Jens Axboe pthread_mutex_unlock(&ipt->start_lock); 122f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return NULL; 123735ed278a7ba6e3f1d5a0c08fc08149a2f435c37Jens Axboe } 124f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 125f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu fio_gettime(&ipt->tps, NULL); 126f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->state = TD_RUNNING; 127f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 128f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu j = 0; 129f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu while (1) { 130680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe for (k = 0; k < page_size; k++) { 131680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe ipt->data[(k + j) % page_size] = k % 256; 132f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.status == IDLE_PROF_STATUS_PROF_STOP) { 133f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu fio_gettime(&ipt->tpe, NULL); 134f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu goto idle_prof_done; 135f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 136f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 137f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu j++; 138f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 139f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 140f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liuidle_prof_done: 141f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 142680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe ipt->loops = j + (double) k / page_size; 143f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->state = TD_EXITED; 144f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_unlock(&ipt->start_lock); 145f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 146f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return NULL; 147f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu} 148f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 149f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu/* calculate mean and standard deviation to complete an unit of work */ 150f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liustatic void calibration_stats(void) 151f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu{ 152f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu int i; 153680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe double sum = 0.0, var = 0.0; 154f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct idle_prof_thread *ipt; 155f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 156f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu for (i = 0; i < ipc.nr_cpus; i++) { 157f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt = &ipc.ipts[i]; 158f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu sum += ipt->cali_time; 159f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 160f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 161f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.cali_mean = sum/ipc.nr_cpus; 162f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 163f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu for (i = 0; i < ipc.nr_cpus; i++) { 164f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt = &ipc.ipts[i]; 165f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu var += pow(ipt->cali_time-ipc.cali_mean, 2); 166f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 167f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 168f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.cali_stddev = sqrt(var/(ipc.nr_cpus-1)); 169f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu} 170f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 171f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liuvoid fio_idle_prof_init(void) 172f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu{ 173f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu int i, ret; 174f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct timeval tp; 175f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct timespec ts; 176680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe pthread_attr_t tattr; 177f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct idle_prof_thread *ipt; 178f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 179f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.nr_cpus = cpus_online(); 180f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.status = IDLE_PROF_STATUS_OK; 181f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 182f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt == IDLE_PROF_OPT_NONE) 183f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 184f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 185f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if ((ret = pthread_attr_init(&tattr))) { 186f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: pthread_attr_init %s\n", strerror(ret)); 187f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 188f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 189f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if ((ret = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM))) { 190f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: pthread_attr_setscope %s\n", strerror(ret)); 191f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 192f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 193f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 194f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.ipts = malloc(ipc.nr_cpus * sizeof(struct idle_prof_thread)); 195f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (!ipc.ipts) { 196f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: malloc failed\n"); 197f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 198f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 199f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 200f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.buf = malloc(ipc.nr_cpus * page_size); 201f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (!ipc.buf) { 202f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: malloc failed\n"); 203f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu free(ipc.ipts); 204f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 205f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 206f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 207680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe /* 208680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe * profiling aborts on any single thread failure since the 209f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu * result won't be accurate if any cpu is not used. 210f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu */ 211f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu for (i = 0; i < ipc.nr_cpus; i++) { 212f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt = &ipc.ipts[i]; 213f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 214f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->cpu = i; 215f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->state = TD_NOT_CREATED; 216f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->data = (unsigned char *)(ipc.buf + page_size * i); 217f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 218f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if ((ret = pthread_mutex_init(&ipt->init_lock, NULL))) { 219f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.status = IDLE_PROF_STATUS_ABORT; 220f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: pthread_mutex_init %s\n", strerror(ret)); 221f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu break; 222f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 223f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 224f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if ((ret = pthread_mutex_init(&ipt->start_lock, NULL))) { 225f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.status = IDLE_PROF_STATUS_ABORT; 226f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: pthread_mutex_init %s\n", strerror(ret)); 227f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu break; 228f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 229f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 230f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if ((ret = pthread_cond_init(&ipt->cond, NULL))) { 231f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.status = IDLE_PROF_STATUS_ABORT; 232f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: pthread_cond_init %s\n", strerror(ret)); 233f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu break; 234f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 235f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 236f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* make sure all threads are spawned before they start */ 237f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_lock(&ipt->init_lock); 238f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 239f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* make sure all threads finish init before profiling starts */ 240f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_lock(&ipt->start_lock); 241f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 242f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if ((ret = pthread_create(&ipt->thread, &tattr, idle_prof_thread_fn, ipt))) { 243f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.status = IDLE_PROF_STATUS_ABORT; 244f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: pthread_create %s\n", strerror(ret)); 245f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu break; 246680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe } else 247f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->state = TD_CREATED; 248f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 249f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if ((ret = pthread_detach(ipt->thread))) { 250f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* log error and let the thread spin */ 251f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: pthread_detatch %s\n", strerror(ret)); 252f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 253f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 254f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 255680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe /* 256680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe * let good threads continue so that they can exit 257680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe * if errors on other threads occurred previously. 258f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu */ 259f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu for (i = 0; i < ipc.nr_cpus; i++) { 260f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt = &ipc.ipts[i]; 261f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_unlock(&ipt->init_lock); 262f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 263f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 264f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.status == IDLE_PROF_STATUS_ABORT) 265f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 266f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 267f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* wait for calibration to finish */ 268f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu for (i = 0; i < ipc.nr_cpus; i++) { 269f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt = &ipc.ipts[i]; 270f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_lock(&ipt->init_lock); 271680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe while ((ipt->state != TD_EXITED) && 272680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe (ipt->state!=TD_INITIALIZED)) { 273f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu fio_gettime(&tp, NULL); 274f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ts.tv_sec = tp.tv_sec + 1; 275f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ts.tv_nsec = tp.tv_usec * 1000; 276f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_cond_timedwait(&ipt->cond, &ipt->init_lock, &ts); 277f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 278f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_unlock(&ipt->init_lock); 279f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 280680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe /* 281680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe * any thread failed to initialize would abort other threads 282f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu * later after fio_idle_prof_start. 283f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu */ 284f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipt->state == TD_EXITED) 285f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.status = IDLE_PROF_STATUS_ABORT; 286f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 287f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 288f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.status != IDLE_PROF_STATUS_ABORT) 289f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu calibration_stats(); 290680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe else 291f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.cali_mean = ipc.cali_stddev = 0.0; 292f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 293f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt == IDLE_PROF_OPT_CALI) 294f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.status = IDLE_PROF_STATUS_CALI_STOP; 295f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu} 296f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 297f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liuvoid fio_idle_prof_start(void) 298f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu{ 299f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu int i; 300f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct idle_prof_thread *ipt; 301f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 302f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt == IDLE_PROF_OPT_NONE) 303f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 304f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 305f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* unlock regardless abort is set or not */ 306f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu for (i = 0; i < ipc.nr_cpus; i++) { 307f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt = &ipc.ipts[i]; 308f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_unlock(&ipt->start_lock); 309f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 310f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu} 311f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 312f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liuvoid fio_idle_prof_stop(void) 313f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu{ 314f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu int i; 315f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu uint64_t runt; 316f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct timeval tp; 317f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct timespec ts; 318f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct idle_prof_thread *ipt; 319f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 320f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt == IDLE_PROF_OPT_NONE) 321f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 322f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 323f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt == IDLE_PROF_OPT_CALI) 324f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 325f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 326f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.status = IDLE_PROF_STATUS_PROF_STOP; 327f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 328f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* wait for all threads to exit from profiling */ 329f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu for (i = 0; i < ipc.nr_cpus; i++) { 330f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt = &ipc.ipts[i]; 331f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_lock(&ipt->start_lock); 332680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe while ((ipt->state != TD_EXITED) && 333680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe (ipt->state!=TD_NOT_CREATED)) { 334f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu fio_gettime(&tp, NULL); 335f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ts.tv_sec = tp.tv_sec + 1; 336f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ts.tv_nsec = tp.tv_usec * 1000; 337f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* timed wait in case a signal is not received */ 338f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_cond_timedwait(&ipt->cond, &ipt->start_lock, &ts); 339f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 340f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_unlock(&ipt->start_lock); 341f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 342f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* calculate idleness */ 343f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.cali_mean != 0.0) { 344f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu runt = utime_since(&ipt->tps, &ipt->tpe); 3459da67e75febb49f29b1657e93e592b656ec84f11Jens Axboe if (runt) 3469da67e75febb49f29b1657e93e592b656ec84f11Jens Axboe ipt->idleness = ipt->loops * ipc.cali_mean / runt; 3479da67e75febb49f29b1657e93e592b656ec84f11Jens Axboe else 3489da67e75febb49f29b1657e93e592b656ec84f11Jens Axboe ipt->idleness = 0.0; 349680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe } else 350f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->idleness = 0.0; 351f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 352f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 353680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe /* 354680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe * memory allocations are freed via explicit fio_idle_prof_cleanup 355f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu * after profiling stats are collected by apps. 356f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu */ 357f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu} 358f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 359680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe/* 360680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe * return system idle percentage when cpu is -1; 361f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu * return one cpu idle percentage otherwise. 362f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu */ 363f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liustatic double fio_idle_prof_cpu_stat(int cpu) 364f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu{ 365f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu int i, nr_cpus = ipc.nr_cpus; 366f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct idle_prof_thread *ipt; 367f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu double p = 0.0; 368f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 369f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt == IDLE_PROF_OPT_NONE) 370f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return 0.0; 371f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 372f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if ((cpu >= nr_cpus) || (cpu < -1)) { 373f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: idle profiling invalid cpu index\n"); 374f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return 0.0; 375f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 376f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 377f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (cpu == -1) { 378f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu for (i = 0; i < nr_cpus; i++) { 379f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt = &ipc.ipts[i]; 380f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu p += ipt->idleness; 381f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 382f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu p /= nr_cpus; 383f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } else { 384f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt = &ipc.ipts[cpu]; 385f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu p = ipt->idleness; 386f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 387f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 388680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe return p * 100.0; 389f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu} 390f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 39110aa136bddbaa7c845ab4eacb4a9a4a88d6657a3Jens Axboestatic void fio_idle_prof_cleanup(void) 392f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu{ 393f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.ipts) { 394f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu free(ipc.ipts); 395f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.ipts = NULL; 396f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 397f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 398f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.buf) { 399f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu free(ipc.buf); 400f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.buf = NULL; 401f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 402f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu} 403f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 404f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liuint fio_idle_prof_parse_opt(const char *args) 405f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu{ 406f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.opt = IDLE_PROF_OPT_NONE; /* default */ 407f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 408f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (!args) { 409f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: empty idle-prof option string\n"); 410f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return -1; 411f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 412f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 4137e09a9f10bb301635b6f9206b3144878a2710b0aJens Axboe#if defined(FIO_HAVE_CPU_AFFINITY) && defined(CONFIG_SCHED_IDLE) 414f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (strcmp("calibrate", args) == 0) { 415f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.opt = IDLE_PROF_OPT_CALI; 416f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu fio_idle_prof_init(); 417f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu fio_idle_prof_start(); 418f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu fio_idle_prof_stop(); 419f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu show_idle_prof_stats(FIO_OUTPUT_NORMAL, NULL); 420f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return 1; 421f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } else if (strcmp("system", args) == 0) { 422f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.opt = IDLE_PROF_OPT_SYSTEM; 423f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return 0; 424f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } else if (strcmp("percpu", args) == 0) { 425f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.opt = IDLE_PROF_OPT_PERCPU; 426f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return 0; 427f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } else { 4284e0a8fa2593006505b7f4e18931a201d221b49e9Jens Axboe log_err("fio: incorrect idle-prof option: %s\n", args); 429f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return -1; 430f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 431f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu#else 432f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: idle-prof not supported on this platform\n"); 433f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return -1; 434f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu#endif 435f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu} 436f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 437f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liuvoid show_idle_prof_stats(int output, struct json_object *parent) 438f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu{ 439f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu int i, nr_cpus = ipc.nr_cpus; 440f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct json_object *tmp; 441f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu char s[MAX_CPU_STR_LEN]; 442680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe 443f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (output == FIO_OUTPUT_NORMAL) { 444f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt > IDLE_PROF_OPT_CALI) 445f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_info("\nCPU idleness:\n"); 446f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu else if (ipc.opt == IDLE_PROF_OPT_CALI) 447f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_info("CPU idleness:\n"); 448f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 449f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt >= IDLE_PROF_OPT_SYSTEM) 450f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_info(" system: %3.2f%%\n", fio_idle_prof_cpu_stat(-1)); 451f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 452f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt == IDLE_PROF_OPT_PERCPU) { 453f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_info(" percpu: %3.2f%%", fio_idle_prof_cpu_stat(0)); 454680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe for (i = 1; i < nr_cpus; i++) 455f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_info(", %3.2f%%", fio_idle_prof_cpu_stat(i)); 456f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_info("\n"); 457f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 458f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 459f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt >= IDLE_PROF_OPT_CALI) { 460f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_info(" unit work: mean=%3.2fus,", ipc.cali_mean); 461f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_info(" stddev=%3.2f\n", ipc.cali_stddev); 462f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 463f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 464f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* dynamic mem allocations can now be freed */ 465f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt != IDLE_PROF_OPT_NONE) 466f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu fio_idle_prof_cleanup(); 467f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 468f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 469f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 470680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe 471f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if ((ipc.opt != IDLE_PROF_OPT_NONE) && (output == FIO_OUTPUT_JSON)) { 472f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (!parent) 473f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 474f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 475f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu tmp = json_create_object(); 476f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (!tmp) 477f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 478f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 479f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu json_object_add_value_object(parent, "cpu_idleness", tmp); 480f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu json_object_add_value_float(tmp, "system", fio_idle_prof_cpu_stat(-1)); 481f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 482f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt == IDLE_PROF_OPT_PERCPU) { 483680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe for (i = 0; i < nr_cpus; i++) { 484f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu snprintf(s, MAX_CPU_STR_LEN, "cpu-%d", i); 485f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu json_object_add_value_float(tmp, s, fio_idle_prof_cpu_stat(i)); 486f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 487f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 488f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 489f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu json_object_add_value_float(tmp, "unit_mean", ipc.cali_mean); 490f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu json_object_add_value_float(tmp, "unit_stddev", ipc.cali_stddev); 491f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 492f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu fio_idle_prof_cleanup(); 493f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 494f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu} 495