The first one is a real patch, introducing an optimisation of the stall/unstall-root path of I-pipe. It removes any caring for the pipeline head case of the root doamin from ipipe_root_stall (something that was lacking for test_and_stall_root anyway), and it pushes under UP the IRQ disabling into the less likely __ipipe_sync_pipeline path in ipipe_unstall_root.
Those two changes together gave me about 5% better Linux performance under RT-load on a low-end Pentium. A further idea of mine was to inline light-weight parts of the __ipipe_*_root API on UP (no SMP at hand to judge on it as well). That's what the second patch, err, hack is for. It gives another 5% Linux speedup on x86, but it unfortunately contains some tricky dependency issues. Of course, it also slightly increases the code size again. Looking at other linux/ipipe.h duplications, e.g. in linux/preempt.h, it might be worth considering to derive a basic header that has no further dependencies and can be included anywhere. Based on such header the proposed optimisation could be built up more cleanly. Jan
---
kernel/ipipe/core.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
Index: linux-2.6.17.13/kernel/ipipe/core.c
===================================================================
--- linux-2.6.17.13.orig/kernel/ipipe/core.c
+++ linux-2.6.17.13/kernel/ipipe/core.c
@@ -134,16 +134,8 @@ void __ipipe_stall_root(void)
unsigned long flags;
ipipe_get_cpu(flags); /* Care for migration. */
-
set_bit(IPIPE_STALL_FLAG, &ipipe_root_domain->cpudata[cpuid].status);
-
-#ifdef CONFIG_SMP
- if (!__ipipe_pipeline_head_p(ipipe_root_domain))
- ipipe_put_cpu(flags);
-#else /* CONFIG_SMP */
- if (__ipipe_pipeline_head_p(ipipe_root_domain))
- local_irq_disable_hw();
-#endif /* CONFIG_SMP */
+ ipipe_put_cpu(flags);
}
void __ipipe_cleanup_domain(struct ipipe_domain *ipd)
@@ -166,6 +158,7 @@ void __ipipe_unstall_root(void)
{
ipipe_declare_cpuid;
+#ifdef CONFIG_SMP
local_irq_disable_hw();
ipipe_load_cpuid();
@@ -176,6 +169,15 @@ void __ipipe_unstall_root(void)
__ipipe_sync_pipeline(IPIPE_IRQMASK_ANY);
local_irq_enable_hw();
+#else /* !CONFIG_SMP */
+ __clear_bit(IPIPE_STALL_FLAG, &ipipe_root_domain->cpudata[cpuid].status);
+
+ if (unlikely(ipipe_root_domain->cpudata[cpuid].irq_pending_hi != 0)) {
+ local_irq_disable_hw();
+ __ipipe_sync_pipeline(IPIPE_IRQMASK_ANY);
+ local_irq_enable_hw();
+ }
+#endif /* CONFIG_SMP */
}
unsigned long __ipipe_test_root(void)
---
arch/i386/kernel/entry.S | 2 -
include/asm-i386/system.h | 51 +++++++++++++++++++++++++++++++++++++++++++---
include/linux/ipipe.h | 34 +++++++++++++++++++++++-------
kernel/ipipe/core.c | 26 +++++++++++++----------
4 files changed, 90 insertions(+), 23 deletions(-)
Index: linux-2.6.17.13/include/linux/ipipe.h
===================================================================
--- linux-2.6.17.13.orig/include/linux/ipipe.h
+++ linux-2.6.17.13/include/linux/ipipe.h
@@ -356,18 +356,12 @@ void __ipipe_remove_domain_proc(struct i
void __ipipe_flush_printk(unsigned irq, void *cookie);
-void __ipipe_stall_root(void);
-
-void __ipipe_unstall_root(void);
-
-unsigned long __ipipe_test_root(void);
-
-unsigned long __ipipe_test_and_stall_root(void);
-
void fastcall __ipipe_walk_pipeline(struct list_head *pos, int cpuid);
void fastcall __ipipe_restore_root(unsigned long x);
+void __ipipe_unstall_root(void);
+
int fastcall __ipipe_schedule_irq(unsigned irq, struct list_head *head);
int fastcall __ipipe_dispatch_event(unsigned event, void *data);
@@ -403,6 +397,30 @@ cpumask_t __ipipe_set_irq_affinity(unsig
int fastcall __ipipe_send_ipi(unsigned ipi,
cpumask_t cpumask);
+void __ipipe_stall_root(void);
+
+unsigned long __ipipe_test_root(void);
+
+unsigned long __ipipe_test_and_stall_root(void);
+
+#else /* !CONFIG_SMP */
+
+static inline void __ipipe_stall_root(void)
+{
+ set_bit(IPIPE_STALL_FLAG, &ipipe_root_domain->cpudata[0].status);
+}
+
+static inline unsigned long __ipipe_test_root(void)
+{
+ return test_bit(IPIPE_STALL_FLAG, &ipipe_root_domain->cpudata[0].status);
+}
+
+static inline unsigned long __ipipe_test_and_stall_root(void)
+{
+ return test_and_set_bit(IPIPE_STALL_FLAG,
+ &ipipe_root_domain->cpudata[0].status);
+}
+
#endif /* CONFIG_SMP */
/* Called with hw interrupts off. */
Index: linux-2.6.17.13/include/asm-i386/system.h
===================================================================
--- linux-2.6.17.13.orig/include/asm-i386/system.h
+++ linux-2.6.17.13/include/asm-i386/system.h
@@ -462,6 +462,9 @@ static inline unsigned long long __cmpxc
#include <linux/linkage.h>
+void fastcall __ipipe_restore_root(unsigned long flags);
+
+#ifdef CONFIG_SMP
void __ipipe_stall_root(void);
void __ipipe_unstall_root(void);
@@ -470,16 +473,58 @@ unsigned long __ipipe_test_root(void);
unsigned long __ipipe_test_and_stall_root(void);
-void fastcall __ipipe_restore_root(unsigned long flags);
+#elif !defined(__LINUX_IPIPE_H)
+
+#define HACK_IPIPE_STALL_FLAG 0 /* Stalls a pipeline stage -- guaranteed at bit #0 */
+
+struct __HACK_ipipe_domain {
+
+ void *fill1, *fill2;
+
+ struct {
+ unsigned long status;
+ } cpudata[1];
+};
+
+extern struct ipipe_domain ipipe_root;
+
+#define HACK_ipipe_root_domain ((struct __HACK_ipipe_domain *)&ipipe_root)
+
+static inline void __HACK_ipipe_stall_root(void)
+{
+ set_bit(HACK_IPIPE_STALL_FLAG, &HACK_ipipe_root_domain->cpudata[0].status);
+}
+
+static inline unsigned long __HACK_ipipe_test_root(void)
+{
+ return test_bit(HACK_IPIPE_STALL_FLAG, &HACK_ipipe_root_domain->cpudata[0].status);
+}
+
+static inline unsigned long __HACK_ipipe_test_and_stall_root(void)
+{
+ return test_and_set_bit(HACK_IPIPE_STALL_FLAG,
+ &HACK_ipipe_root_domain->cpudata[0].status);
+}
+
+#define local_save_flags(x) ((x) = (!__HACK_ipipe_test_root()) << 9)
+#define local_irq_save(x) ((x) = (!__HACK_ipipe_test_and_stall_root()) << 9)
+#define local_irq_disable() __HACK_ipipe_stall_root()
+
+#define irqs_disabled() __HACK_ipipe_test_root()
+
+#else
#define local_save_flags(x) ((x) = (!__ipipe_test_root()) << 9)
#define local_irq_save(x) ((x) = (!__ipipe_test_and_stall_root()) << 9)
-#define local_irq_restore(x) __ipipe_restore_root(!(x & 0x200))
#define local_irq_disable() __ipipe_stall_root()
-#define local_irq_enable() __ipipe_unstall_root()
#define irqs_disabled() __ipipe_test_root()
+#endif
+
+#define local_irq_restore(x) __ipipe_restore_root(!(x & 0x200))
+#define local_irq_enable() __ipipe_unstall_root()
+
#define halt() __asm__ __volatile__("hlt": : :"memory")
#ifdef CONFIG_IPIPE_TRACE_IRQSOFF
Index: linux-2.6.17.13/arch/i386/kernel/entry.S
===================================================================
--- linux-2.6.17.13.orig/arch/i386/kernel/entry.S
+++ linux-2.6.17.13/arch/i386/kernel/entry.S
@@ -77,7 +77,7 @@ NT_MASK = 0x00004000
VM_MASK = 0x00020000
#ifdef CONFIG_IPIPE
-#define CLI call __ipipe_stall_root ; sti
+#define CLI btsl $0,ipipe_root+0x8
#define STI call __ipipe_unstall_root
#define STI_COND_HW sti
#define EMULATE_ROOT_IRET(bypass) \
Index: linux-2.6.17.13/kernel/ipipe/core.c
===================================================================
--- linux-2.6.17.13.orig/kernel/ipipe/core.c
+++ linux-2.6.17.13/kernel/ipipe/core.c
@@ -128,16 +128,6 @@ void __ipipe_init_stage(struct ipipe_dom
#endif /* CONFIG_SMP */
}
-void __ipipe_stall_root(void)
-{
- ipipe_declare_cpuid;
- unsigned long flags;
-
- ipipe_get_cpu(flags); /* Care for migration. */
- set_bit(IPIPE_STALL_FLAG, &ipipe_root_domain->cpudata[cpuid].status);
- ipipe_put_cpu(flags);
-}
-
void __ipipe_cleanup_domain(struct ipipe_domain *ipd)
{
ipipe_unstall_pipeline_from(ipd);
@@ -180,6 +170,17 @@ void __ipipe_unstall_root(void)
#endif /* CONFIG_SMP */
}
+#ifdef CONFIG_SMP
+void __ipipe_stall_root(void)
+{
+ ipipe_declare_cpuid;
+ unsigned long flags;
+
+ ipipe_get_cpu(flags); /* Care for migration. */
+ set_bit(IPIPE_STALL_FLAG, &ipipe_root_domain->cpudata[cpuid].status);
+ ipipe_put_cpu(flags);
+}
+
unsigned long __ipipe_test_root(void)
{
unsigned long flags, x;
@@ -204,6 +205,7 @@ unsigned long __ipipe_test_and_stall_roo
return x;
}
+#endif /* CONFIG_SMP */
void fastcall __ipipe_restore_root(unsigned long x)
{
@@ -1047,10 +1049,12 @@ EXPORT_SYMBOL(ipipe_test_and_unstall_pip
EXPORT_SYMBOL(ipipe_unstall_pipeline_head);
EXPORT_SYMBOL(__ipipe_restore_pipeline_head);
EXPORT_SYMBOL(__ipipe_unstall_root);
-EXPORT_SYMBOL(__ipipe_stall_root);
EXPORT_SYMBOL(__ipipe_restore_root);
+#ifdef CONFIG_CMP
+EXPORT_SYMBOL(__ipipe_stall_root);
EXPORT_SYMBOL(__ipipe_test_and_stall_root);
EXPORT_SYMBOL(__ipipe_test_root);
+#endif /* CONFIG_SMP */
EXPORT_SYMBOL(__ipipe_dispatch_event);
EXPORT_SYMBOL(__ipipe_dispatch_wired);
EXPORT_SYMBOL(__ipipe_sync_stage);
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Adeos-main mailing list [email protected] https://mail.gna.org/listinfo/adeos-main
