Date: Wed, 17 Mar 2010 00:53:58 +0000 (UTC) From: Marcel Moolenaar <marcel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: 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... Message-ID: <201003170053.o2H0rwBw047149@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201003170053.o2H0rwBw047149>