Loading arch/arm/kernel/smp.c +32 −8 Original line number Diff line number Diff line Loading @@ -498,6 +498,18 @@ static void smp_cross_call(const struct cpumask *target, unsigned int ipinr) __smp_cross_call(target, ipinr); } 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 show_ipi_list(struct seq_file *p, int prec) { unsigned int cpu, i; Loading Loading @@ -526,31 +538,32 @@ u64 smp_irq_stat_cpu(unsigned int cpu) 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); smp_cross_call_common(cpumask_of(cpu), IPI_CALL_FUNC); } #ifdef CONFIG_IRQ_WORK void arch_irq_work_raise(void) { if (arch_irq_work_has_interrupt()) smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK); smp_cross_call_common(cpumask_of(smp_processor_id()), IPI_IRQ_WORK); } #endif #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 @@ -666,12 +679,14 @@ void handle_IPI(int ipinr, struct pt_regs *regs) if ((unsigned)ipinr < NR_IPI) trace_ipi_exit_rcuidle(ipi_types[ipinr]); per_cpu(pending_ipi, cpu) = false; set_irq_regs(old_regs); } void smp_send_reschedule(int cpu) { smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); smp_cross_call_common(cpumask_of(cpu), IPI_RESCHEDULE); } void smp_send_stop(void) Loading @@ -682,7 +697,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 Loading @@ -755,7 +770,16 @@ core_initcall(register_cpufreq_notifier); static void raise_nmi(cpumask_t *mask) { smp_cross_call(mask, IPI_CPU_BACKTRACE); /* * Generate the backtrace directly if we are running in a calling * context that is not preemptible by the backtrace IPI. Note * that nmi_cpu_backtrace() automatically removes the current cpu * from mask. */ if (cpumask_test_cpu(smp_processor_id(), mask) && irqs_disabled()) nmi_cpu_backtrace(NULL); smp_cross_call_common(mask, IPI_CPU_BACKTRACE); } void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self) Loading arch/arm64/kernel/smp.c +19 −8 Original line number Diff line number Diff line Loading @@ -594,6 +594,18 @@ static void __init acpi_parse_and_init_cpus(void) #else #define acpi_parse_and_init_cpus(...) do { } while (0) #endif 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 @@ -735,8 +747,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) } } void (*__smp_cross_call)(const struct cpumask *, unsigned int); void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int)) { __smp_cross_call = fn; Loading Loading @@ -786,18 +796,18 @@ u64 smp_irq_stat_cpu(unsigned int cpu) 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); smp_cross_call_common(cpumask_of(cpu), IPI_CALL_FUNC); } #ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL void arch_send_wakeup_ipi_mask(const struct cpumask *mask) { smp_cross_call(mask, IPI_WAKEUP); smp_cross_call_common(mask, IPI_WAKEUP); } #endif Loading Loading @@ -933,19 +943,20 @@ void handle_IPI(int ipinr, struct pt_regs *regs) if ((unsigned)ipinr < NR_IPI) trace_ipi_exit_rcuidle(ipi_types[ipinr]); 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 @@ -961,7 +972,7 @@ void smp_send_stop(void) if (system_state <= SYSTEM_RUNNING) pr_crit("SMP: stopping secondary CPUs\n"); 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 Loading
arch/arm/kernel/smp.c +32 −8 Original line number Diff line number Diff line Loading @@ -498,6 +498,18 @@ static void smp_cross_call(const struct cpumask *target, unsigned int ipinr) __smp_cross_call(target, ipinr); } 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 show_ipi_list(struct seq_file *p, int prec) { unsigned int cpu, i; Loading Loading @@ -526,31 +538,32 @@ u64 smp_irq_stat_cpu(unsigned int cpu) 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); smp_cross_call_common(cpumask_of(cpu), IPI_CALL_FUNC); } #ifdef CONFIG_IRQ_WORK void arch_irq_work_raise(void) { if (arch_irq_work_has_interrupt()) smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK); smp_cross_call_common(cpumask_of(smp_processor_id()), IPI_IRQ_WORK); } #endif #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 @@ -666,12 +679,14 @@ void handle_IPI(int ipinr, struct pt_regs *regs) if ((unsigned)ipinr < NR_IPI) trace_ipi_exit_rcuidle(ipi_types[ipinr]); per_cpu(pending_ipi, cpu) = false; set_irq_regs(old_regs); } void smp_send_reschedule(int cpu) { smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); smp_cross_call_common(cpumask_of(cpu), IPI_RESCHEDULE); } void smp_send_stop(void) Loading @@ -682,7 +697,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 Loading @@ -755,7 +770,16 @@ core_initcall(register_cpufreq_notifier); static void raise_nmi(cpumask_t *mask) { smp_cross_call(mask, IPI_CPU_BACKTRACE); /* * Generate the backtrace directly if we are running in a calling * context that is not preemptible by the backtrace IPI. Note * that nmi_cpu_backtrace() automatically removes the current cpu * from mask. */ if (cpumask_test_cpu(smp_processor_id(), mask) && irqs_disabled()) nmi_cpu_backtrace(NULL); smp_cross_call_common(mask, IPI_CPU_BACKTRACE); } void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self) Loading
arch/arm64/kernel/smp.c +19 −8 Original line number Diff line number Diff line Loading @@ -594,6 +594,18 @@ static void __init acpi_parse_and_init_cpus(void) #else #define acpi_parse_and_init_cpus(...) do { } while (0) #endif 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 @@ -735,8 +747,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) } } void (*__smp_cross_call)(const struct cpumask *, unsigned int); void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int)) { __smp_cross_call = fn; Loading Loading @@ -786,18 +796,18 @@ u64 smp_irq_stat_cpu(unsigned int cpu) 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); smp_cross_call_common(cpumask_of(cpu), IPI_CALL_FUNC); } #ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL void arch_send_wakeup_ipi_mask(const struct cpumask *mask) { smp_cross_call(mask, IPI_WAKEUP); smp_cross_call_common(mask, IPI_WAKEUP); } #endif Loading Loading @@ -933,19 +943,20 @@ void handle_IPI(int ipinr, struct pt_regs *regs) if ((unsigned)ipinr < NR_IPI) trace_ipi_exit_rcuidle(ipi_types[ipinr]); 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 @@ -961,7 +972,7 @@ void smp_send_stop(void) if (system_state <= SYSTEM_RUNNING) pr_crit("SMP: stopping secondary CPUs\n"); 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