svn commit: r205235 - in projects/altix/sys: amd64/amd64 amd64/conf amd64/include amd64/linux32 arm/arm arm/conf cddl/contrib/opensolaris/uts/common/fs/zfs cddl/contrib/opensolaris/uts/common/fs/zf...

Marcel Moolenaar marcel at FreeBSD.org
Wed Mar 17 00:53:58 UTC 2010


Author: marcel
Date: Wed Mar 17 00:53:58 2010
New Revision: 205235
URL: http://svn.freebsd.org/changeset/base/205235

Log:
  Merge svn+ssh://svn.freebsd.org/base/head@205234

Modified:
  projects/altix/sys/amd64/amd64/db_trace.c
  projects/altix/sys/amd64/amd64/exception.S
  projects/altix/sys/amd64/amd64/identcpu.c
  projects/altix/sys/amd64/amd64/mca.c
  projects/altix/sys/amd64/amd64/pmap.c
  projects/altix/sys/amd64/amd64/vm_machdep.c
  projects/altix/sys/amd64/conf/GENERIC
  projects/altix/sys/amd64/conf/NOTES
  projects/altix/sys/amd64/conf/XENHVM
  projects/altix/sys/amd64/include/elf.h
  projects/altix/sys/amd64/include/mca.h
  projects/altix/sys/amd64/include/reg.h
  projects/altix/sys/amd64/include/specialreg.h
  projects/altix/sys/amd64/linux32/linux32_sysvec.c
  projects/altix/sys/arm/arm/busdma_machdep.c
  projects/altix/sys/arm/arm/identcpu.c
  projects/altix/sys/arm/arm/vm_machdep.c
  projects/altix/sys/arm/conf/BWCT.hints
  projects/altix/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
  projects/altix/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c
  projects/altix/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_zfetch.c
  projects/altix/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/arc.h
  projects/altix/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
  projects/altix/sys/compat/freebsd32/freebsd32.h
  projects/altix/sys/compat/freebsd32/freebsd32_misc.c
  projects/altix/sys/compat/freebsd32/freebsd32_proto.h
  projects/altix/sys/compat/freebsd32/freebsd32_syscall.h
  projects/altix/sys/compat/freebsd32/freebsd32_syscalls.c
  projects/altix/sys/compat/freebsd32/freebsd32_sysent.c
  projects/altix/sys/compat/freebsd32/freebsd32_util.h
  projects/altix/sys/compat/freebsd32/syscalls.master
  projects/altix/sys/compat/ia32/ia32_reg.h
  projects/altix/sys/compat/ia32/ia32_sysvec.c
  projects/altix/sys/conf/files.amd64
  projects/altix/sys/conf/files.ia64
  projects/altix/sys/conf/options.amd64
  projects/altix/sys/conf/options.i386
  projects/altix/sys/conf/options.ia64
  projects/altix/sys/dev/aac/aac.c
  projects/altix/sys/dev/acpica/acpi_video.c
  projects/altix/sys/dev/agp/agp_i810.c
  projects/altix/sys/dev/ata/ata-raid.c
  projects/altix/sys/dev/bge/if_bge.c
  projects/altix/sys/dev/bwn/if_bwn.c
  projects/altix/sys/dev/drm/drm_pciids.h
  projects/altix/sys/dev/drm/i915_drv.h
  projects/altix/sys/dev/drm/i915_reg.h
  projects/altix/sys/dev/mii/brgphy.c
  projects/altix/sys/dev/msk/if_msk.c
  projects/altix/sys/dev/msk/if_mskreg.h
  projects/altix/sys/dev/pci/vga_pci.c
  projects/altix/sys/dev/siba/siba_core.c
  projects/altix/sys/dev/usb/controller/usb_controller.c
  projects/altix/sys/dev/usb/controller/uss820dci.c
  projects/altix/sys/dev/usb/input/ukbd.c
  projects/altix/sys/dev/usb/serial/uftdi.c
  projects/altix/sys/dev/usb/serial/uvisor.c
  projects/altix/sys/dev/usb/template/usb_template.c
  projects/altix/sys/dev/usb/template/usb_template.h
  projects/altix/sys/dev/usb/template/usb_template_mtp.c
  projects/altix/sys/dev/usb/usb_device.c
  projects/altix/sys/dev/usb/usb_device.h
  projects/altix/sys/dev/usb/usb_generic.c
  projects/altix/sys/dev/usb/usb_transfer.c
  projects/altix/sys/dev/usb/usbdevs
  projects/altix/sys/dev/usb/wlan/if_run.c
  projects/altix/sys/dev/usb/wlan/if_runreg.h
  projects/altix/sys/dev/usb/wlan/if_runvar.h
  projects/altix/sys/dev/xen/netback/netback.c
  projects/altix/sys/fs/fdescfs/fdesc_vnops.c
  projects/altix/sys/fs/nfsserver/nfs_nfsdport.c
  projects/altix/sys/fs/procfs/procfs_dbregs.c
  projects/altix/sys/fs/procfs/procfs_fpregs.c
  projects/altix/sys/fs/procfs/procfs_ioctl.c
  projects/altix/sys/fs/procfs/procfs_map.c
  projects/altix/sys/fs/procfs/procfs_regs.c
  projects/altix/sys/i386/conf/GENERIC
  projects/altix/sys/i386/conf/NOTES
  projects/altix/sys/i386/conf/XEN
  projects/altix/sys/i386/i386/identcpu.c
  projects/altix/sys/i386/i386/mca.c
  projects/altix/sys/i386/i386/mp_machdep.c
  projects/altix/sys/i386/i386/pmap.c
  projects/altix/sys/i386/include/mca.h
  projects/altix/sys/i386/include/specialreg.h
  projects/altix/sys/i386/xen/mp_machdep.c
  projects/altix/sys/ia64/conf/GENERIC
  projects/altix/sys/ia64/conf/NOTES
  projects/altix/sys/ia64/ia64/clock.c
  projects/altix/sys/ia64/ia64/exception.S
  projects/altix/sys/ia64/ia64/genassym.c
  projects/altix/sys/ia64/ia64/highfp.c
  projects/altix/sys/ia64/ia64/interrupt.c
  projects/altix/sys/ia64/ia64/locore.S
  projects/altix/sys/ia64/ia64/machdep.c
  projects/altix/sys/ia64/ia64/mp_machdep.c
  projects/altix/sys/ia64/ia64/nexus.c
  projects/altix/sys/ia64/ia64/sal.c
  projects/altix/sys/ia64/include/clock.h
  projects/altix/sys/ia64/include/elf.h
  projects/altix/sys/ia64/include/intr.h
  projects/altix/sys/ia64/include/intrcnt.h
  projects/altix/sys/ia64/include/reg.h
  projects/altix/sys/ia64/include/smp.h
  projects/altix/sys/kern/imgact_elf.c
  projects/altix/sys/kern/kern_jail.c
  projects/altix/sys/kern/kern_ktr.c
  projects/altix/sys/kern/kern_module.c
  projects/altix/sys/kern/kern_thr.c
  projects/altix/sys/kern/kern_umtx.c
  projects/altix/sys/kern/sys_generic.c
  projects/altix/sys/kern/sys_process.c
  projects/altix/sys/kern/uipc_socket.c
  projects/altix/sys/kern/vfs_aio.c
  projects/altix/sys/kern/vfs_syscalls.c
  projects/altix/sys/mips/cavium/dev/rgmii/octeon_rgmx.c
  projects/altix/sys/mips/cavium/octeon_machdep.c
  projects/altix/sys/mips/conf/AR71XX
  projects/altix/sys/mips/conf/OCTEON1
  projects/altix/sys/mips/conf/OCTEON1-32
  projects/altix/sys/mips/include/cpuregs.h
  projects/altix/sys/mips/include/kdb.h
  projects/altix/sys/mips/include/param.h
  projects/altix/sys/mips/include/pmap.h
  projects/altix/sys/mips/include/smp.h
  projects/altix/sys/mips/mips/db_trace.c
  projects/altix/sys/mips/mips/mp_machdep.c
  projects/altix/sys/mips/mips/pmap.c
  projects/altix/sys/mips/mips/swtch.S
  projects/altix/sys/mips/mips/vm_machdep.c
  projects/altix/sys/modules/linux/Makefile
  projects/altix/sys/modules/procfs/Makefile
  projects/altix/sys/modules/zfs/Makefile
  projects/altix/sys/net/bpf.c
  projects/altix/sys/net/flowtable.c
  projects/altix/sys/net/flowtable.h
  projects/altix/sys/net/if.h
  projects/altix/sys/net/if_llatbl.c
  projects/altix/sys/net/if_llatbl.h
  projects/altix/sys/net/if_tap.c
  projects/altix/sys/net/if_tun.c
  projects/altix/sys/net/if_var.h
  projects/altix/sys/net/route.h
  projects/altix/sys/net80211/ieee80211_proto.c
  projects/altix/sys/net80211/ieee80211_sta.c
  projects/altix/sys/net80211/ieee80211_tdma.c
  projects/altix/sys/netgraph/ng_socket.c
  projects/altix/sys/netgraph/ng_socketvar.h
  projects/altix/sys/netinet/in_pcb.c
  projects/altix/sys/netinet/in_pcb.h
  projects/altix/sys/netinet/ip_divert.c
  projects/altix/sys/netinet/ip_fw.h
  projects/altix/sys/netinet/ip_input.c
  projects/altix/sys/netinet/ip_ipsec.c
  projects/altix/sys/netinet/ip_output.c
  projects/altix/sys/netinet/ipfw/ip_dn_glue.c
  projects/altix/sys/netinet/ipfw/ip_dn_io.c
  projects/altix/sys/netinet/ipfw/ip_dn_private.h
  projects/altix/sys/netinet/ipfw/ip_dummynet.c
  projects/altix/sys/netinet/ipfw/ip_fw2.c
  projects/altix/sys/netinet/ipfw/ip_fw_dynamic.c
  projects/altix/sys/netinet/ipfw/ip_fw_log.c
  projects/altix/sys/netinet/ipfw/ip_fw_sockopt.c
  projects/altix/sys/netinet/raw_ip.c
  projects/altix/sys/netinet/sctp_crc32.c
  projects/altix/sys/netinet/sctp_crc32.h
  projects/altix/sys/netinet/tcp_subr.c
  projects/altix/sys/netinet/udp_usrreq.c
  projects/altix/sys/netinet6/ip6_output.c
  projects/altix/sys/pc98/conf/GENERIC
  projects/altix/sys/powerpc/aim/mmu_oea64.c
  projects/altix/sys/powerpc/conf/GENERIC
  projects/altix/sys/sparc64/conf/GENERIC
  projects/altix/sys/sun4v/conf/GENERIC
  projects/altix/sys/sys/pcpu.h
  projects/altix/sys/sys/pioctl.h
  projects/altix/sys/sys/pmc.h
  projects/altix/sys/sys/ptrace.h
Directory Properties:
  projects/altix/lib/libstand/   (props changed)
  projects/altix/sys/   (props changed)

Modified: projects/altix/sys/amd64/amd64/db_trace.c
==============================================================================
--- projects/altix/sys/amd64/amd64/db_trace.c	Wed Mar 17 00:37:15 2010	(r205234)
+++ projects/altix/sys/amd64/amd64/db_trace.c	Wed Mar 17 00:53:58 2010	(r205235)
@@ -319,7 +319,7 @@ db_nextframe(struct amd64_frame **fp, db
 			frame_type = INTERRUPT;
 		else if (strcmp(name, "Xfast_syscall") == 0)
 			frame_type = SYSCALL;
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
 		else if (strcmp(name, "Xint0x80_syscall") == 0)
 			frame_type = SYSCALL;
 #endif

Modified: projects/altix/sys/amd64/amd64/exception.S
==============================================================================
--- projects/altix/sys/amd64/amd64/exception.S	Wed Mar 17 00:37:15 2010	(r205234)
+++ projects/altix/sys/amd64/amd64/exception.S	Wed Mar 17 00:53:58 2010	(r205235)
@@ -572,7 +572,7 @@ ENTRY(fork_trampoline)
  * included.
  */
 
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
 	.data
 	.p2align 4
 	.text

Modified: projects/altix/sys/amd64/amd64/identcpu.c
==============================================================================
--- projects/altix/sys/amd64/amd64/identcpu.c	Wed Mar 17 00:37:15 2010	(r205234)
+++ projects/altix/sys/amd64/amd64/identcpu.c	Wed Mar 17 00:53:58 2010	(r205235)
@@ -187,7 +187,9 @@ printcpuinfo(void)
 	if (cpu_vendor_id == CPU_VENDOR_INTEL ||
 	    cpu_vendor_id == CPU_VENDOR_AMD ||
 	    cpu_vendor_id == CPU_VENDOR_CENTAUR) {
-		printf("  Stepping = %u", cpu_id & 0xf);
+		printf("  Family = %x", CPUID_TO_FAMILY(cpu_id));
+		printf("  Model = %x", CPUID_TO_MODEL(cpu_id));
+		printf("  Stepping = %u", cpu_id & CPUID_STEPPING);
 		if (cpu_high > 0) {
 
 			/*

Modified: projects/altix/sys/amd64/amd64/mca.c
==============================================================================
--- projects/altix/sys/amd64/amd64/mca.c	Wed Mar 17 00:37:15 2010	(r205234)
+++ projects/altix/sys/amd64/amd64/mca.c	Wed Mar 17 00:53:58 2010	(r205235)
@@ -186,19 +186,46 @@ mca_error_request(uint16_t mca_error)
 	return ("???");
 }
 
+static const char *
+mca_error_mmtype(uint16_t mca_error)
+{
+
+	switch ((mca_error & 0x70) >> 4) {
+	case 0x0:
+		return ("GEN");
+	case 0x1:
+		return ("RD");
+	case 0x2:
+		return ("WR");
+	case 0x3:
+		return ("AC");
+	case 0x4:
+		return ("MS");
+	}
+	return ("???");
+}
+
 /* Dump details about a single machine check. */
 static void __nonnull(1)
 mca_log(const struct mca_record *rec)
 {
 	uint16_t mca_error;
 
-	printf("MCA: bank %d, status 0x%016llx\n", rec->mr_bank,
+	printf("MCA: Bank %d, Status 0x%016llx\n", rec->mr_bank,
 	    (long long)rec->mr_status);
-	printf("MCA: CPU %d ", rec->mr_apic_id);
+	printf("MCA: Global Cap 0x%016llx, Status 0x%016llx\n",
+	    (long long)rec->mr_mcg_cap, (long long)rec->mr_mcg_status);
+	printf("MCA: Vendor \"%s\", ID 0x%x, APIC ID %d\n", cpu_vendor,
+	    rec->mr_cpu_id, rec->mr_apic_id);
+	printf("MCA: CPU %d ", rec->mr_cpu);
 	if (rec->mr_status & MC_STATUS_UC)
 		printf("UNCOR ");
-	else
+	else {
 		printf("COR ");
+		if (rec->mr_mcg_cap & MCG_CAP_TES_P)
+			printf("(%lld) ", ((long long)rec->mr_status &
+			    MC_STATUS_COR_COUNT) >> 38);
+	}
 	if (rec->mr_status & MC_STATUS_PCC)
 		printf("PCC ");
 	if (rec->mr_status & MC_STATUS_OVER)
@@ -221,6 +248,9 @@ mca_log(const struct mca_record *rec)
 	case 0x0004:
 		printf("FRC error");
 		break;
+	case 0x0005:
+		printf("internal parity error");
+		break;
 	case 0x0400:
 		printf("internal timer error");
 		break;
@@ -245,6 +275,17 @@ mca_log(const struct mca_record *rec)
 			break;
 		}
 
+		/* Memory controller error. */
+		if ((mca_error & 0xef80) == 0x0080) {
+			printf("%s channel ", mca_error_mmtype(mca_error));
+			if ((mca_error & 0x000f) != 0x000f)
+				printf("%d", mca_error & 0x000f);
+			else
+				printf("??");
+			printf(" memory error");
+			break;
+		}
+		
 		/* Cache error. */
 		if ((mca_error & 0xef00) == 0x0100) {
 			printf("%sCACHE %s %s error",
@@ -322,6 +363,11 @@ mca_check_status(int bank, struct mca_re
 		rec->mr_misc = rdmsr(MSR_MC_MISC(bank));
 	rec->mr_tsc = rdtsc();
 	rec->mr_apic_id = PCPU_GET(apic_id);
+	rec->mr_mcg_cap = rdmsr(MSR_MCG_CAP);
+	rec->mr_mcg_status = rdmsr(MSR_MCG_STATUS);
+	rec->mr_cpu_id = cpu_id;
+	rec->mr_cpu_vendor_id = cpu_vendor_id;
+	rec->mr_cpu = PCPU_GET(cpuid);
 
 	/*
 	 * Clear machine check.  Don't do this for uncorrectable

Modified: projects/altix/sys/amd64/amd64/pmap.c
==============================================================================
--- projects/altix/sys/amd64/amd64/pmap.c	Wed Mar 17 00:37:15 2010	(r205234)
+++ projects/altix/sys/amd64/amd64/pmap.c	Wed Mar 17 00:53:58 2010	(r205235)
@@ -152,7 +152,7 @@ __FBSDID("$FreeBSD$");
 
 #if !defined(DIAGNOSTIC)
 #ifdef __GNUC_GNU_INLINE__
-#define PMAP_INLINE	inline
+#define PMAP_INLINE	__attribute__((__gnu_inline__)) inline
 #else
 #define PMAP_INLINE	extern inline
 #endif
@@ -1105,7 +1105,8 @@ pmap_invalidate_cache_range(vm_offset_t 
 
 	if (cpu_feature & CPUID_SS)
 		; /* If "Self Snoop" is supported, do nothing. */
-	else if (cpu_feature & CPUID_CLFSH) {
+	else if ((cpu_feature & CPUID_CLFSH) != 0 &&
+		 eva - sva < 2 * 1024 * 1024) {
 
 		/*
 		 * Otherwise, do per-cache line flush.  Use the mfence
@@ -1122,7 +1123,8 @@ pmap_invalidate_cache_range(vm_offset_t 
 
 		/*
 		 * No targeted cache flush methods are supported by CPU,
-		 * globally invalidate cache as a last resort.
+		 * or the supplied range is bigger then 2MB.
+		 * Globally invalidate cache.
 		 */
 		pmap_invalidate_cache();
 	}

Modified: projects/altix/sys/amd64/amd64/vm_machdep.c
==============================================================================
--- projects/altix/sys/amd64/amd64/vm_machdep.c	Wed Mar 17 00:37:15 2010	(r205234)
+++ projects/altix/sys/amd64/amd64/vm_machdep.c	Wed Mar 17 00:53:58 2010	(r205235)
@@ -439,7 +439,7 @@ cpu_set_upcall_kse(struct thread *td, vo
 	 */
 	cpu_thread_clean(td);
 
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
 	if (td->td_proc->p_sysent->sv_flags & SV_ILP32) {
 		/*
 	 	 * Set the trap frame to point at the beginning of the uts
@@ -490,7 +490,7 @@ cpu_set_user_tls(struct thread *td, void
 	if ((u_int64_t)tls_base >= VM_MAXUSER_ADDRESS)
 		return (EINVAL);
 
-#ifdef COMPAT_IA32
+#ifdef COMPAT_FREEBSD32
 	if (td->td_proc->p_sysent->sv_flags & SV_ILP32) {
 		td->td_pcb->pcb_gsbase = (register_t)tls_base;
 		return (0);

Modified: projects/altix/sys/amd64/conf/GENERIC
==============================================================================
--- projects/altix/sys/amd64/conf/GENERIC	Wed Mar 17 00:37:15 2010	(r205234)
+++ projects/altix/sys/amd64/conf/GENERIC	Wed Mar 17 00:53:58 2010	(r205235)
@@ -44,8 +44,7 @@ options 	PROCFS			# Process filesystem (
 options 	PSEUDOFS		# Pseudo-filesystem framework
 options 	GEOM_PART_GPT		# GUID Partition Tables.
 options 	GEOM_LABEL		# Provides labelization
-options 	COMPAT_43TTY		# BSD 4.3 TTY compat (sgtty)
-options 	COMPAT_IA32		# Compatible with i386 binaries
+options 	COMPAT_FREEBSD32	# Compatible with i386 binaries
 options 	COMPAT_FREEBSD4		# Compatible with FreeBSD4
 options 	COMPAT_FREEBSD5		# Compatible with FreeBSD5
 options 	COMPAT_FREEBSD6		# Compatible with FreeBSD6

Modified: projects/altix/sys/amd64/conf/NOTES
==============================================================================
--- projects/altix/sys/amd64/conf/NOTES	Wed Mar 17 00:37:15 2010	(r205234)
+++ projects/altix/sys/amd64/conf/NOTES	Wed Mar 17 00:53:58 2010	(r205235)
@@ -483,7 +483,7 @@ options 	PMAP_SHPGPERPROC=201
 #XXX these 32 bit binaries is added.
 
 # Enable 32-bit runtime support for FreeBSD/i386 binaries.
-options 	COMPAT_IA32
+options 	COMPAT_FREEBSD32
 
 # Enable iBCS2 runtime support for SCO and ISC binaries
 #XXX#options 	IBCS2
@@ -494,7 +494,7 @@ options 	COMPAT_IA32
 # Enable Linux ABI emulation
 #XXX#options 	COMPAT_LINUX
 
-# Enable 32-bit Linux ABI emulation (requires COMPAT_43 and COMPAT_IA32)
+# Enable 32-bit Linux ABI emulation (requires COMPAT_43 and COMPAT_FREEBSD32)
 options 	COMPAT_LINUX32
 
 # Enable the linux-like proc filesystem support (requires COMPAT_LINUX32

Modified: projects/altix/sys/amd64/conf/XENHVM
==============================================================================
--- projects/altix/sys/amd64/conf/XENHVM	Wed Mar 17 00:37:15 2010	(r205234)
+++ projects/altix/sys/amd64/conf/XENHVM	Wed Mar 17 00:53:58 2010	(r205235)
@@ -45,8 +45,7 @@ options 	PROCFS			# Process filesystem (
 options 	PSEUDOFS		# Pseudo-filesystem framework
 options 	GEOM_PART_GPT		# GUID Partition Tables.
 options 	GEOM_LABEL		# Provides labelization
-options 	COMPAT_43TTY		# BSD 4.3 TTY compat (sgtty)
-options 	COMPAT_IA32		# Compatible with i386 binaries
+options 	COMPAT_FREEBSD32	# Compatible with i386 binaries
 options 	COMPAT_FREEBSD4		# Compatible with FreeBSD4
 options 	COMPAT_FREEBSD5		# Compatible with FreeBSD5
 options 	COMPAT_FREEBSD6		# Compatible with FreeBSD6

Modified: projects/altix/sys/amd64/include/elf.h
==============================================================================
--- projects/altix/sys/amd64/include/elf.h	Wed Mar 17 00:37:15 2010	(r205234)
+++ projects/altix/sys/amd64/include/elf.h	Wed Mar 17 00:53:58 2010	(r205235)
@@ -42,6 +42,7 @@
 #include <sys/elf_generic.h>
 
 #define	ELF_ARCH	EM_X86_64
+#define	ELF_ARCH32	EM_386
 
 #define	ELF_MACHINE_OK(x) ((x) == EM_X86_64)
 

Modified: projects/altix/sys/amd64/include/mca.h
==============================================================================
--- projects/altix/sys/amd64/include/mca.h	Wed Mar 17 00:37:15 2010	(r205234)
+++ projects/altix/sys/amd64/include/mca.h	Wed Mar 17 00:53:58 2010	(r205235)
@@ -37,6 +37,11 @@ struct mca_record {
 	uint64_t	mr_tsc;
 	int		mr_apic_id;
 	int		mr_bank;
+	uint64_t	mr_mcg_cap;
+	uint64_t	mr_mcg_status;
+	int		mr_cpu_id;
+	int		mr_cpu_vendor_id;
+	int		mr_cpu;
 };
 
 #ifdef _KERNEL

Modified: projects/altix/sys/amd64/include/reg.h
==============================================================================
--- projects/altix/sys/amd64/include/reg.h	Wed Mar 17 00:37:15 2010	(r205234)
+++ projects/altix/sys/amd64/include/reg.h	Wed Mar 17 00:53:58 2010	(r205235)
@@ -37,6 +37,10 @@
 #ifndef _MACHINE_REG_H_
 #define	_MACHINE_REG_H_
 
+#if defined(_KERNEL) && !defined(_STANDALONE)
+#include "opt_compat.h"
+#endif
+
 /*
  * Register set accessible via /proc/$pid/regs and PT_{SET,GET}REGS.
  */
@@ -116,6 +120,11 @@ struct dbreg {
 #define	DBREG_DRX(d,x)	((d)->dr[(x)])	/* reference dr0 - dr15 by
 					   register number */
 
+#ifdef COMPAT_FREEBSD32
+#include <machine/fpu.h>
+#include <compat/ia32/ia32_reg.h>
+#endif
+
 #ifdef _KERNEL
 /*
  * XXX these interfaces are MI, so they should be declared in a MI place.

Modified: projects/altix/sys/amd64/include/specialreg.h
==============================================================================
--- projects/altix/sys/amd64/include/specialreg.h	Wed Mar 17 00:37:15 2010	(r205234)
+++ projects/altix/sys/amd64/include/specialreg.h	Wed Mar 17 00:53:58 2010	(r205235)
@@ -267,6 +267,7 @@
 #define	MSR_MTRR16kBase		0x258
 #define	MSR_MTRR4kBase		0x268
 #define	MSR_PAT			0x277
+#define	MSR_MC0_CTL2		0x280
 #define	MSR_MTRRdefType		0x2ff
 #define	MSR_MC0_CTL		0x400
 #define	MSR_MC0_STATUS		0x401
@@ -352,8 +353,10 @@
 #define	MCG_CAP_COUNT		0x000000ff
 #define	MCG_CAP_CTL_P		0x00000100
 #define	MCG_CAP_EXT_P		0x00000200
+#define	MCG_CAP_CMCI_P		0x00000400
 #define	MCG_CAP_TES_P		0x00000800
 #define	MCG_CAP_EXT_CNT		0x00ff0000
+#define	MCG_CAP_SER_P		0x01000000
 #define	MCG_STATUS_RIPV		0x00000001
 #define	MCG_STATUS_EIPV		0x00000002
 #define	MCG_STATUS_MCIP		0x00000004
@@ -363,9 +366,14 @@
 #define	MSR_MC_STATUS(x)	(MSR_MC0_STATUS + (x) * 4)
 #define	MSR_MC_ADDR(x)		(MSR_MC0_ADDR + (x) * 4)
 #define	MSR_MC_MISC(x)		(MSR_MC0_MISC + (x) * 4)
+#define	MSR_MC_CTL2(x)		(MSR_MC0_CTL2 + (x))	/* If MCG_CAP_CMCI_P */
 #define	MC_STATUS_MCA_ERROR	0x000000000000ffffUL
 #define	MC_STATUS_MODEL_ERROR	0x00000000ffff0000UL
 #define	MC_STATUS_OTHER_INFO	0x01ffffff00000000UL
+#define	MC_STATUS_COR_COUNT	0x001fffc000000000UL	/* If MCG_CAP_TES_P */
+#define	MC_STATUS_TES_STATUS	0x0060000000000000UL	/* If MCG_CAP_TES_P */
+#define	MC_STATUS_AR		0x0080000000000000UL	/* If MCG_CAP_CMCI_P */
+#define	MC_STATUS_S		0x0100000000000000UL	/* If MCG_CAP_CMCI_P */
 #define	MC_STATUS_PCC		0x0200000000000000UL
 #define	MC_STATUS_ADDRV		0x0400000000000000UL
 #define	MC_STATUS_MISCV		0x0800000000000000UL
@@ -373,6 +381,10 @@
 #define	MC_STATUS_UC		0x2000000000000000UL
 #define	MC_STATUS_OVER		0x4000000000000000UL
 #define	MC_STATUS_VAL		0x8000000000000000UL
+#define	MC_MISC_RA_LSB		0x000000000000003fUL	/* If MCG_CAP_SER_P */
+#define	MC_MISC_ADDRESS_MODE	0x00000000000001c0UL	/* If MCG_CAP_SER_P */
+#define	MC_CTL2_THRESHOLD	0x0000000000003fffUL
+#define	MC_CTL2_CMCI_EN		0x0000000040000000UL
 
 /*
  * The following four 3-byte registers control the non-cacheable regions.

Modified: projects/altix/sys/amd64/linux32/linux32_sysvec.c
==============================================================================
--- projects/altix/sys/amd64/linux32/linux32_sysvec.c	Wed Mar 17 00:37:15 2010	(r205234)
+++ projects/altix/sys/amd64/linux32/linux32_sysvec.c	Wed Mar 17 00:53:58 2010	(r205235)
@@ -34,8 +34,8 @@
 __FBSDID("$FreeBSD$");
 #include "opt_compat.h"
 
-#ifndef COMPAT_IA32
-#error "Unable to compile Linux-emulator due to missing COMPAT_IA32 option!"
+#ifndef COMPAT_FREEBSD32
+#error "Unable to compile Linux-emulator due to missing COMPAT_FREEBSD32 option!"
 #endif
 
 #define	__ELF_WORD_SIZE	32

Modified: projects/altix/sys/arm/arm/busdma_machdep.c
==============================================================================
--- projects/altix/sys/arm/arm/busdma_machdep.c	Wed Mar 17 00:37:15 2010	(r205234)
+++ projects/altix/sys/arm/arm/busdma_machdep.c	Wed Mar 17 00:53:58 2010	(r205235)
@@ -649,7 +649,8 @@ bus_dmamem_free(bus_dma_tag_t dmat, void
 		KASSERT(map->allocbuffer == vaddr,
 		    ("Trying to freeing the wrong DMA buffer"));
 		vaddr = map->origbuffer;
-		arm_unmap_nocache(map->allocbuffer, dmat->maxsize);
+		arm_unmap_nocache(map->allocbuffer,
+		    dmat->maxsize + ((vm_offset_t)vaddr & PAGE_MASK));
 	}
         if (dmat->maxsize <= PAGE_SIZE &&
 	   dmat->alignment < dmat->maxsize &&

Modified: projects/altix/sys/arm/arm/identcpu.c
==============================================================================
--- projects/altix/sys/arm/arm/identcpu.c	Wed Mar 17 00:37:15 2010	(r205234)
+++ projects/altix/sys/arm/arm/identcpu.c	Wed Mar 17 00:53:58 2010	(r205235)
@@ -329,6 +329,7 @@ const struct cpu_classtab cpu_classes[] 
 	{ "SA-1",	"CPU_SA110" },		/* CPU_CLASS_SA1 */
 	{ "XScale",	"CPU_XSCALE_..." },	/* CPU_CLASS_XSCALE */
 	{ "ARM11J",	"CPU_ARM11" },		/* CPU_CLASS_ARM11J */
+	{ "Marvell",	"CPU_MARVELL" },	/* CPU_CLASS_MARVELL */
 };
 
 /*
@@ -404,6 +405,7 @@ identify_arm_cpu(void)
 	case CPU_CLASS_SA1:
 	case CPU_CLASS_XSCALE:
 	case CPU_CLASS_ARM11J:
+	case CPU_CLASS_MARVELL:
 		if ((ctrl & CPU_CONTROL_DC_ENABLE) == 0)
 			printf(" DC disabled");
 		else

Modified: projects/altix/sys/arm/arm/vm_machdep.c
==============================================================================
--- projects/altix/sys/arm/arm/vm_machdep.c	Wed Mar 17 00:37:15 2010	(r205234)
+++ projects/altix/sys/arm/arm/vm_machdep.c	Wed Mar 17 00:53:58 2010	(r205235)
@@ -171,6 +171,9 @@ sf_buf_free(struct sf_buf *sf)
 	 if (sf->ref_count == 0) {
 		 TAILQ_INSERT_TAIL(&sf_buf_freelist, sf, free_entry);
 		 nsfbufsused--;
+		 pmap_kremove(sf->kva);
+		 sf->m = NULL;
+		 LIST_REMOVE(sf, list_entry);
 		 if (sf_buf_alloc_want > 0)
 			 wakeup_one(&sf_buf_freelist);
 	 }
@@ -502,9 +505,12 @@ arm_unmap_nocache(void *addr, vm_size_t 
 
 	size = round_page(size);
 	i = (raddr - arm_nocache_startaddr) / (PAGE_SIZE);
-	for (; size > 0; size -= PAGE_SIZE, i++)
+	for (; size > 0; size -= PAGE_SIZE, i++) {
 		arm_nocache_allocated[i / BITS_PER_INT] &= ~(1 << (i % 
 		    BITS_PER_INT));
+		pmap_kremove(raddr);
+		raddr += PAGE_SIZE;
+	}
 }
 
 #ifdef ARM_USE_SMALL_ALLOC

Modified: projects/altix/sys/arm/conf/BWCT.hints
==============================================================================
--- projects/altix/sys/arm/conf/BWCT.hints	Wed Mar 17 00:37:15 2010	(r205234)
+++ projects/altix/sys/arm/conf/BWCT.hints	Wed Mar 17 00:53:58 2010	(r205235)
@@ -4,6 +4,6 @@
 hint.ds1672_rtc.0.at="iicbus0"
 hint.ds1672_rtc.0.addr=0xd0
 
-# NAtional Semiconductor LM75 temperature sensor sitting on the I2C bus
+# National Semiconductor LM75 temperature sensor sitting on the I2C bus
 hint.lm75.0.at="iicbus0"
 hint.lm75.0.addr=0x9e

Modified: projects/altix/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
==============================================================================
--- projects/altix/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c	Wed Mar 17 00:37:15 2010	(r205234)
+++ projects/altix/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c	Wed Mar 17 00:53:58 2010	(r205235)
@@ -131,6 +131,7 @@
 #include <sys/kstat.h>
 #include <sys/sdt.h>
 
+#include <sys/ktr.h>
 #include <vm/vm_pageout.h>
 
 static kmutex_t		arc_reclaim_thr_lock;
@@ -186,6 +187,11 @@ SYSCTL_QUAD(_vfs_zfs, OID_AUTO, arc_min,
 SYSCTL_INT(_vfs_zfs, OID_AUTO, mdcomp_disable, CTLFLAG_RDTUN,
     &zfs_mdcomp_disable, 0, "Disable metadata compression");
 
+#ifdef ZIO_USE_UMA
+extern kmem_cache_t	*zio_buf_cache[];
+extern kmem_cache_t	*zio_data_buf_cache[];
+#endif
+
 /*
  * Note that buffers can be in one of 6 states:
  *	ARC_anon	- anonymous (discussed below)
@@ -218,13 +224,31 @@ SYSCTL_INT(_vfs_zfs, OID_AUTO, mdcomp_di
  * second level ARC benefit from these fast lookups.
  */
 
+#define	ARCS_LOCK_PAD		128
+struct arcs_lock {
+	kmutex_t	arcs_lock;
+#ifdef _KERNEL
+	unsigned char	pad[(ARCS_LOCK_PAD - sizeof (kmutex_t))];
+#endif
+};
+
+/*
+ * must be power of two for mask use to work
+ *
+ */
+#define ARC_BUFC_NUMDATALISTS		16
+#define ARC_BUFC_NUMMETADATALISTS	16
+#define ARC_BUFC_NUMLISTS	(ARC_BUFC_NUMMETADATALISTS+ARC_BUFC_NUMDATALISTS)
+
 typedef struct arc_state {
-	list_t	arcs_list[ARC_BUFC_NUMTYPES];	/* list of evictable buffers */
 	uint64_t arcs_lsize[ARC_BUFC_NUMTYPES];	/* amount of evictable data */
 	uint64_t arcs_size;	/* total amount of data in this state */
-	kmutex_t arcs_mtx;
+	list_t	arcs_lists[ARC_BUFC_NUMLISTS]; /* list of evictable buffers */
+	struct arcs_lock arcs_locks[ARC_BUFC_NUMLISTS] __aligned(128);
 } arc_state_t;
 
+#define ARCS_LOCK(s, i) &((s)->arcs_locks[(i)].arcs_lock)
+
 /* The 6 states: */
 static arc_state_t ARC_anon;
 static arc_state_t ARC_mru;
@@ -248,7 +272,9 @@ typedef struct arc_stats {
 	kstat_named_t arcstat_mru_ghost_hits;
 	kstat_named_t arcstat_mfu_hits;
 	kstat_named_t arcstat_mfu_ghost_hits;
+	kstat_named_t arcstat_allocated;
 	kstat_named_t arcstat_deleted;
+	kstat_named_t arcstat_stolen;
 	kstat_named_t arcstat_recycle_miss;
 	kstat_named_t arcstat_mutex_miss;
 	kstat_named_t arcstat_evict_skip;
@@ -280,6 +306,19 @@ typedef struct arc_stats {
 	kstat_named_t arcstat_l2_size;
 	kstat_named_t arcstat_l2_hdr_size;
 	kstat_named_t arcstat_memory_throttle_count;
+	kstat_named_t arcstat_l2_write_trylock_fail;
+	kstat_named_t arcstat_l2_write_in_l2;
+	kstat_named_t arcstat_l2_write_passed_headroom;
+	kstat_named_t arcstat_l2_write_spa_mismatch;
+	kstat_named_t arcstat_l2_write_hdr_io_in_progress;
+	kstat_named_t arcstat_l2_write_not_cacheable;
+	kstat_named_t arcstat_l2_write_full;
+	kstat_named_t arcstat_l2_write_buffer_iter;
+	kstat_named_t arcstat_l2_write_pios;
+	kstat_named_t arcstat_l2_write_bytes_written;
+	kstat_named_t arcstat_l2_write_buffer_bytes_scanned;
+	kstat_named_t arcstat_l2_write_buffer_list_iter;
+	kstat_named_t arcstat_l2_write_buffer_list_null_iter;
 } arc_stats_t;
 
 static arc_stats_t arc_stats = {
@@ -297,7 +336,9 @@ static arc_stats_t arc_stats = {
 	{ "mru_ghost_hits",		KSTAT_DATA_UINT64 },
 	{ "mfu_hits",			KSTAT_DATA_UINT64 },
 	{ "mfu_ghost_hits",		KSTAT_DATA_UINT64 },
+	{ "allocated",			KSTAT_DATA_UINT64 },
 	{ "deleted",			KSTAT_DATA_UINT64 },
+	{ "stolen",			KSTAT_DATA_UINT64 },
 	{ "recycle_miss",		KSTAT_DATA_UINT64 },
 	{ "mutex_miss",			KSTAT_DATA_UINT64 },
 	{ "evict_skip",			KSTAT_DATA_UINT64 },
@@ -328,7 +369,20 @@ static arc_stats_t arc_stats = {
 	{ "l2_io_error",		KSTAT_DATA_UINT64 },
 	{ "l2_size",			KSTAT_DATA_UINT64 },
 	{ "l2_hdr_size",		KSTAT_DATA_UINT64 },
-	{ "memory_throttle_count",	KSTAT_DATA_UINT64 }
+	{ "memory_throttle_count",	KSTAT_DATA_UINT64 },
+	{ "l2_write_trylock_fail", 	KSTAT_DATA_UINT64 },
+	{ "l2_write_in_l2", 		KSTAT_DATA_UINT64 },
+	{ "l2_write_passed_headroom", 	KSTAT_DATA_UINT64 },
+	{ "l2_write_spa_mismatch", 	KSTAT_DATA_UINT64 },
+	{ "l2_write_io_in_progress", 	KSTAT_DATA_UINT64 },
+	{ "l2_write_not_cacheable", 	KSTAT_DATA_UINT64 },
+	{ "l2_write_full", 		KSTAT_DATA_UINT64 },
+	{ "l2_write_buffer_iter", 	KSTAT_DATA_UINT64 },
+	{ "l2_write_pios", 		KSTAT_DATA_UINT64 },
+	{ "l2_write_bytes_written", 		KSTAT_DATA_UINT64 },
+	{ "l2_write_buffer_bytes_scanned", 	KSTAT_DATA_UINT64 },
+	{ "l2_write_buffer_list_iter", 	KSTAT_DATA_UINT64 },
+	{ "l2_write_buffer_list_null_iter", 	KSTAT_DATA_UINT64 }
 };
 
 #define	ARCSTAT(stat)	(arc_stats.stat.value.ui64)
@@ -541,13 +595,19 @@ static buf_hash_table_t buf_hash_table;
 
 uint64_t zfs_crc64_table[256];
 
+#ifdef ZIO_USE_UMA
+extern kmem_cache_t	*zio_buf_cache[];
+extern kmem_cache_t	*zio_data_buf_cache[];
+#endif
+
 /*
  * Level 2 ARC
  */
 
-#define	L2ARC_WRITE_SIZE	(8 * 1024 * 1024)	/* initial write max */
-#define	L2ARC_HEADROOM		4		/* num of writes */
+#define	L2ARC_WRITE_SIZE	(64 * 1024 * 1024)	/* initial write max */
+#define	L2ARC_HEADROOM		128		/* num of writes */
 #define	L2ARC_FEED_SECS		1		/* caching interval */
+#define	L2ARC_FEED_SECS_SHIFT	1		/* caching interval shift */
 
 #define	l2arc_writes_sent	ARCSTAT(arcstat_l2_writes_sent)
 #define	l2arc_writes_done	ARCSTAT(arcstat_l2_writes_done)
@@ -559,7 +619,66 @@ uint64_t l2arc_write_max = L2ARC_WRITE_S
 uint64_t l2arc_write_boost = L2ARC_WRITE_SIZE;	/* extra write during warmup */
 uint64_t l2arc_headroom = L2ARC_HEADROOM;	/* number of dev writes */
 uint64_t l2arc_feed_secs = L2ARC_FEED_SECS;	/* interval seconds */
-boolean_t l2arc_noprefetch = B_TRUE;		/* don't cache prefetch bufs */
+uint64_t l2arc_feed_secs_shift = L2ARC_FEED_SECS_SHIFT;	/* interval seconds shift */
+boolean_t l2arc_noprefetch = B_FALSE;		/* don't cache prefetch bufs */
+
+
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, l2arc_write_max, CTLFLAG_RW,
+    &l2arc_write_max, 0, "max write size");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, l2arc_write_boost, CTLFLAG_RW,
+    &l2arc_write_boost, 0, "extra write during warmup");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, l2arc_headroom, CTLFLAG_RW,
+    &l2arc_headroom, 0, "number of dev writes");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, l2arc_feed_secs, CTLFLAG_RW,
+    &l2arc_feed_secs, 0, "interval seconds");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, l2arc_feed_secs_shift, CTLFLAG_RW,
+    &l2arc_feed_secs_shift, 0, "power of 2 division of feed seconds");
+
+SYSCTL_INT(_vfs_zfs, OID_AUTO, l2arc_noprefetch, CTLFLAG_RW,
+    &l2arc_noprefetch, 0, "don't cache prefetch bufs");
+
+
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, anon_size, CTLFLAG_RD,
+    &ARC_anon.arcs_size, 0, "size of anonymous state");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, anon_metadata_lsize, CTLFLAG_RD,
+    &ARC_anon.arcs_lsize[ARC_BUFC_METADATA], 0, "size of anonymous state");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, anon_data_lsize, CTLFLAG_RD,
+    &ARC_anon.arcs_lsize[ARC_BUFC_DATA], 0, "size of anonymous state");
+
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mru_size, CTLFLAG_RD,
+    &ARC_mru.arcs_size, 0, "size of mru state");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mru_metadata_lsize, CTLFLAG_RD,
+    &ARC_mru.arcs_lsize[ARC_BUFC_METADATA], 0, "size of metadata in mru state");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mru_data_lsize, CTLFLAG_RD,
+    &ARC_mru.arcs_lsize[ARC_BUFC_DATA], 0, "size of data in mru state");
+
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mru_ghost_size, CTLFLAG_RD,
+    &ARC_mru_ghost.arcs_size, 0, "size of mru ghost state");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mru_ghost_metadata_lsize, CTLFLAG_RD,
+    &ARC_mru_ghost.arcs_lsize[ARC_BUFC_METADATA], 0,
+    "size of metadata in mru ghost state");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mru_ghost_data_lsize, CTLFLAG_RD,
+    &ARC_mru_ghost.arcs_lsize[ARC_BUFC_DATA], 0,
+    "size of data in mru ghost state");
+
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mfu_size, CTLFLAG_RD,
+    &ARC_mfu.arcs_size, 0, "size of mfu state");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mfu_metadata_lsize, CTLFLAG_RD,
+    &ARC_mfu.arcs_lsize[ARC_BUFC_METADATA], 0, "size of metadata in mfu state");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mfu_data_lsize, CTLFLAG_RD,
+    &ARC_mfu.arcs_lsize[ARC_BUFC_DATA], 0, "size of data in mfu state");
+
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mfu_ghost_size, CTLFLAG_RD,
+    &ARC_mfu_ghost.arcs_size, 0, "size of mfu ghost state");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mfu_ghost_metadata_lsize, CTLFLAG_RD,
+    &ARC_mfu_ghost.arcs_lsize[ARC_BUFC_METADATA], 0,
+    "size of metadata in mfu ghost state");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, mfu_ghost_data_lsize, CTLFLAG_RD,
+    &ARC_mfu_ghost.arcs_lsize[ARC_BUFC_DATA], 0,
+    "size of data in mfu ghost state");
+
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, l2c_only_size, CTLFLAG_RD,
+    &ARC_l2c_only.arcs_size, 0, "size of mru state");
 
 /*
  * L2ARC Internals
@@ -953,20 +1072,42 @@ arc_buf_freeze(arc_buf_t *buf)
 }
 
 static void
+get_buf_info(arc_buf_hdr_t *ab, arc_state_t *state, list_t **list, kmutex_t **lock)
+{
+	uint64_t buf_hashid = buf_hash(ab->b_spa, &ab->b_dva, ab->b_birth);
+
+	if (ab->b_type == ARC_BUFC_METADATA) 
+		buf_hashid &= (ARC_BUFC_NUMMETADATALISTS-1);
+	else {
+		buf_hashid &= (ARC_BUFC_NUMDATALISTS-1);
+		buf_hashid += ARC_BUFC_NUMMETADATALISTS;
+	}
+
+	*list = &state->arcs_lists[buf_hashid];
+	*lock = ARCS_LOCK(state, buf_hashid);
+}
+
+
+static void
 add_reference(arc_buf_hdr_t *ab, kmutex_t *hash_lock, void *tag)
 {
+
 	ASSERT(MUTEX_HELD(hash_lock));
 
 	if ((refcount_add(&ab->b_refcnt, tag) == 1) &&
 	    (ab->b_state != arc_anon)) {
+		list_t *list;
+		kmutex_t *lock;
 		uint64_t delta = ab->b_size * ab->b_datacnt;
-		list_t *list = &ab->b_state->arcs_list[ab->b_type];
 		uint64_t *size = &ab->b_state->arcs_lsize[ab->b_type];
 
-		ASSERT(!MUTEX_HELD(&ab->b_state->arcs_mtx));
-		mutex_enter(&ab->b_state->arcs_mtx);
+		get_buf_info(ab, ab->b_state, &list, &lock);
+		ASSERT(!MUTEX_HELD(lock));
+		mutex_enter(lock);
 		ASSERT(list_link_active(&ab->b_arc_node));
 		list_remove(list, ab);
+		mutex_exit(lock);
+
 		if (GHOST_STATE(ab->b_state)) {
 			ASSERT3U(ab->b_datacnt, ==, 0);
 			ASSERT3P(ab->b_buf, ==, NULL);
@@ -975,7 +1116,6 @@ add_reference(arc_buf_hdr_t *ab, kmutex_
 		ASSERT(delta > 0);
 		ASSERT3U(*size, >=, delta);
 		atomic_add_64(size, -delta);
-		mutex_exit(&ab->b_state->arcs_mtx);
 		/* remove the prefetch flag if we get a reference */
 		if (ab->b_flags & ARC_PREFETCH)
 			ab->b_flags &= ~ARC_PREFETCH;
@@ -994,14 +1134,19 @@ remove_reference(arc_buf_hdr_t *ab, kmut
 	if (((cnt = refcount_remove(&ab->b_refcnt, tag)) == 0) &&
 	    (state != arc_anon)) {
 		uint64_t *size = &state->arcs_lsize[ab->b_type];
+		list_t *list;
+		kmutex_t *lock;
 
-		ASSERT(!MUTEX_HELD(&state->arcs_mtx));
-		mutex_enter(&state->arcs_mtx);
+		get_buf_info(ab, state, &list, &lock);
+
+		ASSERT(!MUTEX_HELD(lock));
+		mutex_enter(lock);
 		ASSERT(!list_link_active(&ab->b_arc_node));
-		list_insert_head(&state->arcs_list[ab->b_type], ab);
+		list_insert_head(list, ab);
+		mutex_exit(lock);
+
 		ASSERT(ab->b_datacnt > 0);
 		atomic_add_64(size, ab->b_size * ab->b_datacnt);
-		mutex_exit(&state->arcs_mtx);
 	}
 	return (cnt);
 }
@@ -1016,6 +1161,8 @@ arc_change_state(arc_state_t *new_state,
 	arc_state_t *old_state = ab->b_state;
 	int64_t refcnt = refcount_count(&ab->b_refcnt);
 	uint64_t from_delta, to_delta;
+	list_t *list;
+	kmutex_t *lock;
 
 	ASSERT(MUTEX_HELD(hash_lock));
 	ASSERT(new_state != old_state);
@@ -1030,14 +1177,17 @@ arc_change_state(arc_state_t *new_state,
 	 */
 	if (refcnt == 0) {
 		if (old_state != arc_anon) {
-			int use_mutex = !MUTEX_HELD(&old_state->arcs_mtx);
+			int use_mutex;
 			uint64_t *size = &old_state->arcs_lsize[ab->b_type];
 
+			get_buf_info(ab, old_state, &list, &lock);
+			use_mutex = !MUTEX_HELD(lock);
+
 			if (use_mutex)
-				mutex_enter(&old_state->arcs_mtx);
+				mutex_enter(lock);
 
 			ASSERT(list_link_active(&ab->b_arc_node));
-			list_remove(&old_state->arcs_list[ab->b_type], ab);
+			list_remove(list, ab);
 
 			/*
 			 * If prefetching out of the ghost cache,
@@ -1052,16 +1202,20 @@ arc_change_state(arc_state_t *new_state,
 			atomic_add_64(size, -from_delta);
 
 			if (use_mutex)
-				mutex_exit(&old_state->arcs_mtx);
+				mutex_exit(lock);
 		}
 		if (new_state != arc_anon) {
-			int use_mutex = !MUTEX_HELD(&new_state->arcs_mtx);
+			int use_mutex; 
 			uint64_t *size = &new_state->arcs_lsize[ab->b_type];
 
+			get_buf_info(ab, new_state, &list, &lock);
+			use_mutex = !MUTEX_HELD(lock);
+			
+			
 			if (use_mutex)
-				mutex_enter(&new_state->arcs_mtx);
+				mutex_enter(lock);
 
-			list_insert_head(&new_state->arcs_list[ab->b_type], ab);
+			list_insert_head(list, ab);
 
 			/* ghost elements have a ghost size */
 			if (GHOST_STATE(new_state)) {
@@ -1072,7 +1226,7 @@ arc_change_state(arc_state_t *new_state,
 			atomic_add_64(size, to_delta);
 
 			if (use_mutex)
-				mutex_exit(&new_state->arcs_mtx);
+				mutex_exit(lock);
 		}
 	}
 
@@ -1462,21 +1616,49 @@ arc_evict(arc_state_t *state, spa_t *spa
 {
 	arc_state_t *evicted_state;
 	uint64_t bytes_evicted = 0, skipped = 0, missed = 0;
+	int64_t bytes_remaining;
 	arc_buf_hdr_t *ab, *ab_prev = NULL;
-	list_t *list = &state->arcs_list[type];
+	list_t *evicted_list, *list, *evicted_list_start, *list_start;
+	kmutex_t *lock, *evicted_lock;
 	kmutex_t *hash_lock;
 	boolean_t have_lock;
 	void *stolen = NULL;
+	static int evict_metadata_offset, evict_data_offset;
+	int i, idx, offset, list_count, count;
 
 	ASSERT(state == arc_mru || state == arc_mfu);
 
 	evicted_state = (state == arc_mru) ? arc_mru_ghost : arc_mfu_ghost;
+	
+	if (type == ARC_BUFC_METADATA) {
+		offset = 0;
+		list_count = ARC_BUFC_NUMMETADATALISTS;
+		list_start = &state->arcs_lists[0];
+		evicted_list_start = &evicted_state->arcs_lists[0];
+		idx = evict_metadata_offset;
+	} else {
+		offset = ARC_BUFC_NUMMETADATALISTS;
+
+		list_start = &state->arcs_lists[offset];
+		evicted_list_start = &evicted_state->arcs_lists[offset];
+		list_count = ARC_BUFC_NUMDATALISTS;
+		idx = evict_data_offset;
+	}
+	bytes_remaining = evicted_state->arcs_lsize[type];
+	count = 0;
+	
+evict_start:
+	list = &list_start[idx];
+	evicted_list = &evicted_list_start[idx];
+	lock = ARCS_LOCK(state, (offset + idx));
+	evicted_lock = ARCS_LOCK(evicted_state, (offset + idx)); 
 
-	mutex_enter(&state->arcs_mtx);
-	mutex_enter(&evicted_state->arcs_mtx);
+	mutex_enter(lock);
+	mutex_enter(evicted_lock);
 
 	for (ab = list_tail(list); ab; ab = ab_prev) {
 		ab_prev = list_prev(list, ab);
+		bytes_remaining -= (ab->b_size * ab->b_datacnt);
 		/* prefetch buffers have a minimum lifespan */
 		if (HDR_IO_IN_PROGRESS(ab) ||
 		    (spa && ab->b_spa != spa) ||
@@ -1536,18 +1718,36 @@ arc_evict(arc_state_t *state, spa_t *spa
 				mutex_exit(hash_lock);
 			if (bytes >= 0 && bytes_evicted >= bytes)
 				break;
+			if (bytes_remaining > 0) {
+				mutex_exit(evicted_lock);
+				mutex_exit(lock);
+				idx  = ((idx + 1)&(list_count-1));
+				count++;
+				goto evict_start;
+			}
 		} else {
 			missed += 1;
 		}
 	}
 
-	mutex_exit(&evicted_state->arcs_mtx);
-	mutex_exit(&state->arcs_mtx);
-
-	if (bytes_evicted < bytes)
-		dprintf("only evicted %lld bytes from %x",
-		    (longlong_t)bytes_evicted, state);
+	mutex_exit(evicted_lock);
+	mutex_exit(lock);
+	
+	idx  = ((idx + 1)&(list_count-1));
+	count++;
 
+	if (bytes_evicted < bytes) {
+		if (count < list_count)
+			goto evict_start;
+		else
+			dprintf("only evicted %lld bytes from %x",
+			    (longlong_t)bytes_evicted, state);
+	}
+	if (type == ARC_BUFC_METADATA) 
+		evict_metadata_offset = idx;
+	else
+		evict_data_offset = idx;
+		
 	if (skipped)
 		ARCSTAT_INCR(arcstat_evict_skip, skipped);
 
@@ -1574,6 +1774,8 @@ arc_evict(arc_state_t *state, spa_t *spa
 			arc_evict_ghost(arc_mfu_ghost, NULL, todelete);
 		}
 	}
+	if (stolen)
+		ARCSTAT_BUMP(arcstat_stolen);
 
 	return (stolen);
 }
@@ -1586,14 +1788,28 @@ static void
 arc_evict_ghost(arc_state_t *state, spa_t *spa, int64_t bytes)
 {
 	arc_buf_hdr_t *ab, *ab_prev;
-	list_t *list = &state->arcs_list[ARC_BUFC_DATA];
-	kmutex_t *hash_lock;
+	list_t *list, *list_start;
+	kmutex_t *hash_lock, *lock;
 	uint64_t bytes_deleted = 0;
 	uint64_t bufs_skipped = 0;
+	static int evict_offset;
+	int list_count, idx = evict_offset;
+	int offset, count = 0;
 
 	ASSERT(GHOST_STATE(state));
-top:
-	mutex_enter(&state->arcs_mtx);
+
+	/*
+	 * data lists come after metadata lists
+	 */
+	list_start = &state->arcs_lists[ARC_BUFC_NUMMETADATALISTS];
+	list_count = ARC_BUFC_NUMDATALISTS;
+	offset = ARC_BUFC_NUMMETADATALISTS;
+	
+evict_start:
+	list = &list_start[idx];
+	lock = ARCS_LOCK(state, idx + offset);
+
+	mutex_enter(lock);
 	for (ab = list_tail(list); ab; ab = ab_prev) {
 		ab_prev = list_prev(list, ab);
 		if (spa && ab->b_spa != spa)
@@ -1623,20 +1839,31 @@ top:
 				break;
 		} else {
 			if (bytes < 0) {
-				mutex_exit(&state->arcs_mtx);
+				/*
+				 * we're draining the ARC, retry
+				 */
+				mutex_exit(lock);
 				mutex_enter(hash_lock);
 				mutex_exit(hash_lock);
-				goto top;
+				goto evict_start;
 			}
 			bufs_skipped += 1;
 		}
 	}
-	mutex_exit(&state->arcs_mtx);
-
-	if (list == &state->arcs_list[ARC_BUFC_DATA] &&
+	mutex_exit(lock);
+	idx  = ((idx + 1)&(ARC_BUFC_NUMDATALISTS-1));
+	count++;
+	
+	if (count < list_count)
+		goto evict_start;
+	
+	evict_offset = idx;
+	if ((uintptr_t)list > (uintptr_t)&state->arcs_lists[ARC_BUFC_NUMMETADATALISTS] &&
 	    (bytes < 0 || bytes_deleted < bytes)) {
-		list = &state->arcs_list[ARC_BUFC_METADATA];
-		goto top;
+		list_start = &state->arcs_lists[0];
+		list_count = ARC_BUFC_NUMMETADATALISTS;
+		offset = count = 0;
+		goto evict_start;
 	}
 
 	if (bufs_skipped) {
@@ -1750,22 +1977,22 @@ restart:	
 void
 arc_flush(spa_t *spa)
 {
-	while (list_head(&arc_mru->arcs_list[ARC_BUFC_DATA])) {
+	while (arc_mru->arcs_lsize[ARC_BUFC_DATA]) {
 		(void) arc_evict(arc_mru, spa, -1, FALSE, ARC_BUFC_DATA);
 		if (spa)
 			break;
 	}
-	while (list_head(&arc_mru->arcs_list[ARC_BUFC_METADATA])) {
+	while (arc_mru->arcs_lsize[ARC_BUFC_METADATA]) {
 		(void) arc_evict(arc_mru, spa, -1, FALSE, ARC_BUFC_METADATA);
 		if (spa)
 			break;
 	}
-	while (list_head(&arc_mfu->arcs_list[ARC_BUFC_DATA])) {
+	while (arc_mfu->arcs_lsize[ARC_BUFC_DATA]) {
 		(void) arc_evict(arc_mfu, spa, -1, FALSE, ARC_BUFC_DATA);
 		if (spa)
 			break;
 	}
-	while (list_head(&arc_mfu->arcs_list[ARC_BUFC_METADATA])) {
+	while (arc_mfu->arcs_lsize[ARC_BUFC_METADATA]) {
 		(void) arc_evict(arc_mfu, spa, -1, FALSE, ARC_BUFC_METADATA);
 		if (spa)
 			break;
@@ -1896,8 +2123,6 @@ arc_kmem_reap_now(arc_reclaim_strategy_t
 	size_t			i;
 	kmem_cache_t		*prev_cache = NULL;
 	kmem_cache_t		*prev_data_cache = NULL;
-	extern kmem_cache_t	*zio_buf_cache[];
-	extern kmem_cache_t	*zio_data_buf_cache[];
 #endif
 
 #ifdef _KERNEL
@@ -2203,6 +2428,7 @@ out:
 		    arc_anon->arcs_size + arc_mru->arcs_size > arc_p)
 			arc_p = MIN(arc_c, arc_p + size);
 	}
+	ARCSTAT_BUMP(arcstat_allocated);
 }
 
 /*
@@ -2388,7 +2614,10 @@ arc_read_done(zio_t *zio)
 	hdr->b_flags &= ~ARC_L2_EVICTED;
 	if (l2arc_noprefetch && (hdr->b_flags & ARC_PREFETCH))
 		hdr->b_flags &= ~ARC_L2CACHE;
-
+#if 0	
+	else if ((hdr->b_flags & ARC_PREFETCH) == 0)
+		hdr->b_flags |= ARC_L2CACHE;
+#endif	
 	/* byteswap if necessary */
 	callback_list = hdr->b_acb;
 	ASSERT(callback_list != NULL);
@@ -2502,6 +2731,7 @@ arc_read(zio_t *pio, spa_t *spa, blkptr_
     uint32_t *arc_flags, const zbookmark_t *zb)
 {
 	int err;
+	arc_buf_hdr_t *hdr = pbuf->b_hdr;
 
 	ASSERT(!refcount_is_zero(&pbuf->b_hdr->b_refcnt));
 	ASSERT3U((char *)bp - (char *)pbuf->b_data, <, pbuf->b_hdr->b_size);
@@ -2510,8 +2740,8 @@ arc_read(zio_t *pio, spa_t *spa, blkptr_
 	err = arc_read_nolock(pio, spa, bp, done, private, priority,
 	    zio_flags, arc_flags, zb);
 
+	ASSERT3P(hdr, ==, pbuf->b_hdr);
 	rw_exit(&pbuf->b_lock);
-
 	return (err);
 }
 
@@ -2822,7 +3052,9 @@ arc_buf_evict(arc_buf_t *buf)
 	arc_buf_hdr_t *hdr;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-projects mailing list