int ehca_create_comp_pool(void) { int cpu; struct task_struct *task; if (!ehca_scaling_code) return 0; pool = kzalloc(sizeof(struct ehca_comp_pool), GFP_KERNEL); if (pool == NULL) return -ENOMEM; spin_lock_init(&pool->last_cpu_lock); pool->last_cpu = any_online_cpu(cpu_online_map); pool->cpu_comp_tasks = alloc_percpu(struct ehca_cpu_comp_task); if (pool->cpu_comp_tasks == NULL) { kfree(pool); return -EINVAL; } for_each_online_cpu(cpu) { task = create_comp_task(pool, cpu); if (task) { kthread_bind(task, cpu); wake_up_process(task); } } register_hotcpu_notifier(&comp_pool_callback_nb); printk(KERN_INFO "eHCA scaling code enabled\n"); return 0; }
void fixup_irqs(cpumask_t map) { unsigned int irq; static int warned; for (irq = 0; irq < NR_IRQS; irq++) { cpumask_t mask; if (irq == 2) continue; cpus_and(mask, irq_desc[irq].affinity, map); if (any_online_cpu(mask) == NR_CPUS) { printk("Breaking affinity for irq %i\n", irq); mask = map; } if (irq_desc[irq].chip->set_affinity) irq_desc[irq].chip->set_affinity(irq, mask); else if (irq_desc[irq].action && !(warned++)) printk("Cannot set affinity for irq %i\n", irq); } /* That doesn't seem sufficient. Give it 1ms. */ local_irq_enable(); mdelay(1); local_irq_disable(); }
int __cpu_disable(void) { /* FIXME: go put this in a header somewhere */ extern void xics_migrate_irqs_away(void); systemcfg->processorCount--; /*fix boot_cpuid here*/ if (smp_processor_id() == boot_cpuid) boot_cpuid = any_online_cpu(cpu_online_map); /* FIXME: abstract this to not be platform specific later on */ xics_migrate_irqs_away(); return 0; }
static int pSeries_cpu_disable(void) { int cpu = smp_processor_id(); cpu_clear(cpu, cpu_online_map); vdso_data->processorCount--; /*fix boot_cpuid here*/ if (cpu == boot_cpuid) boot_cpuid = any_online_cpu(cpu_online_map); /* FIXME: abstract this to not be platform specific later on */ xics_migrate_irqs_away(); return 0; }
static int __cpuinit comp_pool_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; struct ehca_cpu_comp_task *cct; switch (action) { case CPU_UP_PREPARE: case CPU_UP_PREPARE_FROZEN: ehca_gen_dbg("CPU: %x (CPU_PREPARE)", cpu); if (!create_comp_task(pool, cpu)) { ehca_gen_err("Can't create comp_task for cpu: %x", cpu); return NOTIFY_BAD; } break; case CPU_UP_CANCELED: case CPU_UP_CANCELED_FROZEN: ehca_gen_dbg("CPU: %x (CPU_CANCELED)", cpu); cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu); kthread_bind(cct->task, any_online_cpu(cpu_online_map)); destroy_comp_task(pool, cpu); break; case CPU_ONLINE: case CPU_ONLINE_FROZEN: ehca_gen_dbg("CPU: %x (CPU_ONLINE)", cpu); cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu); kthread_bind(cct->task, cpu); wake_up_process(cct->task); break; case CPU_DOWN_PREPARE: case CPU_DOWN_PREPARE_FROZEN: ehca_gen_dbg("CPU: %x (CPU_DOWN_PREPARE)", cpu); break; case CPU_DOWN_FAILED: case CPU_DOWN_FAILED_FROZEN: ehca_gen_dbg("CPU: %x (CPU_DOWN_FAILED)", cpu); break; case CPU_DEAD: case CPU_DEAD_FROZEN: ehca_gen_dbg("CPU: %x (CPU_DEAD)", cpu); destroy_comp_task(pool, cpu); take_over_work(pool, cpu); break; } return NOTIFY_OK; }
static int __cpuinit cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { int hotcpu = (unsigned long)hcpu; struct task_struct *p; switch (action) { case CPU_UP_PREPARE: case CPU_UP_PREPARE_FROZEN: p = kthread_create(ksoftirqd, hcpu, "ksoftirqd/%d", hotcpu); if (IS_ERR(p)) { printk("ksoftirqd for %i failed\n", hotcpu); return NOTIFY_BAD; } kthread_bind(p, hotcpu); per_cpu(ksoftirqd, hotcpu) = p; break; case CPU_ONLINE: case CPU_ONLINE_FROZEN: wake_up_process(per_cpu(ksoftirqd, hotcpu)); break; #ifdef CONFIG_HOTPLUG_CPU case CPU_UP_CANCELED: case CPU_UP_CANCELED_FROZEN: if (!per_cpu(ksoftirqd, hotcpu)) break; /* Unbind so it can run. Fall thru. */ kthread_bind(per_cpu(ksoftirqd, hotcpu), any_online_cpu(cpu_online_map)); case CPU_DEAD: case CPU_DEAD_FROZEN: p = per_cpu(ksoftirqd, hotcpu); per_cpu(ksoftirqd, hotcpu) = NULL; kthread_stop(p); takeover_tasklets(hotcpu); break; #endif /* CONFIG_HOTPLUG_CPU */ } return NOTIFY_OK; }
int migrate_platform_irqs(unsigned int cpu) { int new_cpei_cpu; irq_desc_t *desc = NULL; cpumask_t mask; int retval = 0; /* * dont permit CPEI target to removed. */ if (cpe_vector > 0 && is_cpu_cpei_target(cpu)) { printk ("CPU (%d) is CPEI Target\n", cpu); if (can_cpei_retarget()) { /* * Now re-target the CPEI to a different processor */ new_cpei_cpu = any_online_cpu(cpu_online_map); mask = cpumask_of_cpu(new_cpei_cpu); set_cpei_target_cpu(new_cpei_cpu); desc = irq_desc + ia64_cpe_irq; /* * Switch for now, immediatly, we need to do fake intr * as other interrupts, but need to study CPEI behaviour with * polling before making changes. */ if (desc) { desc->chip->disable(ia64_cpe_irq); desc->chip->set_affinity(ia64_cpe_irq, mask); desc->chip->enable(ia64_cpe_irq); printk ("Re-targetting CPEI to cpu %d\n", new_cpei_cpu); } } if (!desc) { printk ("Unable to retarget CPEI, offline cpu [%d] failed\n", cpu); retval = -EBUSY; } } return retval; }