static void migrate_overloaded_irqs(struct topo_obj *obj, void *data) { struct load_balance_info *info = data; if (obj->powersave_mode) info->num_powersave++; if ((obj->load + info->std_deviation) <= info->avg_load) { info->num_under++; if (power_thresh != ULONG_MAX && !info->powersave) if (!obj->powersave_mode) info->powersave = obj; } else if ((obj->load - info->std_deviation) >=info->avg_load) { info->num_over++; } if ((obj->load > info->min_load) && (g_list_length(obj->interrupts) > 1)) { /* order the list from greatest to least workload */ sort_irq_list(&obj->interrupts); /* * Each irq carries a weighted average amount of load * we think it's responsible for. This object's load is larger * than the object with the minimum load. Select irqs for * migration if we could move them to the minimum object * without reversing the imbalance or until we only have one * left. */ info->adjustment_load = obj->load; for_each_irq(obj->interrupts, move_candidate_irqs, info); } }
int main(int argc, char** argv) { if (argc>1 && strstr(argv[1],"debug")) debug_mode=1; if (argc>1 && strstr(argv[1],"oneshot")) one_shot_mode=1; if (getenv("IRQBALANCE_BANNED_CPUS")) { cpumask_parse_user(getenv("IRQBALANCE_BANNED_CPUS"), strlen(getenv("IRQBALANCE_BANNED_CPUS")), banned_cpus); } if (getenv("IRQBALANCE_ONESHOT")) one_shot_mode=1; if (getenv("IRQBALANCE_DEBUG")) debug_mode=1; parse_cpu_tree(); /* On single core UP systems irqbalance obviously has no work to do */ if (core_count<2) exit(EXIT_SUCCESS); /* On dual core/hyperthreading shared cache systems just do a one shot setup */ if (cache_domain_count==1) one_shot_mode = 1; if (!debug_mode) if (daemon(0,0)) exit(EXIT_FAILURE); #ifdef HAVE_LIBCAP_NG // Drop capabilities capng_clear(CAPNG_SELECT_BOTH); capng_lock(); capng_apply(CAPNG_SELECT_BOTH); #endif parse_proc_interrupts(); sleep(SLEEP_INTERVAL/4); reset_counts(); parse_proc_interrupts(); pci_numa_scan(); calculate_workload(); sort_irq_list(); if (debug_mode) dump_workloads(); while (1) { sleep_approx(SLEEP_INTERVAL); if (debug_mode) printf("\n\n\n-----------------------------------------------------------------------------\n"); check_power_mode(); parse_proc_interrupts(); /* cope with cpu hotplug -- detected during /proc/interrupts parsing */ if (need_cpu_rescan) { need_cpu_rescan = 0; /* if there's a hotplug event we better turn off power mode for a bit until things settle */ power_mode = 0; if (debug_mode) printf("Rescanning cpu topology \n"); reset_counts(); clear_work_stats(); clear_cpu_tree(); parse_cpu_tree(); } /* deal with NAPI */ account_for_nic_stats(); calculate_workload(); /* to cope with dynamic configurations we scan for new numa information * once every 5 minutes */ if (counter % NUMA_REFRESH_INTERVAL == 16) pci_numa_scan(); calculate_placement(); activate_mapping(); if (debug_mode) dump_tree(); if (one_shot_mode) break; counter++; } return EXIT_SUCCESS; }