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 463c9c470a4b176c739ad58e335f92fedbe549177fJens Axboestatic void free_cpu_affinity(struct idle_prof_thread *ipt) 473c9c470a4b176c739ad58e335f92fedbe549177fJens Axboe{ 483c9c470a4b176c739ad58e335f92fedbe549177fJens Axboe#if defined(FIO_HAVE_CPU_AFFINITY) 493c9c470a4b176c739ad58e335f92fedbe549177fJens Axboe fio_cpuset_exit(&ipt->cpu_mask); 503c9c470a4b176c739ad58e335f92fedbe549177fJens Axboe#endif 513c9c470a4b176c739ad58e335f92fedbe549177fJens Axboe} 523c9c470a4b176c739ad58e335f92fedbe549177fJens Axboe 5359358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboestatic int set_cpu_affinity(struct idle_prof_thread *ipt) 5459358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe{ 5559358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe#if defined(FIO_HAVE_CPU_AFFINITY) 563c9c470a4b176c739ad58e335f92fedbe549177fJens Axboe if (fio_cpuset_init(&ipt->cpu_mask)) { 573c9c470a4b176c739ad58e335f92fedbe549177fJens Axboe log_err("fio: cpuset init failed\n"); 583c9c470a4b176c739ad58e335f92fedbe549177fJens Axboe return -1; 593c9c470a4b176c739ad58e335f92fedbe549177fJens Axboe } 6059358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe 613c9c470a4b176c739ad58e335f92fedbe549177fJens Axboe fio_cpu_set(&ipt->cpu_mask, ipt->cpu); 6259358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe 633c9c470a4b176c739ad58e335f92fedbe549177fJens Axboe if (fio_setaffinity(gettid(), ipt->cpu_mask)) { 6459358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe log_err("fio: fio_setaffinity failed\n"); 653c9c470a4b176c739ad58e335f92fedbe549177fJens Axboe fio_cpuset_exit(&ipt->cpu_mask); 6659358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe return -1; 6759358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe } 6859358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe 6959358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe return 0; 7059358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe#else 7159358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe log_err("fio: fio_setaffinity not supported\n"); 7259358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe return -1; 7359358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe#endif 7459358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe} 7559358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe 76f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liustatic void *idle_prof_thread_fn(void *data) 77f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu{ 78f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu int retval; 79f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu unsigned long j, k; 80f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct idle_prof_thread *ipt = data; 81f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 82f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* wait for all threads are spawned */ 83f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_lock(&ipt->init_lock); 84f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 85f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* exit if any other thread failed to start */ 86d5b351d483aabb0d0a0acd2930640428aa8e6339Jens Axboe if (ipc.status == IDLE_PROF_STATUS_ABORT) { 87d5b351d483aabb0d0a0acd2930640428aa8e6339Jens Axboe pthread_mutex_unlock(&ipt->init_lock); 88f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return NULL; 89d5b351d483aabb0d0a0acd2930640428aa8e6339Jens Axboe } 90f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 9159358c8ef39efea4a2ab141d85b2deebf5cf34fdJens Axboe retval = set_cpu_affinity(ipt); 92f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (retval == -1) { 93f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->state = TD_EXITED; 94f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_unlock(&ipt->init_lock); 95f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return NULL; 96f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 97f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 98f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->cali_time = calibrate_unit(ipt->data); 99f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 100f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* delay to set IDLE class till now for better calibration accuracy */ 1017e09a9f10bb301635b6f9206b3144878a2710b0aJens Axboe#if defined(CONFIG_SCHED_IDLE) 102f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if ((retval = fio_set_sched_idle())) 103f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: fio_set_sched_idle failed\n"); 104f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu#else 105f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu retval = -1; 106f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: fio_set_sched_idle not supported\n"); 107f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu#endif 108f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (retval == -1) { 109f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->state = TD_EXITED; 110f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_unlock(&ipt->init_lock); 1113c9c470a4b176c739ad58e335f92fedbe549177fJens Axboe goto do_exit; 112f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 113f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 114f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->state = TD_INITIALIZED; 115f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 116f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* signal the main thread that calibration is done */ 117f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_cond_signal(&ipt->cond); 118f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_unlock(&ipt->init_lock); 119f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 120f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* wait for other calibration to finish */ 121f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_lock(&ipt->start_lock); 122f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 123f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* exit if other threads failed to initialize */ 124735ed278a7ba6e3f1d5a0c08fc08149a2f435c37Jens Axboe if (ipc.status == IDLE_PROF_STATUS_ABORT) { 125735ed278a7ba6e3f1d5a0c08fc08149a2f435c37Jens Axboe pthread_mutex_unlock(&ipt->start_lock); 1263c9c470a4b176c739ad58e335f92fedbe549177fJens Axboe goto do_exit; 127735ed278a7ba6e3f1d5a0c08fc08149a2f435c37Jens Axboe } 128f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 129f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* exit if we are doing calibration only */ 130735ed278a7ba6e3f1d5a0c08fc08149a2f435c37Jens Axboe if (ipc.status == IDLE_PROF_STATUS_CALI_STOP) { 131735ed278a7ba6e3f1d5a0c08fc08149a2f435c37Jens Axboe pthread_mutex_unlock(&ipt->start_lock); 1323c9c470a4b176c739ad58e335f92fedbe549177fJens Axboe goto do_exit; 133735ed278a7ba6e3f1d5a0c08fc08149a2f435c37Jens Axboe } 134f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 135f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu fio_gettime(&ipt->tps, NULL); 136f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->state = TD_RUNNING; 137f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 138f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu j = 0; 139f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu while (1) { 140680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe for (k = 0; k < page_size; k++) { 141680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe ipt->data[(k + j) % page_size] = k % 256; 142f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.status == IDLE_PROF_STATUS_PROF_STOP) { 143f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu fio_gettime(&ipt->tpe, NULL); 144f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu goto idle_prof_done; 145f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 146f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 147f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu j++; 148f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 149f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 150f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liuidle_prof_done: 151f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 152680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe ipt->loops = j + (double) k / page_size; 153f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->state = TD_EXITED; 154f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_unlock(&ipt->start_lock); 155f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 1563c9c470a4b176c739ad58e335f92fedbe549177fJens Axboedo_exit: 1573c9c470a4b176c739ad58e335f92fedbe549177fJens Axboe free_cpu_affinity(ipt); 158f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return NULL; 159f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu} 160f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 161f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu/* calculate mean and standard deviation to complete an unit of work */ 162f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liustatic void calibration_stats(void) 163f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu{ 164f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu int i; 165680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe double sum = 0.0, var = 0.0; 166f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct idle_prof_thread *ipt; 167f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 168f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu for (i = 0; i < ipc.nr_cpus; i++) { 169f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt = &ipc.ipts[i]; 170f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu sum += ipt->cali_time; 171f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 172f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 173f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.cali_mean = sum/ipc.nr_cpus; 174f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 175f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu for (i = 0; i < ipc.nr_cpus; i++) { 176f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt = &ipc.ipts[i]; 177f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu var += pow(ipt->cali_time-ipc.cali_mean, 2); 178f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 179f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 180f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.cali_stddev = sqrt(var/(ipc.nr_cpus-1)); 181f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu} 182f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 183f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liuvoid fio_idle_prof_init(void) 184f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu{ 185f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu int i, ret; 186f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct timeval tp; 187f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct timespec ts; 188680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe pthread_attr_t tattr; 189f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct idle_prof_thread *ipt; 190f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 191f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.nr_cpus = cpus_online(); 192f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.status = IDLE_PROF_STATUS_OK; 193f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 194f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt == IDLE_PROF_OPT_NONE) 195f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 196f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 197f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if ((ret = pthread_attr_init(&tattr))) { 198f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: pthread_attr_init %s\n", strerror(ret)); 199f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 200f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 201f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if ((ret = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM))) { 202f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: pthread_attr_setscope %s\n", strerror(ret)); 203f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 204f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 205f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 206f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.ipts = malloc(ipc.nr_cpus * sizeof(struct idle_prof_thread)); 207f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (!ipc.ipts) { 208f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: malloc failed\n"); 209f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 210f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 211f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 212f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.buf = malloc(ipc.nr_cpus * page_size); 213f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (!ipc.buf) { 214f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: malloc failed\n"); 215f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu free(ipc.ipts); 216f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 217f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 218f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 219680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe /* 220680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe * profiling aborts on any single thread failure since the 221f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu * result won't be accurate if any cpu is not used. 222f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu */ 223f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu for (i = 0; i < ipc.nr_cpus; i++) { 224f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt = &ipc.ipts[i]; 225f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 226f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->cpu = i; 227f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->state = TD_NOT_CREATED; 228f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->data = (unsigned char *)(ipc.buf + page_size * i); 229f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 230f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if ((ret = pthread_mutex_init(&ipt->init_lock, NULL))) { 231f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.status = IDLE_PROF_STATUS_ABORT; 232f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: pthread_mutex_init %s\n", strerror(ret)); 233f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu break; 234f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 235f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 236f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if ((ret = pthread_mutex_init(&ipt->start_lock, NULL))) { 237f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.status = IDLE_PROF_STATUS_ABORT; 238f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: pthread_mutex_init %s\n", strerror(ret)); 239f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu break; 240f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 241f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 242f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if ((ret = pthread_cond_init(&ipt->cond, NULL))) { 243f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.status = IDLE_PROF_STATUS_ABORT; 244f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: pthread_cond_init %s\n", strerror(ret)); 245f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu break; 246f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 247f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 248f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* make sure all threads are spawned before they start */ 249f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_lock(&ipt->init_lock); 250f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 251f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* make sure all threads finish init before profiling starts */ 252f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_lock(&ipt->start_lock); 253f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 254f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if ((ret = pthread_create(&ipt->thread, &tattr, idle_prof_thread_fn, ipt))) { 255f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.status = IDLE_PROF_STATUS_ABORT; 256f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: pthread_create %s\n", strerror(ret)); 257f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu break; 258680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe } else 259f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->state = TD_CREATED; 260f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 261f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if ((ret = pthread_detach(ipt->thread))) { 262f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* log error and let the thread spin */ 263f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: pthread_detatch %s\n", strerror(ret)); 264f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 265f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 266f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 267680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe /* 268680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe * let good threads continue so that they can exit 269680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe * if errors on other threads occurred previously. 270f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu */ 271f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu for (i = 0; i < ipc.nr_cpus; i++) { 272f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt = &ipc.ipts[i]; 273f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_unlock(&ipt->init_lock); 274f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 275f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 276f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.status == IDLE_PROF_STATUS_ABORT) 277f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 278f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 279f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* wait for calibration to finish */ 280f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu for (i = 0; i < ipc.nr_cpus; i++) { 281f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt = &ipc.ipts[i]; 282f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_lock(&ipt->init_lock); 283680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe while ((ipt->state != TD_EXITED) && 284680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe (ipt->state!=TD_INITIALIZED)) { 285f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu fio_gettime(&tp, NULL); 286f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ts.tv_sec = tp.tv_sec + 1; 287f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ts.tv_nsec = tp.tv_usec * 1000; 288f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_cond_timedwait(&ipt->cond, &ipt->init_lock, &ts); 289f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 290f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_unlock(&ipt->init_lock); 291f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 292680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe /* 293680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe * any thread failed to initialize would abort other threads 294f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu * later after fio_idle_prof_start. 295f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu */ 296f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipt->state == TD_EXITED) 297f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.status = IDLE_PROF_STATUS_ABORT; 298f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 299f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 300f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.status != IDLE_PROF_STATUS_ABORT) 301f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu calibration_stats(); 302680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe else 303f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.cali_mean = ipc.cali_stddev = 0.0; 304f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 305f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt == IDLE_PROF_OPT_CALI) 306f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.status = IDLE_PROF_STATUS_CALI_STOP; 307f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu} 308f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 309f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liuvoid fio_idle_prof_start(void) 310f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu{ 311f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu int i; 312f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct idle_prof_thread *ipt; 313f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 314f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt == IDLE_PROF_OPT_NONE) 315f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 316f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 317f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* unlock regardless abort is set or not */ 318f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu for (i = 0; i < ipc.nr_cpus; i++) { 319f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt = &ipc.ipts[i]; 320f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_unlock(&ipt->start_lock); 321f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 322f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu} 323f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 324f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liuvoid fio_idle_prof_stop(void) 325f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu{ 326f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu int i; 327f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu uint64_t runt; 328f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct timeval tp; 329f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct timespec ts; 330f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct idle_prof_thread *ipt; 331f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 332f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt == IDLE_PROF_OPT_NONE) 333f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 334f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 335f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt == IDLE_PROF_OPT_CALI) 336f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 337f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 338f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.status = IDLE_PROF_STATUS_PROF_STOP; 339f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 340f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* wait for all threads to exit from profiling */ 341f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu for (i = 0; i < ipc.nr_cpus; i++) { 342f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt = &ipc.ipts[i]; 343f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_lock(&ipt->start_lock); 344680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe while ((ipt->state != TD_EXITED) && 345680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe (ipt->state!=TD_NOT_CREATED)) { 346f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu fio_gettime(&tp, NULL); 347f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ts.tv_sec = tp.tv_sec + 1; 348f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ts.tv_nsec = tp.tv_usec * 1000; 349f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* timed wait in case a signal is not received */ 350f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_cond_timedwait(&ipt->cond, &ipt->start_lock, &ts); 351f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 352f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu pthread_mutex_unlock(&ipt->start_lock); 353f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 354f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* calculate idleness */ 355f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.cali_mean != 0.0) { 356f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu runt = utime_since(&ipt->tps, &ipt->tpe); 3579da67e75febb49f29b1657e93e592b656ec84f11Jens Axboe if (runt) 3589da67e75febb49f29b1657e93e592b656ec84f11Jens Axboe ipt->idleness = ipt->loops * ipc.cali_mean / runt; 3599da67e75febb49f29b1657e93e592b656ec84f11Jens Axboe else 3609da67e75febb49f29b1657e93e592b656ec84f11Jens Axboe ipt->idleness = 0.0; 361680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe } else 362f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt->idleness = 0.0; 363f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 364f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 365680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe /* 366680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe * memory allocations are freed via explicit fio_idle_prof_cleanup 367f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu * after profiling stats are collected by apps. 368f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu */ 369f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu} 370f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 371680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe/* 372680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe * return system idle percentage when cpu is -1; 373f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu * return one cpu idle percentage otherwise. 374f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu */ 375f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liustatic double fio_idle_prof_cpu_stat(int cpu) 376f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu{ 377f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu int i, nr_cpus = ipc.nr_cpus; 378f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct idle_prof_thread *ipt; 379f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu double p = 0.0; 380f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 381f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt == IDLE_PROF_OPT_NONE) 382f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return 0.0; 383f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 384f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if ((cpu >= nr_cpus) || (cpu < -1)) { 385f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: idle profiling invalid cpu index\n"); 386f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return 0.0; 387f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 388f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 389f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (cpu == -1) { 390f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu for (i = 0; i < nr_cpus; i++) { 391f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt = &ipc.ipts[i]; 392f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu p += ipt->idleness; 393f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 394f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu p /= nr_cpus; 395f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } else { 396f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipt = &ipc.ipts[cpu]; 397f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu p = ipt->idleness; 398f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 399f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 400680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe return p * 100.0; 401f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu} 402f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 40310aa136bddbaa7c845ab4eacb4a9a4a88d6657a3Jens Axboestatic void fio_idle_prof_cleanup(void) 404f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu{ 405f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.ipts) { 406f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu free(ipc.ipts); 407f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.ipts = NULL; 408f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 409f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 410f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.buf) { 411f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu free(ipc.buf); 412f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.buf = NULL; 413f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 414f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu} 415f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 416f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liuint fio_idle_prof_parse_opt(const char *args) 417f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu{ 418f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.opt = IDLE_PROF_OPT_NONE; /* default */ 419f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 420f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (!args) { 421f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: empty idle-prof option string\n"); 422f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return -1; 423f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 424f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 4257e09a9f10bb301635b6f9206b3144878a2710b0aJens Axboe#if defined(FIO_HAVE_CPU_AFFINITY) && defined(CONFIG_SCHED_IDLE) 426f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (strcmp("calibrate", args) == 0) { 427f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.opt = IDLE_PROF_OPT_CALI; 428f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu fio_idle_prof_init(); 429f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu fio_idle_prof_start(); 430f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu fio_idle_prof_stop(); 431f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu show_idle_prof_stats(FIO_OUTPUT_NORMAL, NULL); 432f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return 1; 433f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } else if (strcmp("system", args) == 0) { 434f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.opt = IDLE_PROF_OPT_SYSTEM; 435f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return 0; 436f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } else if (strcmp("percpu", args) == 0) { 437f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu ipc.opt = IDLE_PROF_OPT_PERCPU; 438f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return 0; 439f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } else { 4404e0a8fa2593006505b7f4e18931a201d221b49e9Jens Axboe log_err("fio: incorrect idle-prof option: %s\n", args); 441f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return -1; 442f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 443f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu#else 444f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_err("fio: idle-prof not supported on this platform\n"); 445f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return -1; 446f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu#endif 447f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu} 448f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 449f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liuvoid show_idle_prof_stats(int output, struct json_object *parent) 450f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu{ 451f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu int i, nr_cpus = ipc.nr_cpus; 452f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu struct json_object *tmp; 453f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu char s[MAX_CPU_STR_LEN]; 454680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe 455f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (output == FIO_OUTPUT_NORMAL) { 456f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt > IDLE_PROF_OPT_CALI) 457f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_info("\nCPU idleness:\n"); 458f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu else if (ipc.opt == IDLE_PROF_OPT_CALI) 459f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_info("CPU idleness:\n"); 460f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 461f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt >= IDLE_PROF_OPT_SYSTEM) 462f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_info(" system: %3.2f%%\n", fio_idle_prof_cpu_stat(-1)); 463f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 464f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt == IDLE_PROF_OPT_PERCPU) { 465f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_info(" percpu: %3.2f%%", fio_idle_prof_cpu_stat(0)); 466680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe for (i = 1; i < nr_cpus; i++) 467f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_info(", %3.2f%%", fio_idle_prof_cpu_stat(i)); 468f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_info("\n"); 469f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 470f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 471f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt >= IDLE_PROF_OPT_CALI) { 472f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_info(" unit work: mean=%3.2fus,", ipc.cali_mean); 473f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu log_info(" stddev=%3.2f\n", ipc.cali_stddev); 474f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 475f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 476f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu /* dynamic mem allocations can now be freed */ 477f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt != IDLE_PROF_OPT_NONE) 478f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu fio_idle_prof_cleanup(); 479f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 480f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 481f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 482680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe 483f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if ((ipc.opt != IDLE_PROF_OPT_NONE) && (output == FIO_OUTPUT_JSON)) { 484f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (!parent) 485f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 486f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 487f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu tmp = json_create_object(); 488f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (!tmp) 489f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu return; 490f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 491f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu json_object_add_value_object(parent, "cpu_idleness", tmp); 492f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu json_object_add_value_float(tmp, "system", fio_idle_prof_cpu_stat(-1)); 493f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 494f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu if (ipc.opt == IDLE_PROF_OPT_PERCPU) { 495680b5abcb197f52382c8c568c6f1453b410e2b66Jens Axboe for (i = 0; i < nr_cpus; i++) { 496f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu snprintf(s, MAX_CPU_STR_LEN, "cpu-%d", i); 497f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu json_object_add_value_float(tmp, s, fio_idle_prof_cpu_stat(i)); 498f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 499f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 500f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 501f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu json_object_add_value_float(tmp, "unit_mean", ipc.cali_mean); 502f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu json_object_add_value_float(tmp, "unit_stddev", ipc.cali_stddev); 503f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu 504f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu fio_idle_prof_cleanup(); 505f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu } 506f2a2ce0eedb44eaa8689e4cbfa77c79b1751b216Huadong Liu} 507