All of lore.kernel.org
 help / color / mirror / Atom feed
* [Adeos-main] [PATCH 8/7] Optimise cpuid passing (i386)
@ 2007-04-27 19:03 Jan Kiszka
  0 siblings, 0 replies; only message in thread
From: Jan Kiszka @ 2007-04-27 19:03 UTC (permalink / raw)
  To: adeos-main; +Cc: Philippe Gerum


[-- Attachment #1.1: Type: text/plain, Size: 610 bytes --]

Looking at a disassembled kernel (Mathias' MSI issue...), I got some
idea how to optimise the I-pipe-internal cpuid passing, and I applied it
on further functions.

With the help of the preprocessor, we now eliminate any cpuid parameters
on UP completely, save a few bytes around __ipipe_walk_pipeline. And on
SMP, we don't have to reload it in internal functions that are called by
others who already did so. I think this is faster than consulting the
hardware (via the __ipipe_logical_cpuid indirection).

Only prototyped on i386, just build-tested, so it should be no problem
to apply...

Jan

[-- Attachment #1.2: optimise-cpuid.patch --]
[-- Type: text/plain, Size: 7042 bytes --]

---
 include/linux/ipipe.h |   21 ++++++++++++++++-----
 kernel/ipipe/core.c   |   29 ++++++++++++++---------------
 2 files changed, 30 insertions(+), 20 deletions(-)

Index: linux-2.6.20/include/linux/ipipe.h
===================================================================
--- linux-2.6.20.orig/include/linux/ipipe.h
+++ linux-2.6.20/include/linux/ipipe.h
@@ -95,6 +95,7 @@
 
 #define IPIPE_NR_CPUS		NR_CPUS
 #define ipipe_declare_cpuid	int cpuid
+#define ipipe_define_up_cpuid	do { } while (0)
 #define ipipe_load_cpuid()	do { \
 					cpuid = ipipe_processor_id();	\
 				} while(0)
@@ -111,6 +112,7 @@
 
 #define IPIPE_NR_CPUS		1
 #define ipipe_declare_cpuid	const int cpuid = 0
+#define ipipe_define_up_cpuid	ipipe_declare_cpuid
 #define ipipe_load_cpuid()	do { } while(0)
 #define ipipe_lock_cpu(flags)	local_irq_save_hw(flags)
 #define ipipe_unlock_cpu(flags)	local_irq_restore_hw(flags)
@@ -304,15 +306,24 @@ void __ipipe_remove_domain_proc(struct i
 
 void __ipipe_flush_printk(unsigned irq, void *cookie);
 
-void fastcall __ipipe_walk_pipeline(struct list_head *pos, int cpuid);
-
 int fastcall __ipipe_schedule_irq(unsigned irq, struct list_head *head);
 
 int fastcall __ipipe_dispatch_event(unsigned event, void *data);
 
-int fastcall __ipipe_dispatch_wired(struct ipipe_domain *head, unsigned irq);
+#ifndef CONFIG_SMP
+/* Eliminate cpuid parameter */
+#define __ipipe_dispatch_wired(head, irq, cpuid) \
+	__ipipe_dispatch_wired(head, irq)
+#define __ipipe_sync_stage(syncmask, cpuid)	__ipipe_sync_stage(syncmask)
+#define __ipipe_walk_pipeline(pos, cpuid)	__ipipe_walk_pipeline(pos)
+#endif /* !CONFIG_SMP */
+
+int __ipipe_dispatch_wired(struct ipipe_domain *head, unsigned irq,
+			   int cpuid);
+
+void __ipipe_sync_stage(unsigned long syncmask, int cpuid);
 
-void fastcall __ipipe_sync_stage(unsigned long syncmask);
+void __ipipe_walk_pipeline(struct list_head *pos, int cpuid);
 
 void __ipipe_pin_range_globally(unsigned long start, unsigned long end);
 
@@ -322,7 +333,7 @@ int __ipipe_pin_range_mapping(struct mm_
 			      unsigned long start, unsigned long end);
 
 #ifndef __ipipe_sync_pipeline
-#define __ipipe_sync_pipeline(syncmask) __ipipe_sync_stage(syncmask)
+#define __ipipe_sync_pipeline(syncmask, cpuid) __ipipe_sync_stage(syncmask, cpuid)
 #endif
 
 #ifndef __ipipe_run_irqtail
Index: linux-2.6.20/kernel/ipipe/core.c
===================================================================
--- linux-2.6.20.orig/kernel/ipipe/core.c
+++ linux-2.6.20/kernel/ipipe/core.c
@@ -198,7 +198,7 @@ void __ipipe_unstall_root(void)
         __clear_bit(IPIPE_STALL_FLAG, &ipipe_root_domain->cpudata[cpuid].status);
 
         if (unlikely(ipipe_root_domain->cpudata[cpuid].irq_pending_hi != 0))
-                __ipipe_sync_pipeline(IPIPE_IRQMASK_ANY);
+                __ipipe_sync_pipeline(IPIPE_IRQMASK_ANY, cpuid);
 
         local_irq_enable_hw();
 }
@@ -316,7 +316,7 @@ void ipipe_unstall_pipeline_head(void)
 
 	if (unlikely(head->cpudata[cpuid].irq_pending_hi != 0)) {
 		if (likely(head == per_cpu(ipipe_percpu_domain, cpuid)))
-			__ipipe_sync_pipeline(IPIPE_IRQMASK_ANY);
+			__ipipe_sync_pipeline(IPIPE_IRQMASK_ANY, cpuid);
 		else
 			__ipipe_walk_pipeline(&head->p_link, cpuid);
         }
@@ -352,7 +352,7 @@ void fastcall __ipipe_restore_pipeline_h
 		__clear_bit(IPIPE_STALL_FLAG, &head->cpudata[cpuid].status);
 		if (unlikely(head->cpudata[cpuid].irq_pending_hi != 0)) {
 			if (likely(head == per_cpu(ipipe_percpu_domain, cpuid)))
-				__ipipe_sync_pipeline(IPIPE_IRQMASK_ANY);
+				__ipipe_sync_pipeline(IPIPE_IRQMASK_ANY, cpuid);
 			else
 				__ipipe_walk_pipeline(&head->p_link, cpuid);
 		}
@@ -363,8 +363,9 @@ void fastcall __ipipe_restore_pipeline_h
 /* __ipipe_walk_pipeline(): Plays interrupts pending in the log. Must
    be called with local hw interrupts disabled. */
 
-void fastcall __ipipe_walk_pipeline(struct list_head *pos, int cpuid)
+void __ipipe_walk_pipeline(struct list_head *pos, int cpuid)
 {
+	ipipe_define_up_cpuid;
 	struct ipipe_domain *this_domain = per_cpu(ipipe_percpu_domain, cpuid);
 
 	while (pos != &__ipipe_pipeline) {
@@ -378,7 +379,7 @@ void fastcall __ipipe_walk_pipeline(stru
 		if (next_domain->cpudata[cpuid].irq_pending_hi != 0) {
 
 			if (next_domain == this_domain)
-				__ipipe_sync_pipeline(IPIPE_IRQMASK_ANY);
+				__ipipe_sync_pipeline(IPIPE_IRQMASK_ANY, cpuid);
 			else {
 				__ipipe_switch_to(this_domain, next_domain,
 						  cpuid);
@@ -389,7 +390,7 @@ void fastcall __ipipe_walk_pipeline(stru
 				    irq_pending_hi != 0
 				    && !test_bit(IPIPE_STALL_FLAG,
 						 &this_domain->cpudata[cpuid].status))
-					__ipipe_sync_pipeline(IPIPE_IRQMASK_ANY);
+					__ipipe_sync_pipeline(IPIPE_IRQMASK_ANY, cpuid);
 			}
 
 			break;
@@ -438,7 +439,7 @@ void ipipe_suspend_domain(void)
 		per_cpu(ipipe_percpu_domain, cpuid) = next_domain;
 
 sync_stage:
-		__ipipe_sync_pipeline(IPIPE_IRQMASK_ANY);
+		__ipipe_sync_pipeline(IPIPE_IRQMASK_ANY, cpuid);
 
 		ipipe_load_cpuid();	/* Processor might have changed. */
 
@@ -663,7 +664,7 @@ int fastcall __ipipe_dispatch_event (uns
 		    next_domain->cpudata[cpuid].irq_pending_hi != 0 &&
 		    !test_bit(IPIPE_STALL_FLAG,&next_domain->cpudata[cpuid].status)) {
 			per_cpu(ipipe_percpu_domain, cpuid) = next_domain;
-			__ipipe_sync_pipeline(IPIPE_IRQMASK_ANY);
+			__ipipe_sync_pipeline(IPIPE_IRQMASK_ANY, cpuid);
 			ipipe_load_cpuid();
 			if (per_cpu(ipipe_percpu_domain, cpuid) != next_domain)
 				this_domain = per_cpu(ipipe_percpu_domain, cpuid);
@@ -706,13 +707,12 @@ int fastcall __ipipe_dispatch_event (uns
  * Called with hw interrupts off.
  */
 
-int fastcall __ipipe_dispatch_wired(struct ipipe_domain *head, unsigned irq)
+int __ipipe_dispatch_wired(struct ipipe_domain *head, unsigned irq, int cpuid)
 {
 	struct ipcpudata *cpudata;
 	struct ipipe_domain *old;
-	ipipe_declare_cpuid;
+	ipipe_define_up_cpuid;
 
-	ipipe_load_cpuid();
 	cpudata = &head->cpudata[cpuid];
 	cpudata->irq_counters[irq].total_hits++;
 
@@ -762,16 +762,15 @@ int fastcall __ipipe_dispatch_wired(stru
  *
  * This routine must be called with hw interrupts off.
  */
-void fastcall __ipipe_sync_stage(unsigned long syncmask)
+void __ipipe_sync_stage(unsigned long syncmask, int cpuid)
 {
 	unsigned long mask, submask;
 	struct ipcpudata *cpudata;
 	struct ipipe_domain *ipd;
-	ipipe_declare_cpuid;
 	int level, rank;
 	unsigned irq;
+	ipipe_define_up_cpuid;
 
-	ipipe_load_cpuid();
 	ipd = per_cpu(ipipe_percpu_domain, cpuid);
 	cpudata = &ipd->cpudata[cpuid];
 
@@ -931,7 +930,7 @@ int ipipe_register_domain(struct ipipe_d
 		if (ipipe_root_domain->cpudata[cpuid].irq_pending_hi != 0 &&
 		    !test_bit(IPIPE_STALL_FLAG,
 			      &ipipe_root_domain->cpudata[cpuid].status))
-			__ipipe_sync_pipeline(IPIPE_IRQMASK_ANY);
+			__ipipe_sync_pipeline(IPIPE_IRQMASK_ANY, cpuid);
 
 		ipipe_unlock_cpu(flags);
 	}


[-- Attachment #1.3: optimise-cpuid-i386.patch --]
[-- Type: text/plain, Size: 1430 bytes --]

---
 arch/i386/kernel/ipipe.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Index: linux-2.6.20/arch/i386/kernel/ipipe.c
===================================================================
--- linux-2.6.20.orig/arch/i386/kernel/ipipe.c
+++ linux-2.6.20/arch/i386/kernel/ipipe.c
@@ -574,7 +574,7 @@ asmlinkage void __ipipe_unstall_iret_roo
 
 		if ((ipipe_root_domain->cpudata[cpuid].
 		     irq_pending_hi & IPIPE_IRQMASK_VIRT) != 0)
-			__ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT);
+			__ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT, cpuid);
 	}
 #ifdef CONFIG_IPIPE_TRACE_IRQSOFF
 	ipipe_trace_end(0x8000000D);
@@ -612,7 +612,7 @@ asmlinkage int __ipipe_syscall_root(stru
 			 * is tested. */
 			ipipe_lock_cpu(flags);
 			if ((ipipe_root_domain->cpudata[cpuid].irq_pending_hi & IPIPE_IRQMASK_VIRT) != 0)
-				__ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT);
+				__ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT, cpuid);
 			ipipe_unlock_cpu(flags);
 			return -1;
 		}
@@ -785,7 +785,7 @@ int __ipipe_handle_irq(struct pt_regs re
 	if (likely(test_bit(IPIPE_WIRED_FLAG, &next_domain->irqs[irq].control))) {
 		if (!m_ack && next_domain->irqs[irq].acknowledge != NULL)
 			next_domain->irqs[irq].acknowledge(irq);
-		if (likely(__ipipe_dispatch_wired(next_domain, irq))) {
+		if (likely(__ipipe_dispatch_wired(next_domain, irq, cpuid))) {
 			ipipe_load_cpuid();
 			goto finalize;
 		} else


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 250 bytes --]

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2007-04-27 19:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-27 19:03 [Adeos-main] [PATCH 8/7] Optimise cpuid passing (i386) Jan Kiszka

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.