Re: [GIT PULL] x86/apic changes for v4.4

2015-11-03 Thread Linus Torvalds
On Tue, Nov 3, 2015 at 2:32 AM, Ingo Molnar  wrote:
>
> Please pull the latest x86-apic-for-linus git tree from:

Side note, I have an *old* patch that I think simplifies the
(reasonably common) case of sending IPI's to individual CPU's. That's
done by the "reschedule ipi" in particular.

That's something that is trivially done on the x2apic, but that the
mask-based interfaces makes insanely complicated.

I have *not* rebased this on top of modern kernels so it may not
actually work as a patch any more, because I'm just sending this out
as a "Hmm, what do you guys think" rather than a real submission.

Comments?

Linus
From 9f09a8b2a1fa58f2e692af4a7283fd1674749d39 Mon Sep 17 00:00:00 2001
From: Linus Torvalds 
Date: Fri, 20 Feb 2015 11:06:02 -0800
Subject: [PATCH] x86: add a single-target IPI function to the apic

We still fall back on the "send mask" versions if an apic definition
doesn't have the single-target version, but at least this allows the
(trivial) case for the common clustered x2apic case.

Signed-off-by: Linus Torvalds 
---
 arch/x86/include/asm/apic.h   |  1 +
 arch/x86/kernel/apic/x2apic_cluster.c |  9 +
 arch/x86/kernel/smp.c | 16 ++--
 3 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 92003f3c8a42..5d47ffcfa65d 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -296,6 +296,7 @@ struct apic {
   unsigned int *apicid);
 
 	/* ipi */
+	void (*send_IPI)(int cpu, int vector);
 	void (*send_IPI_mask)(const struct cpumask *mask, int vector);
 	void (*send_IPI_mask_allbutself)(const struct cpumask *mask,
 	 int vector);
diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c
index e658f21681c8..177c4fb027a1 100644
--- a/arch/x86/kernel/apic/x2apic_cluster.c
+++ b/arch/x86/kernel/apic/x2apic_cluster.c
@@ -23,6 +23,14 @@ static inline u32 x2apic_cluster(int cpu)
 	return per_cpu(x86_cpu_to_logical_apicid, cpu) >> 16;
 }
 
+static void x2apic_send_IPI(int cpu, int vector)
+{
+	u32 dest = per_cpu(x86_cpu_to_logical_apicid, cpu);
+
+	x2apic_wrmsr_fence();
+	__x2apic_send_IPI_dest(dest, vector, APIC_DEST_LOGICAL);
+}
+
 static void
 __x2apic_send_IPI_mask(const struct cpumask *mask, int vector, int apic_dest)
 {
@@ -266,6 +274,7 @@ static struct apic apic_x2apic_cluster = {
 
 	.cpu_mask_to_apicid_and		= x2apic_cpu_mask_to_apicid_and,
 
+	.send_IPI			= x2apic_send_IPI,
 	.send_IPI_mask			= x2apic_send_IPI_mask,
 	.send_IPI_mask_allbutself	= x2apic_send_IPI_mask_allbutself,
 	.send_IPI_allbutself		= x2apic_send_IPI_allbutself,
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index be8e1bde07aa..78c9b12d892a 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -114,6 +114,18 @@ static atomic_t stopping_cpu = ATOMIC_INIT(-1);
 static bool smp_no_nmi_ipi = false;
 
 /*
+ * Helper wrapper: not all apic definitions support sending to
+ * a single CPU, so we fall back to sending to a mask.
+ */
+static void send_IPI_cpu(int cpu, int vector)
+{
+	if (apic->send_IPI)
+		apic->send_IPI(cpu, vector);
+	else
+		apic->send_IPI_mask(cpumask_of(cpu), vector);
+}
+
+/*
  * this function sends a 'reschedule' IPI to another CPU.
  * it goes straight through and wastes no time serializing
  * anything. Worst case is that we lose a reschedule ...
@@ -124,12 +136,12 @@ static void native_smp_send_reschedule(int cpu)
 		WARN_ON(1);
 		return;
 	}
-	apic->send_IPI_mask(cpumask_of(cpu), RESCHEDULE_VECTOR);
+	send_IPI_cpu(cpu, RESCHEDULE_VECTOR);
 }
 
 void native_send_call_func_single_ipi(int cpu)
 {
-	apic->send_IPI_mask(cpumask_of(cpu), CALL_FUNCTION_SINGLE_VECTOR);
+	send_IPI_cpu(cpu, CALL_FUNCTION_SINGLE_VECTOR);
 }
 
 void native_send_call_func_ipi(const struct cpumask *mask)
-- 
2.6.2.402.g2635c2b



[GIT PULL] x86/apic changes for v4.4

2015-11-03 Thread Ingo Molnar
Linus,

Please pull the latest x86-apic-for-linus git tree from:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-apic-for-linus

   # HEAD: 4faefda97bc1be6ca909ba0fd0927ea78f37f67e x86/io_apic: Make 
eoi_ioapic_pin() static

The main changes in this cycle were:

 - Numachip updates: new hardware support, fixes and cleanups. (Daniel J 
Blueman)

 - misc smaller cleanups and fixlets.

  out-of-topic modifications in x86-apic-for-linus:
  ---
  drivers/clocksource/Makefile   # ce2e572cfe7b: x86/numachip: Introduce 
Numa
  drivers/clocksource/numachip.c # ef34cc3428a7: x86/numachip: Fix timer 
buil
   # ce2e572cfe7b: x86/numachip: Introduce Numa

 Thanks,

Ingo

-->
Andy Shevchenko (1):
  x86/io_apic: Make eoi_ioapic_pin() static

Daniel J Blueman (5):
  x86/numachip: Cleanup Numachip support
  x86/numachip: Add Numachip2 APIC support
  x86/numachip: Add Numachip IPI optimisations
  x86/numachip: Introduce Numachip2 timer mechanisms
  x86/numachip: Fix timer build conflict

Denys Vlasenko (1):
  x86/apic: Deinline various functions

Geliang Tang (1):
  x86/irq: Drop unlikely before IS_ERR_OR_NULL

Paolo Bonzini (1):
  x86/x2apic: Make stub functions available even if !CONFIG_X86_LOCAL_APIC


 arch/x86/include/asm/apic.h  | 110 +++---
 arch/x86/include/asm/numachip/numachip.h |   1 +
 arch/x86/include/asm/numachip/numachip_csr.h | 153 +--
 arch/x86/kernel/apic/apic.c  |   8 +-
 arch/x86/kernel/apic/apic_numachip.c | 220 +++
 arch/x86/kernel/apic/io_apic.c   |   2 +-
 arch/x86/kernel/irq_64.c |   2 +-
 drivers/clocksource/Makefile |   1 +
 drivers/clocksource/numachip.c   |  95 
 9 files changed, 360 insertions(+), 232 deletions(-)
 create mode 100644 drivers/clocksource/numachip.c

diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index ebf6d5e5668c..a30316bf801a 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -115,6 +115,59 @@ static inline bool apic_is_x2apic_enabled(void)
return msr & X2APIC_ENABLE;
 }
 
+extern void enable_IR_x2apic(void);
+
+extern int get_physical_broadcast(void);
+
+extern int lapic_get_maxlvt(void);
+extern void clear_local_APIC(void);
+extern void disconnect_bsp_APIC(int virt_wire_setup);
+extern void disable_local_APIC(void);
+extern void lapic_shutdown(void);
+extern void sync_Arb_IDs(void);
+extern void init_bsp_APIC(void);
+extern void setup_local_APIC(void);
+extern void init_apic_mappings(void);
+void register_lapic_address(unsigned long address);
+extern void setup_boot_APIC_clock(void);
+extern void setup_secondary_APIC_clock(void);
+extern int APIC_init_uniprocessor(void);
+
+#ifdef CONFIG_X86_64
+static inline int apic_force_enable(unsigned long addr)
+{
+   return -1;
+}
+#else
+extern int apic_force_enable(unsigned long addr);
+#endif
+
+extern int apic_bsp_setup(bool upmode);
+extern void apic_ap_setup(void);
+
+/*
+ * On 32bit this is mach-xxx local
+ */
+#ifdef CONFIG_X86_64
+extern int apic_is_clustered_box(void);
+#else
+static inline int apic_is_clustered_box(void)
+{
+   return 0;
+}
+#endif
+
+extern int setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask);
+
+#else /* !CONFIG_X86_LOCAL_APIC */
+static inline void lapic_shutdown(void) { }
+#define local_apic_timer_c2_ok 1
+static inline void init_apic_mappings(void) { }
+static inline void disable_local_APIC(void) { }
+# define setup_boot_APIC_clock x86_init_noop
+# define setup_secondary_APIC_clock x86_init_noop
+#endif /* !CONFIG_X86_LOCAL_APIC */
+
 #ifdef CONFIG_X86_X2APIC
 /*
  * Make previous memory operations globally visible before
@@ -186,67 +239,14 @@ static inline int x2apic_enabled(void)
 }
 
 #define x2apic_supported() (cpu_has_x2apic)
-#else
+#else /* !CONFIG_X86_X2APIC */
 static inline void check_x2apic(void) { }
 static inline void x2apic_setup(void) { }
 static inline int x2apic_enabled(void) { return 0; }
 
 #define x2apic_mode(0)
 #definex2apic_supported()  (0)
-#endif
-
-extern void enable_IR_x2apic(void);
-
-extern int get_physical_broadcast(void);
-
-extern int lapic_get_maxlvt(void);
-extern void clear_local_APIC(void);
-extern void disconnect_bsp_APIC(int virt_wire_setup);
-extern void disable_local_APIC(void);
-extern void lapic_shutdown(void);
-extern void sync_Arb_IDs(void);
-extern void init_bsp_APIC(void);
-extern void setup_local_APIC(void);
-extern void init_apic_mappings(void);
-void register_lapic_address(unsigned long address);
-extern void setup_boot_APIC_clock(void);
-extern void setup_secondary_APIC_clock(void);
-extern int APIC_init_uniprocessor(void);
-
-#ifdef CONFIG_X86_64
-static inline int apic_force_enable(unsigned long addr)
-{
-   

[GIT PULL] x86/apic changes for v4.4

2015-11-03 Thread Ingo Molnar
Linus,

Please pull the latest x86-apic-for-linus git tree from:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-apic-for-linus

   # HEAD: 4faefda97bc1be6ca909ba0fd0927ea78f37f67e x86/io_apic: Make 
eoi_ioapic_pin() static

The main changes in this cycle were:

 - Numachip updates: new hardware support, fixes and cleanups. (Daniel J 
Blueman)

 - misc smaller cleanups and fixlets.

  out-of-topic modifications in x86-apic-for-linus:
  ---
  drivers/clocksource/Makefile   # ce2e572cfe7b: x86/numachip: Introduce 
Numa
  drivers/clocksource/numachip.c # ef34cc3428a7: x86/numachip: Fix timer 
buil
   # ce2e572cfe7b: x86/numachip: Introduce Numa

 Thanks,

Ingo

-->
Andy Shevchenko (1):
  x86/io_apic: Make eoi_ioapic_pin() static

Daniel J Blueman (5):
  x86/numachip: Cleanup Numachip support
  x86/numachip: Add Numachip2 APIC support
  x86/numachip: Add Numachip IPI optimisations
  x86/numachip: Introduce Numachip2 timer mechanisms
  x86/numachip: Fix timer build conflict

Denys Vlasenko (1):
  x86/apic: Deinline various functions

Geliang Tang (1):
  x86/irq: Drop unlikely before IS_ERR_OR_NULL

Paolo Bonzini (1):
  x86/x2apic: Make stub functions available even if !CONFIG_X86_LOCAL_APIC


 arch/x86/include/asm/apic.h  | 110 +++---
 arch/x86/include/asm/numachip/numachip.h |   1 +
 arch/x86/include/asm/numachip/numachip_csr.h | 153 +--
 arch/x86/kernel/apic/apic.c  |   8 +-
 arch/x86/kernel/apic/apic_numachip.c | 220 +++
 arch/x86/kernel/apic/io_apic.c   |   2 +-
 arch/x86/kernel/irq_64.c |   2 +-
 drivers/clocksource/Makefile |   1 +
 drivers/clocksource/numachip.c   |  95 
 9 files changed, 360 insertions(+), 232 deletions(-)
 create mode 100644 drivers/clocksource/numachip.c

diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index ebf6d5e5668c..a30316bf801a 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -115,6 +115,59 @@ static inline bool apic_is_x2apic_enabled(void)
return msr & X2APIC_ENABLE;
 }
 
+extern void enable_IR_x2apic(void);
+
+extern int get_physical_broadcast(void);
+
+extern int lapic_get_maxlvt(void);
+extern void clear_local_APIC(void);
+extern void disconnect_bsp_APIC(int virt_wire_setup);
+extern void disable_local_APIC(void);
+extern void lapic_shutdown(void);
+extern void sync_Arb_IDs(void);
+extern void init_bsp_APIC(void);
+extern void setup_local_APIC(void);
+extern void init_apic_mappings(void);
+void register_lapic_address(unsigned long address);
+extern void setup_boot_APIC_clock(void);
+extern void setup_secondary_APIC_clock(void);
+extern int APIC_init_uniprocessor(void);
+
+#ifdef CONFIG_X86_64
+static inline int apic_force_enable(unsigned long addr)
+{
+   return -1;
+}
+#else
+extern int apic_force_enable(unsigned long addr);
+#endif
+
+extern int apic_bsp_setup(bool upmode);
+extern void apic_ap_setup(void);
+
+/*
+ * On 32bit this is mach-xxx local
+ */
+#ifdef CONFIG_X86_64
+extern int apic_is_clustered_box(void);
+#else
+static inline int apic_is_clustered_box(void)
+{
+   return 0;
+}
+#endif
+
+extern int setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask);
+
+#else /* !CONFIG_X86_LOCAL_APIC */
+static inline void lapic_shutdown(void) { }
+#define local_apic_timer_c2_ok 1
+static inline void init_apic_mappings(void) { }
+static inline void disable_local_APIC(void) { }
+# define setup_boot_APIC_clock x86_init_noop
+# define setup_secondary_APIC_clock x86_init_noop
+#endif /* !CONFIG_X86_LOCAL_APIC */
+
 #ifdef CONFIG_X86_X2APIC
 /*
  * Make previous memory operations globally visible before
@@ -186,67 +239,14 @@ static inline int x2apic_enabled(void)
 }
 
 #define x2apic_supported() (cpu_has_x2apic)
-#else
+#else /* !CONFIG_X86_X2APIC */
 static inline void check_x2apic(void) { }
 static inline void x2apic_setup(void) { }
 static inline int x2apic_enabled(void) { return 0; }
 
 #define x2apic_mode(0)
 #definex2apic_supported()  (0)
-#endif
-
-extern void enable_IR_x2apic(void);
-
-extern int get_physical_broadcast(void);
-
-extern int lapic_get_maxlvt(void);
-extern void clear_local_APIC(void);
-extern void disconnect_bsp_APIC(int virt_wire_setup);
-extern void disable_local_APIC(void);
-extern void lapic_shutdown(void);
-extern void sync_Arb_IDs(void);
-extern void init_bsp_APIC(void);
-extern void setup_local_APIC(void);
-extern void init_apic_mappings(void);
-void register_lapic_address(unsigned long address);
-extern void setup_boot_APIC_clock(void);
-extern void setup_secondary_APIC_clock(void);
-extern int APIC_init_uniprocessor(void);
-
-#ifdef CONFIG_X86_64
-static inline int apic_force_enable(unsigned long addr)
-{
-   

Re: [GIT PULL] x86/apic changes for v4.4

2015-11-03 Thread Linus Torvalds
On Tue, Nov 3, 2015 at 2:32 AM, Ingo Molnar  wrote:
>
> Please pull the latest x86-apic-for-linus git tree from:

Side note, I have an *old* patch that I think simplifies the
(reasonably common) case of sending IPI's to individual CPU's. That's
done by the "reschedule ipi" in particular.

That's something that is trivially done on the x2apic, but that the
mask-based interfaces makes insanely complicated.

I have *not* rebased this on top of modern kernels so it may not
actually work as a patch any more, because I'm just sending this out
as a "Hmm, what do you guys think" rather than a real submission.

Comments?

Linus
From 9f09a8b2a1fa58f2e692af4a7283fd1674749d39 Mon Sep 17 00:00:00 2001
From: Linus Torvalds 
Date: Fri, 20 Feb 2015 11:06:02 -0800
Subject: [PATCH] x86: add a single-target IPI function to the apic

We still fall back on the "send mask" versions if an apic definition
doesn't have the single-target version, but at least this allows the
(trivial) case for the common clustered x2apic case.

Signed-off-by: Linus Torvalds 
---
 arch/x86/include/asm/apic.h   |  1 +
 arch/x86/kernel/apic/x2apic_cluster.c |  9 +
 arch/x86/kernel/smp.c | 16 ++--
 3 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 92003f3c8a42..5d47ffcfa65d 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -296,6 +296,7 @@ struct apic {
   unsigned int *apicid);
 
 	/* ipi */
+	void (*send_IPI)(int cpu, int vector);
 	void (*send_IPI_mask)(const struct cpumask *mask, int vector);
 	void (*send_IPI_mask_allbutself)(const struct cpumask *mask,
 	 int vector);
diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c
index e658f21681c8..177c4fb027a1 100644
--- a/arch/x86/kernel/apic/x2apic_cluster.c
+++ b/arch/x86/kernel/apic/x2apic_cluster.c
@@ -23,6 +23,14 @@ static inline u32 x2apic_cluster(int cpu)
 	return per_cpu(x86_cpu_to_logical_apicid, cpu) >> 16;
 }
 
+static void x2apic_send_IPI(int cpu, int vector)
+{
+	u32 dest = per_cpu(x86_cpu_to_logical_apicid, cpu);
+
+	x2apic_wrmsr_fence();
+	__x2apic_send_IPI_dest(dest, vector, APIC_DEST_LOGICAL);
+}
+
 static void
 __x2apic_send_IPI_mask(const struct cpumask *mask, int vector, int apic_dest)
 {
@@ -266,6 +274,7 @@ static struct apic apic_x2apic_cluster = {
 
 	.cpu_mask_to_apicid_and		= x2apic_cpu_mask_to_apicid_and,
 
+	.send_IPI			= x2apic_send_IPI,
 	.send_IPI_mask			= x2apic_send_IPI_mask,
 	.send_IPI_mask_allbutself	= x2apic_send_IPI_mask_allbutself,
 	.send_IPI_allbutself		= x2apic_send_IPI_allbutself,
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index be8e1bde07aa..78c9b12d892a 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -114,6 +114,18 @@ static atomic_t stopping_cpu = ATOMIC_INIT(-1);
 static bool smp_no_nmi_ipi = false;
 
 /*
+ * Helper wrapper: not all apic definitions support sending to
+ * a single CPU, so we fall back to sending to a mask.
+ */
+static void send_IPI_cpu(int cpu, int vector)
+{
+	if (apic->send_IPI)
+		apic->send_IPI(cpu, vector);
+	else
+		apic->send_IPI_mask(cpumask_of(cpu), vector);
+}
+
+/*
  * this function sends a 'reschedule' IPI to another CPU.
  * it goes straight through and wastes no time serializing
  * anything. Worst case is that we lose a reschedule ...
@@ -124,12 +136,12 @@ static void native_smp_send_reschedule(int cpu)
 		WARN_ON(1);
 		return;
 	}
-	apic->send_IPI_mask(cpumask_of(cpu), RESCHEDULE_VECTOR);
+	send_IPI_cpu(cpu, RESCHEDULE_VECTOR);
 }
 
 void native_send_call_func_single_ipi(int cpu)
 {
-	apic->send_IPI_mask(cpumask_of(cpu), CALL_FUNCTION_SINGLE_VECTOR);
+	send_IPI_cpu(cpu, CALL_FUNCTION_SINGLE_VECTOR);
 }
 
 void native_send_call_func_ipi(const struct cpumask *mask)
-- 
2.6.2.402.g2635c2b