hc
2024-11-01 2f529f9b558ca1c1bd74be7437a84e4711743404
kernel/arch/arm64/kernel/smp.c
....@@ -86,7 +86,7 @@
8686 NR_IPI
8787 };
8888
89
-static int ipi_irq_base __read_mostly;
89
+int ipi_irq_base __read_mostly;
9090 static int nr_ipi __read_mostly = NR_IPI;
9191 static struct irq_desc *ipi_desc[NR_IPI] __read_mostly;
9292
....@@ -273,6 +273,7 @@
273273 complete(&cpu_running);
274274
275275 local_daif_restore(DAIF_PROCCTX);
276
+ local_irq_enable_full();
276277
277278 /*
278279 * OK, it's off to the idle thread for us
....@@ -811,6 +812,8 @@
811812
812813 static void smp_cross_call(const struct cpumask *target, unsigned int ipinr);
813814
815
+static unsigned int get_ipi_count(unsigned int irq, unsigned int cpu);
816
+
814817 unsigned long irq_err_count;
815818
816819 int arch_show_interrupts(struct seq_file *p, int prec)
....@@ -822,7 +825,7 @@
822825 seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i,
823826 prec >= 4 ? " " : "");
824827 for_each_online_cpu(cpu)
825
- seq_printf(p, "%10u ", kstat_irqs_cpu(irq, cpu));
828
+ seq_printf(p, "%10u ", get_ipi_count(irq, cpu));
826829 seq_printf(p, " %s\n", ipi_types[i]);
827830 }
828831
....@@ -888,7 +891,7 @@
888891
889892 atomic_dec(&waiting_for_crash_ipi);
890893
891
- local_irq_disable();
894
+ local_irq_disable_full();
892895 sdei_mask_local_cpu();
893896
894897 if (IS_ENABLED(CONFIG_HOTPLUG_CPU))
....@@ -900,7 +903,7 @@
900903 }
901904
902905 /*
903
- * Main handler for inter-processor interrupts
906
+ * Main handler for inter-processor interrupts on the in-band stage.
904907 */
905908 static void do_handle_IPI(int ipinr)
906909 {
....@@ -963,6 +966,73 @@
963966 trace_ipi_exit_rcuidle(ipi_types[ipinr]);
964967 }
965968
969
+static void __smp_cross_call(const struct cpumask *target, unsigned int ipinr)
970
+{
971
+ trace_ipi_raise(target, ipi_types[ipinr]);
972
+ __ipi_send_mask(ipi_desc[ipinr], target);
973
+}
974
+
975
+#ifdef CONFIG_IRQ_PIPELINE
976
+
977
+static DEFINE_PER_CPU(unsigned long, ipi_messages);
978
+
979
+static DEFINE_PER_CPU(unsigned int [NR_IPI], ipi_counts);
980
+
981
+static irqreturn_t ipi_handler(int irq, void *data)
982
+{
983
+ unsigned long *pmsg;
984
+ unsigned int ipinr;
985
+
986
+ /*
987
+ * Decode in-band IPIs (0..NR_IPI - 1) multiplexed over
988
+ * SGI0. Out-of-band IPIs (SGI1, SGI2) have their own
989
+ * individual handler.
990
+ */
991
+ pmsg = raw_cpu_ptr(&ipi_messages);
992
+ while (*pmsg) {
993
+ ipinr = ffs(*pmsg) - 1;
994
+ clear_bit(ipinr, pmsg);
995
+ __this_cpu_inc(ipi_counts[ipinr]);
996
+ do_handle_IPI(ipinr);
997
+ }
998
+
999
+ return IRQ_HANDLED;
1000
+}
1001
+
1002
+static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
1003
+{
1004
+ unsigned int cpu;
1005
+
1006
+ /* regular in-band IPI (multiplexed over SGI0). */
1007
+ for_each_cpu(cpu, target)
1008
+ set_bit(ipinr, &per_cpu(ipi_messages, cpu));
1009
+
1010
+ wmb();
1011
+ __smp_cross_call(target, 0);
1012
+}
1013
+
1014
+static unsigned int get_ipi_count(unsigned int irq, unsigned int cpu)
1015
+{
1016
+ return per_cpu(ipi_counts[irq - ipi_irq_base], cpu);
1017
+}
1018
+
1019
+void irq_send_oob_ipi(unsigned int irq,
1020
+ const struct cpumask *cpumask)
1021
+{
1022
+ unsigned int sgi = irq - ipi_irq_base;
1023
+
1024
+ if (WARN_ON(irq_pipeline_debug() &&
1025
+ (sgi < OOB_IPI_OFFSET ||
1026
+ sgi >= OOB_IPI_OFFSET + OOB_NR_IPI)))
1027
+ return;
1028
+
1029
+ /* Out-of-band IPI (SGI1-2). */
1030
+ __smp_cross_call(cpumask, sgi);
1031
+}
1032
+EXPORT_SYMBOL_GPL(irq_send_oob_ipi);
1033
+
1034
+#else
1035
+
9661036 static irqreturn_t ipi_handler(int irq, void *data)
9671037 {
9681038 do_handle_IPI(irq - ipi_irq_base);
....@@ -971,9 +1041,15 @@
9711041
9721042 static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
9731043 {
974
- trace_ipi_raise(target, ipi_types[ipinr]);
975
- __ipi_send_mask(ipi_desc[ipinr], target);
1044
+ __smp_cross_call(target, ipinr);
9761045 }
1046
+
1047
+static unsigned int get_ipi_count(unsigned int irq, unsigned int cpu)
1048
+{
1049
+ return kstat_irqs_cpu(irq, cpu);
1050
+}
1051
+
1052
+#endif /* CONFIG_IRQ_PIPELINE */
9771053
9781054 static void ipi_setup(int cpu)
9791055 {
....@@ -1001,18 +1077,25 @@
10011077
10021078 void __init set_smp_ipi_range(int ipi_base, int n)
10031079 {
1004
- int i;
1080
+ int i, inband_nr_ipi;
10051081
10061082 WARN_ON(n < NR_IPI);
10071083 nr_ipi = min(n, NR_IPI);
1084
+ /*
1085
+ * irq_pipeline: the in-band stage traps SGI0 only,
1086
+ * over which IPI messages are mutiplexed. Other SGIs
1087
+ * are available for exchanging out-of-band IPIs.
1088
+ */
1089
+ inband_nr_ipi = irqs_pipelined() ? 1 : nr_ipi;
10081090
10091091 for (i = 0; i < nr_ipi; i++) {
1010
- int err;
1092
+ if (i < inband_nr_ipi) {
1093
+ int err;
10111094
1012
- err = request_percpu_irq(ipi_base + i, ipi_handler,
1013
- "IPI", &cpu_number);
1014
- WARN_ON(err);
1015
-
1095
+ err = request_percpu_irq(ipi_base + i, ipi_handler,
1096
+ "IPI", &cpu_number);
1097
+ WARN_ON(err);
1098
+ }
10161099 ipi_desc[i] = irq_to_desc(ipi_base + i);
10171100 irq_set_status_flags(ipi_base + i, IRQ_HIDDEN);
10181101