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
---
 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);
        }

---
 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: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Adeos-main mailing list
[email protected]
https://mail.gna.org/listinfo/adeos-main

Reply via email to