WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Slightly disgusting hack to avoid using lots of lock ins

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Slightly disgusting hack to avoid using lots of lock instructions on a uniprocessor
From: BitKeeper Bot <riel@xxxxxxxxxxx>
Date: Thu, 16 Jun 2005 11:44:16 +0000
Delivery-date: Sat, 18 Jun 2005 01:01:19 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: Xen Development List <xen-devel@xxxxxxxxxxxxxxxxxxx>
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
ChangeSet 1.1713.1.13, 2005/06/16 12:44:16+01:00, sos22@xxxxxxxxxxxxxxxxxxxx

        Slightly disgusting hack to avoid using lots of lock instructions on a 
uniprocessor
        machine just because we happened to compile with CONFIG_SMP.  
Essentially, we
        make a big table of all of the instruction sequences which differ in 
``easy''
        ways between UP and SMP kernels, and then select which one to use at 
run time.
        
        Signed-off-by: Steven Smith <sos22@xxxxxxxxx>



 linux-2.6.11-xen-sparse/arch/xen/i386/Kconfig             |   13 
 linux-2.6.11-xen-sparse/arch/xen/i386/kernel/Makefile     |    1 
 linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c    |   17 
 linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/system.h |   57 ++
 patches/linux-2.6.11/smp-alts.patch                       |  302 ++++++++++++++
 5 files changed, 384 insertions(+), 6 deletions(-)


diff -Nru a/linux-2.6.11-xen-sparse/arch/xen/i386/Kconfig 
b/linux-2.6.11-xen-sparse/arch/xen/i386/Kconfig
--- a/linux-2.6.11-xen-sparse/arch/xen/i386/Kconfig     2005-06-17 21:02:25 
-04:00
+++ b/linux-2.6.11-xen-sparse/arch/xen/i386/Kconfig     2005-06-17 21:02:25 
-04:00
@@ -372,6 +372,19 @@
 
          If you don't know what to do here, say N.
 
+config SMP_ALTERNATIVES
+        bool "SMP alternatives support (EXPERIMENTAL)"
+        depends on SMP && EXPERIMENTAL
+        help
+          Try to reduce the overhead of running an SMP kernel on a uniprocessor
+          host slightly by replacing certain key instruction sequences
+          according to whether we currently have more than one CPU available.
+          This should provide a noticeable boost to performance when
+          running SMP kernels on UP machines, and have negligible impact
+          when running on an true SMP host.
+
+          If unsure, say N.
+
 config NR_CPUS
        int "Maximum number of CPUs (2-255)"
        range 2 255
diff -Nru a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/Makefile 
b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/Makefile
--- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/Makefile     2005-06-17 
21:02:25 -04:00
+++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/Makefile     2005-06-17 
21:02:25 -04:00
@@ -42,6 +42,7 @@
 c-obj-$(CONFIG_HPET_TIMER)     += time_hpet.o
 c-obj-$(CONFIG_EFI)            += efi.o efi_stub.o
 c-obj-$(CONFIG_EARLY_PRINTK)   += early_printk.o
+c-obj-$(CONFIG_SMP_ALTERNATIVES)+= smpalts.o
 
 EXTRA_AFLAGS   := -traditional
 
diff -Nru a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c 
b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c
--- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c    2005-06-17 
21:02:25 -04:00
+++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c    2005-06-17 
21:02:25 -04:00
@@ -54,6 +54,8 @@
 #include <asm/desc.h>
 #include <asm/arch_hooks.h>
 
+#include <asm/smp_alt.h>
+
 #ifndef CONFIG_X86_IO_APIC
 #define Dprintk(args...)
 #endif
@@ -1186,6 +1188,10 @@
                if (max_cpus <= cpucount+1)
                        continue;
 
+#ifdef CONFIG_SMP_ALTERNATIVES
+               if (kicked == 1)
+                       prepare_for_smp();
+#endif
                if (do_boot_cpu(cpu))
                        printk("CPU #%d not responding - cannot use it.\n",
                                                                cpu);
@@ -1301,6 +1307,11 @@
 /* must be called with the cpucontrol mutex held */
 static int __devinit cpu_enable(unsigned int cpu)
 {
+#ifdef CONFIG_SMP_ALTERNATIVES
+       if (num_online_cpus() == 1)
+               prepare_for_smp();
+#endif
+
        /* get the target out of its holding state */
        per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
        wmb();
@@ -1340,6 +1351,12 @@
        fixup_irqs(map);
        /* It's now safe to remove this processor from the online map */
        cpu_clear(cpu, cpu_online_map);
+
+#ifdef CONFIG_SMP_ALTERNATIVES
+       if (num_online_cpus() == 1)
+               unprepare_for_smp();
+#endif
+
        return 0;
 }
 
diff -Nru a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/system.h 
b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/system.h
--- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/system.h 2005-06-17 
21:02:25 -04:00
+++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/system.h 2005-06-17 
21:02:25 -04:00
@@ -8,6 +8,7 @@
 #include <asm/segment.h>
 #include <asm/cpufeature.h>
 #include <asm-xen/hypervisor.h>
+#include <asm/smp_alt.h>
 
 #ifdef __KERNEL__
 
@@ -251,19 +252,19 @@
        unsigned long prev;
        switch (size) {
        case 1:
-               __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
+               __asm__ __volatile__(LOCK "cmpxchgb %b1,%2"
                                     : "=a"(prev)
                                     : "q"(new), "m"(*__xg(ptr)), "0"(old)
                                     : "memory");
                return prev;
        case 2:
-               __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
+               __asm__ __volatile__(LOCK "cmpxchgw %w1,%2"
                                     : "=a"(prev)
                                     : "q"(new), "m"(*__xg(ptr)), "0"(old)
                                     : "memory");
                return prev;
        case 4:
-               __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
+               __asm__ __volatile__(LOCK "cmpxchgl %1,%2"
                                     : "=a"(prev)
                                     : "q"(new), "m"(*__xg(ptr)), "0"(old)
                                     : "memory");
@@ -427,11 +428,55 @@
 #endif
 
 #ifdef CONFIG_SMP
-#define smp_mb()       mb()
-#define smp_rmb()      rmb()
 #define smp_wmb()      wmb()
-#define smp_read_barrier_depends()     read_barrier_depends()
+#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
+#define smp_alt_mb(instr)                                           \
+__asm__ __volatile__("6667:\nnop\nnop\nnop\nnop\nnop\nnop\n6668:\n" \
+                    ".section __smp_alternatives,\"a\"\n"          \
+                    ".long 6667b\n"                                \
+                     ".long 6673f\n"                                \
+                    ".previous\n"                                  \
+                    ".section __smp_replacements,\"a\"\n"          \
+                    "6673:.byte 6668b-6667b\n"                     \
+                    ".byte 6670f-6669f\n"                          \
+                    ".byte 6671f-6670f\n"                          \
+                     ".byte 0\n"                                    \
+                    ".byte %c0\n"                                  \
+                    "6669:lock;addl $0,0(%%esp)\n"                 \
+                    "6670:" instr "\n"                             \
+                    "6671:\n"                                      \
+                    ".previous\n"                                  \
+                    :                                              \
+                    : "i" (X86_FEATURE_XMM2)                       \
+                    : "memory")
+#define smp_rmb() smp_alt_mb("lfence")
+#define smp_mb()  smp_alt_mb("mfence")
+#define set_mb(var, value) do {                                     \
+unsigned long __set_mb_temp;                                        \
+__asm__ __volatile__("6667:movl %1, %0\n6668:\n"                    \
+                    ".section __smp_alternatives,\"a\"\n"          \
+                    ".long 6667b\n"                                \
+                    ".long 6673f\n"                                \
+                    ".previous\n"                                  \
+                    ".section __smp_replacements,\"a\"\n"          \
+                    "6673: .byte 6668b-6667b\n"                    \
+                    ".byte 6670f-6669f\n"                          \
+                    ".byte 0\n"                                    \
+                    ".byte 6671f-6670f\n"                          \
+                    ".byte -1\n"                                   \
+                    "6669: xchg %1, %0\n"                          \
+                    "6670:movl %1, %0\n"                           \
+                    "6671:\n"                                      \
+                    ".previous\n"                                  \
+                    : "=m" (var), "=r" (__set_mb_temp)             \
+                    : "1" (value)                                  \
+                    : "memory"); } while (0)
+#else
+#define smp_rmb()      rmb()
+#define smp_mb()       mb()
 #define set_mb(var, value) do { xchg(&var, value); } while (0)
+#endif
+#define smp_read_barrier_depends()     read_barrier_depends()
 #else
 #define smp_mb()       barrier()
 #define smp_rmb()      barrier()
diff -Nru a/patches/linux-2.6.11/smp-alts.patch 
b/patches/linux-2.6.11/smp-alts.patch
--- /dev/null   Wed Dec 31 16:00:00 196900
+++ b/patches/linux-2.6.11/smp-alts.patch       2005-06-17 21:02:25 -04:00
@@ -0,0 +1,554 @@
+diff -Naur linux-2.6.11/arch/i386/Kconfig linux-2.6.11.post/arch/i386/Kconfig
+--- linux-2.6.11/arch/i386/Kconfig     2005-03-02 07:37:49.000000000 +0000
++++ linux-2.6.11.post/arch/i386/Kconfig        2005-06-10 13:42:35.000000000 
+0100
+@@ -481,6 +481,19 @@
+ 
+         If you don't know what to do here, say N.
+ 
++config SMP_ALTERNATIVES
++      bool "SMP alternatives support (EXPERIMENTAL)"
++      depends on SMP && EXPERIMENTAL
++      help
++        Try to reduce the overhead of running an SMP kernel on a uniprocessor
++        host slightly by replacing certain key instruction sequences
++        according to whether we currently have more than one CPU available.
++        This should provide a noticeable boost to performance when
++        running SMP kernels on UP machines, and have negligible impact
++        when running on an true SMP host.
++
++          If unsure, say N.
++        
+ config NR_CPUS
+       int "Maximum number of CPUs (2-255)"
+       range 2 255
+diff -Naur linux-2.6.11/arch/i386/kernel/Makefile 
linux-2.6.11.post/arch/i386/kernel/Makefile
+--- linux-2.6.11/arch/i386/kernel/Makefile     2005-03-02 07:37:49.000000000 
+0000
++++ linux-2.6.11.post/arch/i386/kernel/Makefile        2005-06-16 
11:16:18.555332435 +0100
+@@ -32,6 +32,7 @@
+ obj-$(CONFIG_HPET_TIMER)      += time_hpet.o
+ obj-$(CONFIG_EFI)             += efi.o efi_stub.o
+ obj-$(CONFIG_EARLY_PRINTK)    += early_printk.o
++obj-$(CONFIG_SMP_ALTERNATIVES)  += smpalts.o
+ 
+ EXTRA_AFLAGS   := -traditional
+ 
+diff -Naur linux-2.6.11/arch/i386/kernel/smpalts.c 
linux-2.6.11.post/arch/i386/kernel/smpalts.c
+--- linux-2.6.11/arch/i386/kernel/smpalts.c    1970-01-01 01:00:00.000000000 
+0100
++++ linux-2.6.11.post/arch/i386/kernel/smpalts.c       2005-06-16 
11:23:39.300902424 +0100
+@@ -0,0 +1,76 @@
++#include <linux/kernel.h>
++#include <asm/system.h>
++#include <asm/smp_alt.h>
++#include <asm/processor.h>
++#include <asm/string.h>
++
++struct smp_replacement_record {
++      unsigned char targ_size;
++      unsigned char smp1_size;
++      unsigned char smp2_size;
++      unsigned char up_size;
++      unsigned char feature;
++      unsigned char data[0];
++};
++
++struct smp_alternative_record {
++      void *targ_start;
++      struct smp_replacement_record *repl;
++};
++
++extern struct smp_alternative_record __start_smp_alternatives_table,
++  __stop_smp_alternatives_table;
++
++void prepare_for_smp(void)
++{
++      struct smp_alternative_record *r;
++      printk(KERN_INFO "Enabling SMP...\n");
++      for (r = &__start_smp_alternatives_table;
++           r != &__stop_smp_alternatives_table;
++           r++) {
++              BUG_ON(r->repl->targ_size < r->repl->smp1_size);
++              BUG_ON(r->repl->targ_size < r->repl->smp2_size);
++              BUG_ON(r->repl->targ_size < r->repl->up_size);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Slightly disgusting hack to avoid using lots of lock instructions on a uniprocessor, BitKeeper Bot <=