---
arch/arm64/include/asm/cputype.h | 3 +++
arch/arm64/kernel/smp.c | 30 ++++++++++++++++++++++++
drivers/irqchip/irq-gic-phytium-2500-its.c | 37 ++++++++++++++++++++++++++++++
drivers/irqchip/irq-gic-phytium-2500.c | 21 +++++++++++++++++
4 files changed, 91 insertions(+)
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index ef5b040..b5d815d 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -133,6 +133,9 @@
#define MIDR_FUJITSU_ERRATUM_010001_MASK (~MIDR_CPU_VAR_REV(1, 0))
#define TCR_CLEAR_FUJITSU_ERRATUM_010001 (TCR_NFD1 | TCR_NFD0)
+#define PHYTIUM_CPU_PART_2500 0X663
+#define MIDR_FT_2500 MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_2500)
+
#ifndef __ASSEMBLY__
#include <asm/sysreg.h>
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index a909b91..f1df23f 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -33,6 +33,8 @@
#include <linux/kernel_stat.h>
#include <linux/kexec.h>
#include <linux/kvm_host.h>
+#include <linux/perf/arm_pmu.h>
+#include <linux/crash_dump.h>
#include <asm/alternative.h>
#include <asm/atomic.h>
@@ -530,6 +532,29 @@ static int __init smp_cpu_setup(int cpu)
static bool bootcpu_valid __initdata;
static unsigned int cpu_count = 1;
+#ifdef CONFIG_ARCH_PHYTIUM
+/*
+ * On phytium S2500 multi-socket server, for example 2-socket(2P), there are
+ * socekt0 and socket1 on the server:
+ * If storage device(like SAS controller and disks to save vmcore into) is
+ * installed on socket1 and second kernel brings up 2 CPUs both on socket0 with
+ * nr_cpus=2, then vmcore will fail to be saved into the disk.
+ * To avoid this issue, Bypass other non-cpu0 to ensure that each cpu0 on each
+ * socket can bootup and handle interrupt when booting the second kernel.
+ */
+static bool __init is_phytium_kdump_cpu_need_bypass(u64 hwid)
+{
+ if ((read_cpuid_id() & MIDR_CPU_MODEL_MASK) != MIDR_FT_2500)
+ return false;
+ /*Bypass other non-cpu0 to ensure second kernel can bring up each cpu0
+ * on each socket*/
+ if (is_kdump_kernel() && (hwid & 0xffff) != (cpu_logical_map(0) &
0xffff))
+ return true;
+ return false;
+}
+#endif
+
+
#ifdef CONFIG_ACPI
static struct acpi_madt_generic_interrupt cpu_madt_gicc[NR_CPUS];
@@ -579,6 +604,11 @@ struct acpi_madt_generic_interrupt *acpi_cpu_get_madt_gicc(int cpu)
if (cpu_count >= NR_CPUS)
return;
+#ifdef CONFIG_ARCH_PHYTIUM
+ if (is_phytium_kdump_cpu_need_bypass(hwid))
+ return;
+#endif
+
/* map the logical cpu id to cpu MPIDR */
set_cpu_logical_map(cpu_count, hwid);
diff --git a/drivers/irqchip/irq-gic-phytium-2500-its.c
b/drivers/irqchip/irq-gic-phytium-2500-its.c
index 26b2349..3fbaafe 100644
--- a/drivers/irqchip/irq-gic-phytium-2500-its.c
+++ b/drivers/irqchip/irq-gic-phytium-2500-its.c
@@ -1677,6 +1677,23 @@ static int its_cpumask_select(struct its_device *its_dev,
cpu = cpumask_any_and(mask_val, cpu_mask);
cpus = cpus + cpu % skt_cpu_cnt[skt_id];
+ if (is_kdump_kernel()){
+ skt = (cpu_logical_map(cpu) >> 16) & 0xff;
+ if(skt_id == skt){
+ return cpu;
+ }
+ for (i = 0; i < nr_cpu_ids; i++) {
+ skt = (cpu_logical_map(i) >> 16) & 0xff;
+ if ((skt >= 0) && (skt < MAX_MARS3_SKT_COUNT)) {
+ if(skt_id == skt){
+ return i;
+ }
+ } else if (0xff != skt ) {
+ pr_err("socket address: %d is out of range.", skt);
+ }
+ }
+ }
+
return cpus;
}
@@ -3010,6 +3027,9 @@ static bool enabled_lpis_allowed(void)
phys_addr_t addr;
u64 val;
+ if (is_kdump_kernel())
+ return true;
+
/* Check whether the property table is in a reserved region */
val = gicr_read_propbaser(gic_data_rdist_rd_base() + GICR_PROPBASER);
addr = val & GENMASK_ULL(51, 12);
@@ -3653,6 +3673,23 @@ static int its_cpumask_first(struct its_device *its_dev,
cpus = cpu;
}
+ if (is_kdump_kernel()){
+ skt = (cpu_logical_map(cpu) >> 16) & 0xff;
+ if(skt_id == skt){
+ return cpu;
+ }
+ for (i = 0; i < nr_cpu_ids; i++) {
+ skt = (cpu_logical_map(i) >> 16) & 0xff;
+ if ((skt >= 0) && (skt < MAX_MARS3_SKT_COUNT)) {
+ if(skt_id == skt){
+ return i;
+ }
+ } else if (0xff != skt ) {
+ pr_err("socket address: %d is out of range.", skt);
+ }
+ }
+ }
+
return cpus;
}
diff --git a/drivers/irqchip/irq-gic-phytium-2500.c
b/drivers/irqchip/irq-gic-phytium-2500.c
index d6e198bb..f08a9fa 100644
--- a/drivers/irqchip/irq-gic-phytium-2500.c
+++ b/drivers/irqchip/irq-gic-phytium-2500.c
@@ -22,6 +22,7 @@
#include <linux/acpi.h>
#include <linux/cpu.h>
#include <linux/cpu_pm.h>
+#include <linux/crash_dump.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
@@ -1347,6 +1348,23 @@ static int gic_cpumask_select(struct irq_data *d, const struct
cpumask *mask_val
cpu = cpumask_any_and(mask_val, cpu_online_mask);
cpus = cpus + cpu % skt_cpu_cnt[irq_skt];
+ if (is_kdump_kernel()){
+ skt = (cpu_logical_map(cpu) >> 16) & 0xff;
+ if(irq_skt == skt){
+ return cpu;
+ }
+ for (i = 0; i < nr_cpu_ids; i++) {
+ skt = (cpu_logical_map(i) >> 16) & 0xff;
+ if ((skt >= 0) && (skt < MAX_MARS3_SOC_COUNT)) {
+ if(irq_skt == skt){
+ return i;
+ }
+ } else if (0xff != skt ) {
+ pr_err("socket address: %d is out of range.", skt);
+ }
+ }
+ }
+
return cpus;
}
@@ -2439,6 +2457,9 @@ static void __init gic_acpi_setup_kvm_info(void)
#ifdef CONFIG_ACPI
mars3_sockets_bitmap = gic_mars3_sockets_bitmap();
+ if (is_kdump_kernel()){
+ mars3_sockets_bitmap = 0x3;
+ }
if (mars3_sockets_bitmap == 0){
mars3_sockets_bitmap = 0x1;
pr_err("No socket, please check cpus MPIDR_AFFINITY_LEVEL!!!");
--
1.8.3.1
显示某日回复
Hi Wencheng,
Could you add some commit message to describe your patch? What's the problem you try
to solve?
The subject line format should be:
subsystem-name: Xxxxxx
More comments in line.
------------------------------------------------------------------
发件人:liwencheng <liwencheng(a)phytium.com.cn>
发送时间:2022年4月28日(星期四) 17:43
收件人:arm-arch <arm-arch(a)lists.openanolis.cn>
抄 送:liwencheng <liwencheng(a)phytium.com.cn>
主 题:[Arm-arch] [PATCH 2/3] Kdump patch for S2500 start one cpu on each socket to handle
interrupt of hard disk.
---
arch/arm64/include/asm/cputype.h | 3 +++
arch/arm64/kernel/smp.c | 30 ++++++++++++++++++++++++
drivers/irqchip/irq-gic-phytium-2500-its.c | 37 ++++++++++++++++++++++++++++++
drivers/irqchip/irq-gic-phytium-2500.c | 21 +++++++++++++++++
4 files changed, 91 insertions(+)
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index ef5b040..b5d815d 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -133,6 +133,9 @@
#define MIDR_FUJITSU_ERRATUM_010001_MASK (~MIDR_CPU_VAR_REV(1, 0))
#define TCR_CLEAR_FUJITSU_ERRATUM_010001 (TCR_NFD1 | TCR_NFD0)
+#define PHYTIUM_CPU_PART_2500 0X663
+#define MIDR_FT_2500 MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_2500)
+
#ifndef __ASSEMBLY__
#include <asm/sysreg.h>
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index a909b91..f1df23f 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -33,6 +33,8 @@
#include <linux/kernel_stat.h>
#include <linux/kexec.h>
#include <linux/kvm_host.h>
+#include <linux/perf/arm_pmu.h>
+#include <linux/crash_dump.h>
#include <asm/alternative.h>
#include <asm/atomic.h>
@@ -530,6 +532,29 @@ static int __init smp_cpu_setup(int cpu)
static bool bootcpu_valid __initdata;
static unsigned int cpu_count = 1;
+#ifdef CONFIG_ARCH_PHYTIUM
+/*
+ * On phytium S2500 multi-socket server, for example 2-socket(2P), there are
+ * socekt0 and socket1 on the server:
+ * If storage device(like SAS controller and disks to save vmcore into) is
+ * installed on socket1 and second kernel brings up 2 CPUs both on socket0 with
+ * nr_cpus=2, then vmcore will fail to be saved into the disk.
+ * To avoid this issue, Bypass other non-cpu0 to ensure that each cpu0 on each
+ * socket can bootup and handle interrupt when booting the second kernel.
+ */
+static bool __init is_phytium_kdump_cpu_need_bypass(u64 hwid)
+{
+ if ((read_cpuid_id() & MIDR_CPU_MODEL_MASK) != MIDR_FT_2500)
+ return false;
+ /*Bypass other non-cpu0 to ensure second kernel can bring up each cpu0
+ * on each socket*/
+ if (is_kdump_kernel() && (hwid & 0xffff) != (cpu_logical_map(0) &
0xffff))
I think you should use MPIDR_HWID_BITMASK macro instead of magic number:0xffff
+ return true;
+ return false;
+}
+#endif
+
+
#ifdef CONFIG_ACPI
static struct acpi_madt_generic_interrupt cpu_madt_gicc[NR_CPUS];
@@ -579,6 +604,11 @@ struct acpi_madt_generic_interrupt *acpi_cpu_get_madt_gicc(int cpu)
if (cpu_count >= NR_CPUS)
return;
+#ifdef CONFIG_ARCH_PHYTIUM
+ if (is_phytium_kdump_cpu_need_bypass(hwid))
+ return;
+#endif
+
/* map the logical cpu id to cpu MPIDR */
set_cpu_logical_map(cpu_count, hwid);
diff --git a/drivers/irqchip/irq-gic-phytium-2500-its.c
b/drivers/irqchip/irq-gic-phytium-2500-its.c
index 26b2349..3fbaafe 100644
--- a/drivers/irqchip/irq-gic-phytium-2500-its.c
+++ b/drivers/irqchip/irq-gic-phytium-2500-its.c
@@ -1677,6 +1677,23 @@ static int its_cpumask_select(struct its_device *its_dev,
cpu = cpumask_any_and(mask_val, cpu_mask);
cpus = cpus + cpu % skt_cpu_cnt[skt_id];
+ if (is_kdump_kernel()){
+ skt = (cpu_logical_map(cpu) >> 16) & 0xff;
+ if(skt_id == skt){
+ return cpu;
+ }
+ for (i = 0; i < nr_cpu_ids; i++) {
+ skt = (cpu_logical_map(i) >> 16) & 0xff;
+ if ((skt >= 0) && (skt < MAX_MARS3_SKT_COUNT)) {
+ if(skt_id == skt){
+ return i;
+ }
+ } else if (0xff != skt ) {
+ pr_err("socket address: %d is out of range.", skt);
+ }
+ }
+ }
+
return cpus;
}
@@ -3010,6 +3027,9 @@ static bool enabled_lpis_allowed(void)
phys_addr_t addr;
u64 val;
+ if (is_kdump_kernel())
+ return true;
+
/* Check whether the property table is in a reserved region */
val = gicr_read_propbaser(gic_data_rdist_rd_base() + GICR_PROPBASER);
addr = val & GENMASK_ULL(51, 12);
@@ -3653,6 +3673,23 @@ static int its_cpumask_first(struct its_device *its_dev,
cpus = cpu;
}
+ if (is_kdump_kernel()){
+ skt = (cpu_logical_map(cpu) >> 16) & 0xff;
+ if(skt_id == skt){
+ return cpu;
+ }
+ for (i = 0; i < nr_cpu_ids; i++) {
+ skt = (cpu_logical_map(i) >> 16) & 0xff;
+ if ((skt >= 0) && (skt < MAX_MARS3_SKT_COUNT)) {
+ if(skt_id == skt){
+ return i;
+ }
+ } else if (0xff != skt ) {
+ pr_err("socket address: %d is out of range.", skt);
+ }
+ }
+ }
+
return cpus;
}
diff --git a/drivers/irqchip/irq-gic-phytium-2500.c
b/drivers/irqchip/irq-gic-phytium-2500.c
index d6e198bb..f08a9fa 100644
--- a/drivers/irqchip/irq-gic-phytium-2500.c
+++ b/drivers/irqchip/irq-gic-phytium-2500.c
@@ -22,6 +22,7 @@
#include <linux/acpi.h>
#include <linux/cpu.h>
#include <linux/cpu_pm.h>
+#include <linux/crash_dump.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
@@ -1347,6 +1348,23 @@ static int gic_cpumask_select(struct irq_data *d, const struct
cpumask *mask_val
cpu = cpumask_any_and(mask_val, cpu_online_mask);
cpus = cpus + cpu % skt_cpu_cnt[irq_skt];
+ if (is_kdump_kernel()){
+ skt = (cpu_logical_map(cpu) >> 16) & 0xff;
+ if(irq_skt == skt){
+ return cpu;
+ }
+ for (i = 0; i < nr_cpu_ids; i++) {
+ skt = (cpu_logical_map(i) >> 16) & 0xff;
+ if ((skt >= 0) && (skt < MAX_MARS3_SOC_COUNT)) {
+ if(irq_skt == skt){
+ return i;
+ }
+ } else if (0xff != skt ) {
+ pr_err("socket address: %d is out of range.", skt);
+ }
+ }
+ }
+
return cpus;
}
@@ -2439,6 +2457,9 @@ static void __init gic_acpi_setup_kvm_info(void)
#ifdef CONFIG_ACPI
mars3_sockets_bitmap = gic_mars3_sockets_bitmap();
+ if (is_kdump_kernel()){
+ mars3_sockets_bitmap = 0x3;
+ }
No need '{ }' for only single line code of the 'if' block.
if (mars3_sockets_bitmap == 0){
mars3_sockets_bitmap = 0x1;
pr_err("No socket, please check cpus MPIDR_AFFINITY_LEVEL!!!");
--
1.8.3.1
_______________________________________________
Arm-arch mailing list -- arm-arch(a)lists.openanolis.cn
To unsubscribe send an email to arm-arch-leave(a)lists.openanolis.cn