static void hotplug_timer(struct work_struct *work) { struct cpu_hotplug_info tmp_hotplug_info[4]; int i; unsigned int load = 0; unsigned int cpu_rq_min=0; unsigned long nr_rq_min = -1UL; unsigned int select_off_cpu = 0; enum flag flag_hotplug; mutex_lock(&hotplug_lock); // exit if we turned off dynamic hotplug by tegrak // cancel the timer if (!hotplug_on) { if (!second_core_on && cpu_online(1) == 1) cpu_down(1); goto off_hotplug; } if (user_lock == 1) goto no_hotplug; for_each_online_cpu(i) { struct cpu_time_info *tmp_info; cputime64_t cur_wall_time, cur_idle_time; unsigned int idle_time, wall_time; tmp_info = &per_cpu(hotplug_cpu_time, i); cur_idle_time = get_cpu_idle_time_us(i, &cur_wall_time); idle_time = (unsigned int)cputime64_sub(cur_idle_time, tmp_info->prev_cpu_idle); tmp_info->prev_cpu_idle = cur_idle_time; wall_time = (unsigned int)cputime64_sub(cur_wall_time, tmp_info->prev_cpu_wall); tmp_info->prev_cpu_wall = cur_wall_time; if (wall_time < idle_time) goto no_hotplug; tmp_info->load = 100 * (wall_time - idle_time) / wall_time; load += tmp_info->load; /*find minimum runqueue length*/ tmp_hotplug_info[i].nr_running = get_cpu_nr_running(i); if (i && nr_rq_min > tmp_hotplug_info[i].nr_running) { nr_rq_min = tmp_hotplug_info[i].nr_running; cpu_rq_min = i; } } for (i = NUM_CPUS - 1; i > 0; --i) { if (cpu_online(i) == 0) { select_off_cpu = i; break; } } /*standallone hotplug*/ flag_hotplug = standalone_hotplug(load, nr_rq_min, cpu_rq_min); /*do not ever hotplug out CPU 0*/ if((cpu_rq_min == 0) && (flag_hotplug == HOTPLUG_OUT)) goto no_hotplug; /*cpu hotplug*/ if (flag_hotplug == HOTPLUG_IN && cpu_online(select_off_cpu) == CPU_OFF) { DBG_PRINT("cpu%d turning on!\n", select_off_cpu); cpu_up(select_off_cpu); DBG_PRINT("cpu%d on\n", select_off_cpu); hotpluging_rate = CHECK_DELAY * 4; } else if (flag_hotplug == HOTPLUG_OUT && cpu_online(cpu_rq_min) == CPU_ON) { DBG_PRINT("cpu%d turnning off!\n", cpu_rq_min); cpu_down(cpu_rq_min); DBG_PRINT("cpu%d off!\n", cpu_rq_min); hotpluging_rate = CHECK_DELAY; } no_hotplug: //printk("hotplug_timer done.\n"); queue_delayed_work_on(0, hotplug_wq, &hotplug_work, hotpluging_rate); off_hotplug: mutex_unlock(&hotplug_lock); }
static void hotplug_timer(struct work_struct *work) { struct cpu_hotplug_info tmp_hotplug_info[4]; int i; unsigned int load = 0; unsigned int cpu_rq_min=0; unsigned long nr_rq_min = -1UL; unsigned int select_off_cpu = 0; enum flag flag_hotplug; mutex_lock(&hotplug_lock); if (user_lock == 1) goto no_hotplug; for_each_online_cpu(i) { struct cpu_time_info *tmp_info; cputime64_t cur_wall_time, cur_idle_time; unsigned int idle_time, wall_time; tmp_info = &per_cpu(hotplug_cpu_time, i); cur_idle_time = get_cpu_idle_time_us(i, &cur_wall_time); idle_time = (unsigned int)cputime64_sub(cur_idle_time, tmp_info->prev_cpu_idle); tmp_info->prev_cpu_idle = cur_idle_time; wall_time = (unsigned int)cputime64_sub(cur_wall_time, tmp_info->prev_cpu_wall); tmp_info->prev_cpu_wall = cur_wall_time; if (wall_time < idle_time) goto no_hotplug; tmp_info->load = 100 * (wall_time - idle_time) / wall_time; load += tmp_info->load; /*find minimum runqueue length*/ tmp_hotplug_info[i].nr_running = get_cpu_nr_running(i); if (i && nr_rq_min > tmp_hotplug_info[i].nr_running) { nr_rq_min = tmp_hotplug_info[i].nr_running; cpu_rq_min = i; } } for (i = NUM_CPUS - 1; i > 0; --i) { if (cpu_online(i) == 0) { select_off_cpu = i; break; } } /*standallone hotplug*/ flag_hotplug = standalone_hotplug(load, nr_rq_min, cpu_rq_min); /*cpu hotplug*/ if (flag_hotplug == HOTPLUG_IN && cpu_online(select_off_cpu) == CPU_OFF) { #ifndef PRODUCT_SHIP DBG_PRINT("cpu%d turning on!\n", select_off_cpu); #endif cpu_up(select_off_cpu); #ifndef PRODUCT_SHIP DBG_PRINT("cpu%d on\n", select_off_cpu); #endif hotpluging_rate = CHECK_DELAY * 4; } else if (flag_hotplug == HOTPLUG_OUT && cpu_online(cpu_rq_min) == CPU_ON) { #ifndef PRODUCT_SHIP DBG_PRINT("cpu%d turnning off!\n", cpu_rq_min); #endif cpu_down(cpu_rq_min); #ifndef PRODUCT_SHIP DBG_PRINT("cpu%d off!\n", cpu_rq_min); #endif hotpluging_rate = CHECK_DELAY; } no_hotplug: queue_delayed_work_on(0, hotplug_wq, &hotplug_work, hotpluging_rate); mutex_unlock(&hotplug_lock); }