Loading arch/arm/kernel/smp.c +21 −7 Original line number Diff line number Diff line Loading @@ -434,6 +434,18 @@ void __init smp_prepare_cpus(unsigned int max_cpus) } static void (*smp_cross_call)(const struct cpumask *, unsigned int); DEFINE_PER_CPU(bool, pending_ipi); static void smp_cross_call_common(const struct cpumask *cpumask, unsigned int func) { unsigned int cpu; for_each_cpu(cpu, cpumask) per_cpu(pending_ipi, cpu) = true; smp_cross_call(cpumask, func); } void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int)) { Loading @@ -443,17 +455,17 @@ void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int)) void arch_send_call_function_ipi_mask(const struct cpumask *mask) { smp_cross_call(mask, IPI_CALL_FUNC); smp_cross_call_common(mask, IPI_CALL_FUNC); } void arch_send_wakeup_ipi_mask(const struct cpumask *mask) { smp_cross_call(mask, IPI_WAKEUP); smp_cross_call_common(mask, IPI_WAKEUP); } void arch_send_call_function_single_ipi(int cpu) { smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); smp_cross_call_common(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); } static const char *ipi_types[NR_IPI] = { Loading Loading @@ -501,7 +513,7 @@ static DEFINE_PER_CPU(struct clock_event_device, percpu_clockevent); #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST void tick_broadcast(const struct cpumask *mask) { smp_cross_call(mask, IPI_TIMER); smp_cross_call_common(mask, IPI_TIMER); } #endif Loading Loading @@ -620,7 +632,7 @@ void smp_send_all_cpu_backtrace(void) pr_info("\nsending IPI to all other CPUs:\n"); if (!cpus_empty(backtrace_mask)) smp_cross_call(&backtrace_mask, IPI_CPU_BACKTRACE); smp_cross_call_common(&backtrace_mask, IPI_CPU_BACKTRACE); /* Wait for up to 10 seconds for all other CPUs to do the backtrace */ for (i = 0; i < 10 * 1000; i++) { Loading Loading @@ -706,13 +718,15 @@ void handle_IPI(int ipinr, struct pt_regs *regs) cpu, ipinr); break; } per_cpu(pending_ipi, cpu) = false; set_irq_regs(old_regs); } void smp_send_reschedule(int cpu) { BUG_ON(cpu_is_offline(cpu)); smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); smp_cross_call_common(cpumask_of(cpu), IPI_RESCHEDULE); } void smp_send_stop(void) Loading @@ -723,7 +737,7 @@ void smp_send_stop(void) cpumask_copy(&mask, cpu_online_mask); cpumask_clear_cpu(smp_processor_id(), &mask); if (!cpumask_empty(&mask)) smp_cross_call(&mask, IPI_CPU_STOP); smp_cross_call_common(&mask, IPI_CPU_STOP); /* Wait up to one second for other CPUs to stop */ timeout = USEC_PER_SEC; Loading arch/arm64/kernel/smp.c +20 −7 Original line number Diff line number Diff line Loading @@ -321,6 +321,18 @@ void __init smp_prepare_boot_cpu(void) } static void (*smp_cross_call)(const struct cpumask *, unsigned int); DEFINE_PER_CPU(bool, pending_ipi); void smp_cross_call_common(const struct cpumask *cpumask, unsigned int func) { unsigned int cpu; for_each_cpu(cpu, cpumask) per_cpu(pending_ipi, cpu) = true; smp_cross_call(cpumask, func); } /* * Enumerate the possible CPU set from the device tree and build the Loading Loading @@ -483,17 +495,17 @@ void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int)) void arch_send_call_function_ipi_mask(const struct cpumask *mask) { smp_cross_call(mask, IPI_CALL_FUNC); smp_cross_call_common(mask, IPI_CALL_FUNC); } void arch_send_call_function_single_ipi(int cpu) { smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); smp_cross_call_common(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); } void arch_send_wakeup_ipi_mask(const struct cpumask *mask) { smp_cross_call(mask, IPI_WAKEUP); smp_cross_call_common(mask, IPI_WAKEUP); } #ifdef CONFIG_IRQ_WORK Loading Loading @@ -596,7 +608,7 @@ static void smp_send_all_cpu_backtrace(void) pr_info("\nsending IPI to all other CPUs:\n"); if (!cpus_empty(backtrace_mask)) smp_cross_call(&backtrace_mask, IPI_CPU_BACKTRACE); smp_cross_call_common(&backtrace_mask, IPI_CPU_BACKTRACE); /* Wait for up to 10 seconds for all other CPUs to do the backtrace */ for (i = 0; i < 10 * 1000; i++) { Loading Loading @@ -696,19 +708,20 @@ void handle_IPI(int ipinr, struct pt_regs *regs) pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr); break; } per_cpu(pending_ipi, cpu) = false; set_irq_regs(old_regs); } void smp_send_reschedule(int cpu) { BUG_ON(cpu_is_offline(cpu)); smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); smp_cross_call_common(cpumask_of(cpu), IPI_RESCHEDULE); } #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST void tick_broadcast(const struct cpumask *mask) { smp_cross_call(mask, IPI_TIMER); smp_cross_call_common(mask, IPI_TIMER); } #endif Loading @@ -722,7 +735,7 @@ void smp_send_stop(void) cpumask_copy(&mask, cpu_online_mask); cpu_clear(smp_processor_id(), mask); smp_cross_call(&mask, IPI_CPU_STOP); smp_cross_call_common(&mask, IPI_CPU_STOP); } /* Wait up to one second for other CPUs to stop */ Loading drivers/cpuidle/lpm-levels.c +2 −2 Original line number Diff line number Diff line Loading @@ -447,8 +447,8 @@ static int cluster_configure(struct lpm_cluster *cluster, int idx, spin_lock(&cluster->sync_lock); if (!cpumask_equal(&cluster->num_childs_in_sync, &cluster->child_cpus)) { if (!cpumask_equal(&cluster->num_childs_in_sync, &cluster->child_cpus) || is_IPI_pending(&cluster->num_childs_in_sync)) { spin_unlock(&cluster->sync_lock); return -EPERM; } Loading drivers/cpuidle/lpm-levels.h +19 −0 Original line number Diff line number Diff line Loading @@ -103,3 +103,22 @@ bool lpm_cluster_mode_allow(struct lpm_cluster *cluster, unsigned int mode, bool from_idle); extern struct lpm_cluster *lpm_root_node; #ifdef CONFIG_SMP extern DEFINE_PER_CPU(bool, pending_ipi); static inline bool is_IPI_pending(const struct cpumask *mask) { unsigned int cpu; for_each_cpu(cpu, mask) { if per_cpu(pending_ipi, cpu) return true; } return false; } #else static inline bool is_IPI_pending(const struct cpumask *mask) { return false; } #endif Loading
arch/arm/kernel/smp.c +21 −7 Original line number Diff line number Diff line Loading @@ -434,6 +434,18 @@ void __init smp_prepare_cpus(unsigned int max_cpus) } static void (*smp_cross_call)(const struct cpumask *, unsigned int); DEFINE_PER_CPU(bool, pending_ipi); static void smp_cross_call_common(const struct cpumask *cpumask, unsigned int func) { unsigned int cpu; for_each_cpu(cpu, cpumask) per_cpu(pending_ipi, cpu) = true; smp_cross_call(cpumask, func); } void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int)) { Loading @@ -443,17 +455,17 @@ void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int)) void arch_send_call_function_ipi_mask(const struct cpumask *mask) { smp_cross_call(mask, IPI_CALL_FUNC); smp_cross_call_common(mask, IPI_CALL_FUNC); } void arch_send_wakeup_ipi_mask(const struct cpumask *mask) { smp_cross_call(mask, IPI_WAKEUP); smp_cross_call_common(mask, IPI_WAKEUP); } void arch_send_call_function_single_ipi(int cpu) { smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); smp_cross_call_common(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); } static const char *ipi_types[NR_IPI] = { Loading Loading @@ -501,7 +513,7 @@ static DEFINE_PER_CPU(struct clock_event_device, percpu_clockevent); #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST void tick_broadcast(const struct cpumask *mask) { smp_cross_call(mask, IPI_TIMER); smp_cross_call_common(mask, IPI_TIMER); } #endif Loading Loading @@ -620,7 +632,7 @@ void smp_send_all_cpu_backtrace(void) pr_info("\nsending IPI to all other CPUs:\n"); if (!cpus_empty(backtrace_mask)) smp_cross_call(&backtrace_mask, IPI_CPU_BACKTRACE); smp_cross_call_common(&backtrace_mask, IPI_CPU_BACKTRACE); /* Wait for up to 10 seconds for all other CPUs to do the backtrace */ for (i = 0; i < 10 * 1000; i++) { Loading Loading @@ -706,13 +718,15 @@ void handle_IPI(int ipinr, struct pt_regs *regs) cpu, ipinr); break; } per_cpu(pending_ipi, cpu) = false; set_irq_regs(old_regs); } void smp_send_reschedule(int cpu) { BUG_ON(cpu_is_offline(cpu)); smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); smp_cross_call_common(cpumask_of(cpu), IPI_RESCHEDULE); } void smp_send_stop(void) Loading @@ -723,7 +737,7 @@ void smp_send_stop(void) cpumask_copy(&mask, cpu_online_mask); cpumask_clear_cpu(smp_processor_id(), &mask); if (!cpumask_empty(&mask)) smp_cross_call(&mask, IPI_CPU_STOP); smp_cross_call_common(&mask, IPI_CPU_STOP); /* Wait up to one second for other CPUs to stop */ timeout = USEC_PER_SEC; Loading
arch/arm64/kernel/smp.c +20 −7 Original line number Diff line number Diff line Loading @@ -321,6 +321,18 @@ void __init smp_prepare_boot_cpu(void) } static void (*smp_cross_call)(const struct cpumask *, unsigned int); DEFINE_PER_CPU(bool, pending_ipi); void smp_cross_call_common(const struct cpumask *cpumask, unsigned int func) { unsigned int cpu; for_each_cpu(cpu, cpumask) per_cpu(pending_ipi, cpu) = true; smp_cross_call(cpumask, func); } /* * Enumerate the possible CPU set from the device tree and build the Loading Loading @@ -483,17 +495,17 @@ void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int)) void arch_send_call_function_ipi_mask(const struct cpumask *mask) { smp_cross_call(mask, IPI_CALL_FUNC); smp_cross_call_common(mask, IPI_CALL_FUNC); } void arch_send_call_function_single_ipi(int cpu) { smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); smp_cross_call_common(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); } void arch_send_wakeup_ipi_mask(const struct cpumask *mask) { smp_cross_call(mask, IPI_WAKEUP); smp_cross_call_common(mask, IPI_WAKEUP); } #ifdef CONFIG_IRQ_WORK Loading Loading @@ -596,7 +608,7 @@ static void smp_send_all_cpu_backtrace(void) pr_info("\nsending IPI to all other CPUs:\n"); if (!cpus_empty(backtrace_mask)) smp_cross_call(&backtrace_mask, IPI_CPU_BACKTRACE); smp_cross_call_common(&backtrace_mask, IPI_CPU_BACKTRACE); /* Wait for up to 10 seconds for all other CPUs to do the backtrace */ for (i = 0; i < 10 * 1000; i++) { Loading Loading @@ -696,19 +708,20 @@ void handle_IPI(int ipinr, struct pt_regs *regs) pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr); break; } per_cpu(pending_ipi, cpu) = false; set_irq_regs(old_regs); } void smp_send_reschedule(int cpu) { BUG_ON(cpu_is_offline(cpu)); smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); smp_cross_call_common(cpumask_of(cpu), IPI_RESCHEDULE); } #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST void tick_broadcast(const struct cpumask *mask) { smp_cross_call(mask, IPI_TIMER); smp_cross_call_common(mask, IPI_TIMER); } #endif Loading @@ -722,7 +735,7 @@ void smp_send_stop(void) cpumask_copy(&mask, cpu_online_mask); cpu_clear(smp_processor_id(), mask); smp_cross_call(&mask, IPI_CPU_STOP); smp_cross_call_common(&mask, IPI_CPU_STOP); } /* Wait up to one second for other CPUs to stop */ Loading
drivers/cpuidle/lpm-levels.c +2 −2 Original line number Diff line number Diff line Loading @@ -447,8 +447,8 @@ static int cluster_configure(struct lpm_cluster *cluster, int idx, spin_lock(&cluster->sync_lock); if (!cpumask_equal(&cluster->num_childs_in_sync, &cluster->child_cpus)) { if (!cpumask_equal(&cluster->num_childs_in_sync, &cluster->child_cpus) || is_IPI_pending(&cluster->num_childs_in_sync)) { spin_unlock(&cluster->sync_lock); return -EPERM; } Loading
drivers/cpuidle/lpm-levels.h +19 −0 Original line number Diff line number Diff line Loading @@ -103,3 +103,22 @@ bool lpm_cluster_mode_allow(struct lpm_cluster *cluster, unsigned int mode, bool from_idle); extern struct lpm_cluster *lpm_root_node; #ifdef CONFIG_SMP extern DEFINE_PER_CPU(bool, pending_ipi); static inline bool is_IPI_pending(const struct cpumask *mask) { unsigned int cpu; for_each_cpu(cpu, mask) { if per_cpu(pending_ipi, cpu) return true; } return false; } #else static inline bool is_IPI_pending(const struct cpumask *mask) { return false; } #endif