Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 22 Nov 2009 14:32:33 +0000 (UTC)
From:      Jun Kuriyama <kuriyama@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r199648 - in stable/8/sys: amd64/amd64 amd64/include i386/i386
Message-ID:  <200911221432.nAMEWXsV020708@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kuriyama
Date: Sun Nov 22 14:32:32 2009
New Revision: 199648
URL: http://svn.freebsd.org/changeset/base/199648

Log:
  - MFC r199067,199215,199253
  
    - Add hw.clflush_disable loader tunable to avoid panic (trap 9) at
      map_invalidate_cache_range() even if CPU is not Intel.
  
    - This tunable can be set to -1 (default), 0 and 1.  -1 is same as
      current behavior, which automatically disable CLFLUSH on Intel CPUs
      without CPUID_SS (should be occured on Xen only).  You can specify 1
      when this panic happened on non-Intel CPUs (such as AMD's).  Because
      disabling CLFLUSH may reduce performance, you can try with setting 0
      on Intel CPUs without SS to use CLFLUSH feature.
  
    - Amd64 init_secondary() calls initializecpu() while curthread is
      still not properly set up. r199067 added the call to
      TUNABLE_INT_FETCH() to initializecpu() that results in hang because
      AP are started when kernel environment is already dynamic and thus
      needs to acquire mutex, that is too early in AP start sequence to
      work.
  
      Extract the code that should be executed only once, because it sets
      up global variables, from initializecpu() to initializecpucache(),
      and call the later only from hammer_time() executed on BSP. Now,
      TUNABLE_INT_FETCH() is done only once at BSP at the early boot
      stage.

Modified:
  stable/8/sys/amd64/amd64/initcpu.c
  stable/8/sys/amd64/amd64/machdep.c
  stable/8/sys/amd64/include/md_var.h
  stable/8/sys/i386/i386/initcpu.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/amd64/amd64/initcpu.c
==============================================================================
--- stable/8/sys/amd64/amd64/initcpu.c	Sun Nov 22 14:04:20 2009	(r199647)
+++ stable/8/sys/amd64/amd64/initcpu.c	Sun Nov 22 14:32:32 2009	(r199648)
@@ -47,6 +47,12 @@ __FBSDID("$FreeBSD$");
 static int	hw_instruction_sse;
 SYSCTL_INT(_hw, OID_AUTO, instruction_sse, CTLFLAG_RD,
     &hw_instruction_sse, 0, "SIMD/MMX2 instructions available in CPU");
+/*
+ * -1: automatic (default)
+ *  0: keep enable CLFLUSH
+ *  1: force disable CLFLUSH
+ */
+static int	hw_clflush_disable = -1;
 
 int	cpu;			/* Are we 386, 386sx, 486, etc? */
 u_int	cpu_feature;		/* Feature flags */
@@ -157,6 +163,11 @@ initializecpu(void)
 	    CPUID_TO_FAMILY(cpu_id) == 0x6 &&
 	    CPUID_TO_MODEL(cpu_id) >= 0xf)
 		init_via();
+}
+
+void
+initializecpucache()
+{
 
 	/*
 	 * CPUID with %eax = 1, %ebx returns
@@ -169,6 +180,15 @@ initializecpu(void)
 	 * XXXKIB: (temporary) hack to work around traps generated when
 	 * CLFLUSHing APIC registers window.
 	 */
-	if (cpu_vendor_id == CPU_VENDOR_INTEL && !(cpu_feature & CPUID_SS))
+	TUNABLE_INT_FETCH("hw.clflush_disable", &hw_clflush_disable);
+	if (cpu_vendor_id == CPU_VENDOR_INTEL && !(cpu_feature & CPUID_SS) &&
+	    hw_clflush_disable == -1)
+		cpu_feature &= ~CPUID_CLFSH;
+	/*
+	 * Allow to disable CLFLUSH feature manually by
+	 * hw.clflush_disable tunable.  This may help Xen guest on some AMD
+	 * CPUs.
+	 */
+	if (hw_clflush_disable == 1)
 		cpu_feature &= ~CPUID_CLFSH;
 }

Modified: stable/8/sys/amd64/amd64/machdep.c
==============================================================================
--- stable/8/sys/amd64/amd64/machdep.c	Sun Nov 22 14:04:20 2009	(r199647)
+++ stable/8/sys/amd64/amd64/machdep.c	Sun Nov 22 14:32:32 2009	(r199648)
@@ -1667,6 +1667,7 @@ hammer_time(u_int64_t modulep, u_int64_t
 
 	identify_cpu();		/* Final stage of CPU initialization */
 	initializecpu();	/* Initialize CPU registers */
+	initializecpucache();
 
 	/* make an initial tss so cpu can get interrupt stack on syscall! */
 	common_tss[0].tss_rsp0 = thread0.td_kstack + \

Modified: stable/8/sys/amd64/include/md_var.h
==============================================================================
--- stable/8/sys/amd64/include/md_var.h	Sun Nov 22 14:04:20 2009	(r199647)
+++ stable/8/sys/amd64/include/md_var.h	Sun Nov 22 14:32:32 2009	(r199648)
@@ -89,6 +89,7 @@ void	gs_load_fault(void) __asm(__STRING(
 void	dump_add_page(vm_paddr_t);
 void	dump_drop_page(vm_paddr_t);
 void	initializecpu(void);
+void	initializecpucache(void);
 void	fillw(int /*u_short*/ pat, void *base, size_t cnt);
 void	fpstate_drop(struct thread *td);
 int	is_physical_memory(vm_paddr_t addr);

Modified: stable/8/sys/i386/i386/initcpu.c
==============================================================================
--- stable/8/sys/i386/i386/initcpu.c	Sun Nov 22 14:04:20 2009	(r199647)
+++ stable/8/sys/i386/i386/initcpu.c	Sun Nov 22 14:32:32 2009	(r199648)
@@ -75,6 +75,12 @@ static void	init_mendocino(void);
 static int	hw_instruction_sse;
 SYSCTL_INT(_hw, OID_AUTO, instruction_sse, CTLFLAG_RD,
     &hw_instruction_sse, 0, "SIMD/MMX2 instructions available in CPU");
+/*
+ * -1: automatic (default)
+ *  0: keep enable CLFLUSH
+ *  1: force disable CLFLUSH
+ */
+static int	hw_clflush_disable = -1;
 
 /* Must *NOT* be BSS or locore will bzero these after setting them */
 int	cpu = 0;		/* Are we 386, 386sx, 486, etc? */
@@ -721,7 +727,16 @@ initializecpu(void)
 	 * XXXKIB: (temporary) hack to work around traps generated when
 	 * CLFLUSHing APIC registers window.
 	 */
-	if (cpu_vendor_id == CPU_VENDOR_INTEL && !(cpu_feature & CPUID_SS))
+	TUNABLE_INT_FETCH("hw.clflush_disable", &hw_clflush_disable);
+	if (cpu_vendor_id == CPU_VENDOR_INTEL && !(cpu_feature & CPUID_SS) &&
+	    hw_clflush_disable == -1)
+		cpu_feature &= ~CPUID_CLFSH;
+	/*
+	 * Allow to disable CLFLUSH feature manually by
+	 * hw.clflush_disable tunable.  This may help Xen guest on some AMD
+	 * CPUs.
+	 */
+	if (hw_clflush_disable == 1)
 		cpu_feature &= ~CPUID_CLFSH;
 
 #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911221432.nAMEWXsV020708>