1da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe/* 2da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe * CPU engine 3da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe * 4da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe * Doesn't transfer any data, merely burns CPU cycles according to 5da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe * the settings. 6da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe * 7da751ca9665bcdeca56d2eec5b629a0953c07662Jens Axboe */ 85f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe#include "../fio.h" 92866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe 100353050fe32065e1932a43a7c39a7c390ea71142Jens Axboestruct cpu_options { 110353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe struct thread_data *td; 120353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe unsigned int cpuload; 130353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe unsigned int cpucycle; 14046395d7ab181288d14737c1d0041e98328f473fJens Axboe unsigned int exit_io_done; 150353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe}; 160353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe 170353050fe32065e1932a43a7c39a7c390ea71142Jens Axboestatic struct fio_option options[] = { 180353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe { 190353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe .name = "cpuload", 200353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe .lname = "CPU load", 210353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe .type = FIO_OPT_INT, 220353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe .off1 = offsetof(struct cpu_options, cpuload), 230353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe .help = "Use this percentage of CPU", 240353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe .category = FIO_OPT_C_GENERAL, 250353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe .group = FIO_OPT_G_INVALID, 260353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe }, 270353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe { 280353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe .name = "cpuchunks", 290353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe .lname = "CPU chunk", 300353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe .type = FIO_OPT_INT, 310353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe .off1 = offsetof(struct cpu_options, cpucycle), 320353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe .help = "Length of the CPU burn cycles (usecs)", 330353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe .def = "50000", 340353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe .parent = "cpuload", 350353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe .hide = 1, 360353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe .category = FIO_OPT_C_GENERAL, 370353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe .group = FIO_OPT_G_INVALID, 380353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe }, 390353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe { 40046395d7ab181288d14737c1d0041e98328f473fJens Axboe .name = "exit_on_io_done", 41046395d7ab181288d14737c1d0041e98328f473fJens Axboe .lname = "Exit when IO threads are done", 42046395d7ab181288d14737c1d0041e98328f473fJens Axboe .type = FIO_OPT_BOOL, 43046395d7ab181288d14737c1d0041e98328f473fJens Axboe .off1 = offsetof(struct cpu_options, exit_io_done), 44046395d7ab181288d14737c1d0041e98328f473fJens Axboe .help = "Exit when IO threads finish", 45046395d7ab181288d14737c1d0041e98328f473fJens Axboe .def = "0", 46046395d7ab181288d14737c1d0041e98328f473fJens Axboe .category = FIO_OPT_C_GENERAL, 47046395d7ab181288d14737c1d0041e98328f473fJens Axboe .group = FIO_OPT_G_INVALID, 48046395d7ab181288d14737c1d0041e98328f473fJens Axboe }, 49046395d7ab181288d14737c1d0041e98328f473fJens Axboe { 500353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe .name = NULL, 510353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe }, 520353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe}; 530353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe 540353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe 55ba0fbe1029bae1de08d66a72b6d0b2505c67c438Jens Axboestatic int fio_cpuio_queue(struct thread_data *td, struct io_u fio_unused *io_u) 56ba0fbe1029bae1de08d66a72b6d0b2505c67c438Jens Axboe{ 570353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe struct cpu_options *co = td->eo; 580353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe 59046395d7ab181288d14737c1d0041e98328f473fJens Axboe if (co->exit_io_done && !fio_running_or_pending_io_threads()) { 60046395d7ab181288d14737c1d0041e98328f473fJens Axboe td->done = 1; 61046395d7ab181288d14737c1d0041e98328f473fJens Axboe return FIO_Q_BUSY; 62046395d7ab181288d14737c1d0041e98328f473fJens Axboe } 63046395d7ab181288d14737c1d0041e98328f473fJens Axboe 640353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe usec_spin(co->cpucycle); 65ba0fbe1029bae1de08d66a72b6d0b2505c67c438Jens Axboe return FIO_Q_COMPLETED; 66ba0fbe1029bae1de08d66a72b6d0b2505c67c438Jens Axboe} 67ba0fbe1029bae1de08d66a72b6d0b2505c67c438Jens Axboe 682866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboestatic int fio_cpuio_init(struct thread_data *td) 692866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe{ 702dc1bbeb58edc85f2829eed6729862c438ea2353Jens Axboe struct thread_options *o = &td->o; 710353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe struct cpu_options *co = td->eo; 722dc1bbeb58edc85f2829eed6729862c438ea2353Jens Axboe 730353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe if (!co->cpuload) { 74ba0fbe1029bae1de08d66a72b6d0b2505c67c438Jens Axboe td_vmsg(td, EINVAL, "cpu thread needs rate (cpuload=)","cpuio"); 752866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe return 1; 76ba0fbe1029bae1de08d66a72b6d0b2505c67c438Jens Axboe } 77ba0fbe1029bae1de08d66a72b6d0b2505c67c438Jens Axboe 780353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe if (co->cpuload > 100) 790353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe co->cpuload = 100; 802866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe 81ba0fbe1029bae1de08d66a72b6d0b2505c67c438Jens Axboe /* 82ba0fbe1029bae1de08d66a72b6d0b2505c67c438Jens Axboe * set thinktime_sleep and thinktime_spin appropriately 83ba0fbe1029bae1de08d66a72b6d0b2505c67c438Jens Axboe */ 842dc1bbeb58edc85f2829eed6729862c438ea2353Jens Axboe o->thinktime_blocks = 1; 852dc1bbeb58edc85f2829eed6729862c438ea2353Jens Axboe o->thinktime_spin = 0; 860353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe o->thinktime = (co->cpucycle * (100 - co->cpuload)) / co->cpuload; 872866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe 882dc1bbeb58edc85f2829eed6729862c438ea2353Jens Axboe o->nr_files = o->open_files = 1; 890353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe 900353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe log_info("%s: ioengine=cpu, cpuload=%u, cpucycle=%u\n", td->o.name, 910353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe co->cpuload, co->cpucycle); 920353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe 93ba0fbe1029bae1de08d66a72b6d0b2505c67c438Jens Axboe return 0; 94ba0fbe1029bae1de08d66a72b6d0b2505c67c438Jens Axboe} 95ba0fbe1029bae1de08d66a72b6d0b2505c67c438Jens Axboe 96f4e62a5f3640dfe2d2119bbe1e40bf57747f6564Jens Axboestatic int fio_cpuio_open(struct thread_data fio_unused *td, 97f4e62a5f3640dfe2d2119bbe1e40bf57747f6564Jens Axboe struct fio_file fio_unused *f) 98ba0fbe1029bae1de08d66a72b6d0b2505c67c438Jens Axboe{ 992866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe return 0; 1002866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe} 1012866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe 1025f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboestatic struct ioengine_ops ioengine = { 1032866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe .name = "cpuio", 1042866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe .version = FIO_IOOPS_VERSION, 105ba0fbe1029bae1de08d66a72b6d0b2505c67c438Jens Axboe .queue = fio_cpuio_queue, 1062866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe .init = fio_cpuio_init, 107ba0fbe1029bae1de08d66a72b6d0b2505c67c438Jens Axboe .open_file = fio_cpuio_open, 1081f809d151ddc4a4c348c2e4f6007db510e3e08a2Jens Axboe .flags = FIO_SYNCIO | FIO_DISKLESSIO | FIO_NOIO, 1090353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe .options = options, 1100353050fe32065e1932a43a7c39a7c390ea71142Jens Axboe .option_struct_size = sizeof(struct cpu_options), 1112866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe}; 1125f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe 1135f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboestatic void fio_init fio_cpuio_register(void) 1145f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{ 1155f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe register_ioengine(&ioengine); 1165f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe} 1175f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe 1185f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboestatic void fio_exit fio_cpuio_unregister(void) 1195f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{ 1205f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe unregister_ioengine(&ioengine); 1215f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe} 122