Mercurial > illumos > illumos-gate
changeset 13682:e7836650181b
1618 zfs causing system to hang in vmem_xalloc()
Reviewed by: Eric Schrock <eric.schrock@delphix.com>
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Matt Ahrens <matt@delphix.com>
Reviewed by: Richard Elling <richard.elling@richardelling.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Steve Gonczi <gonczi@comcast.net>
Approved by: Gordon Ross <gwr@nexenta.com>
author | George Wilson <gwilson@delphix.com> |
---|---|
date | Sun, 06 May 2012 18:49:02 -0700 |
parents | 73253247f9e5 |
children | cf6fa37148dd |
files | usr/src/lib/libzpool/common/kernel.c usr/src/lib/libzpool/common/sys/zfs_context.h usr/src/uts/common/fs/zfs/arc.c usr/src/uts/common/os/vmem.c usr/src/uts/common/sys/vmem.h |
diffstat | 5 files changed, 53 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/lib/libzpool/common/kernel.c Thu May 03 15:56:05 2012 +0200 +++ b/usr/src/lib/libzpool/common/kernel.c Sun May 06 18:49:02 2012 -0700 @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012 by Delphix. All rights reserved. */ #include <assert.h> @@ -45,6 +46,7 @@ uint64_t physmem; vnode_t *rootdir = (vnode_t *)0xabcd1234; char hw_serial[HW_HOSTID_LEN]; +vmem_t *zio_arena = NULL; struct utsname utsname = { "userland", "libzpool", "1", "1", "na"
--- a/usr/src/lib/libzpool/common/sys/zfs_context.h Thu May 03 15:56:05 2012 +0200 +++ b/usr/src/lib/libzpool/common/sys/zfs_context.h Sun May 06 18:49:02 2012 -0700 @@ -20,9 +20,8 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - */ -/* * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012 by Delphix. All rights reserved. */ #ifndef _SYS_ZFS_CONTEXT_H @@ -330,9 +329,12 @@ #define kmem_debugging() 0 #define kmem_cache_reap_now(_c) /* nothing */ #define kmem_cache_set_move(_c, _cb) /* nothing */ +#define vmem_qcache_reap(_v) /* nothing */ #define POINTER_INVALIDATE(_pp) /* nothing */ #define POINTER_IS_VALID(_p) 0 +extern vmem_t *zio_arena; + typedef umem_cache_t kmem_cache_t; typedef enum kmem_cbrc {
--- a/usr/src/uts/common/fs/zfs/arc.c Thu May 03 15:56:05 2012 +0200 +++ b/usr/src/uts/common/fs/zfs/arc.c Sun May 06 18:49:02 2012 -0700 @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2011 Nexenta Systems, Inc. All rights reserved. - * Copyright (c) 2011 by Delphix. All rights reserved. + * Copyright (c) 2012 by Delphix. All rights reserved. */ /* @@ -1982,6 +1982,11 @@ arc_adjust(); } +/* + * Determine if the system is under memory pressure and is asking + * to reclaim memory. A return value of 1 indicates that the system + * is under memory pressure and that the arc should adjust accordingly. + */ static int arc_reclaim_needed(void) { @@ -2029,11 +2034,24 @@ * heap is allocated. (Or, in the calculation, if less than 1/4th is * free) */ - if (btop(vmem_size(heap_arena, VMEM_FREE)) < - (btop(vmem_size(heap_arena, VMEM_FREE | VMEM_ALLOC)) >> 2)) + if (vmem_size(heap_arena, VMEM_FREE) < + (vmem_size(heap_arena, VMEM_FREE | VMEM_ALLOC) >> 2)) return (1); #endif + /* + * If zio data pages are being allocated out of a separate heap segment, + * then enforce that the size of available vmem for this arena remains + * above about 1/16th free. + * + * Note: The 1/16th arena free requirement was put in place + * to aggressively evict memory from the arc in order to avoid + * memory fragmentation issues. + */ + if (zio_arena != NULL && + vmem_size(zio_arena, VMEM_FREE) < + (vmem_size(zio_arena, VMEM_ALLOC) >> 4)) + return (1); #else if (spa_get_random(100) == 0) return (1); @@ -2085,6 +2103,13 @@ } kmem_cache_reap_now(buf_cache); kmem_cache_reap_now(hdr_cache); + + /* + * Ask the vmem areana to reclaim unused memory from its + * quantum caches. + */ + if (zio_arena != NULL && strat == ARC_RECLAIM_AGGR) + vmem_qcache_reap(zio_arena); } static void @@ -2218,18 +2243,6 @@ if (type == ARC_BUFC_METADATA && arc_meta_used >= arc_meta_limit) return (1); -#ifdef _KERNEL - /* - * If zio data pages are being allocated out of a separate heap segment, - * then enforce that the size of available vmem for this area remains - * above about 1/32nd free. - */ - if (type == ARC_BUFC_DATA && zio_arena != NULL && - vmem_size(zio_arena, VMEM_FREE) < - (vmem_size(zio_arena, VMEM_ALLOC) >> 5)) - return (1); -#endif - if (arc_reclaim_needed()) return (1);
--- a/usr/src/uts/common/os/vmem.c Thu May 03 15:56:05 2012 +0200 +++ b/usr/src/uts/common/os/vmem.c Sun May 06 18:49:02 2012 -0700 @@ -24,6 +24,10 @@ */ /* + * Copyright (c) 2012 by Delphix. All rights reserved. + */ + +/* * Big Theory Statement for the virtual memory allocator. * * For a more complete description of the main ideas, see: @@ -1706,6 +1710,19 @@ (void) timeout(vmem_update, dummy, vmem_update_interval * hz); } +void +vmem_qcache_reap(vmem_t *vmp) +{ + int i; + + /* + * Reap any quantum caches that may be part of this vmem. + */ + for (i = 0; i < VMEM_NQCACHE_MAX; i++) + if (vmp->vm_qcache[i]) + kmem_cache_reap_now(vmp->vm_qcache[i]); +} + /* * Prepare vmem for use. */
--- a/usr/src/uts/common/sys/vmem.h Thu May 03 15:56:05 2012 +0200 +++ b/usr/src/uts/common/sys/vmem.h Sun May 06 18:49:02 2012 -0700 @@ -20,6 +20,7 @@ */ /* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012 by Delphix. All rights reserved. */ #ifndef _SYS_VMEM_H @@ -142,6 +143,7 @@ extern int vmem_contains(vmem_t *, void *, size_t); extern void vmem_walk(vmem_t *, int, void (*)(void *, void *, size_t), void *); extern size_t vmem_size(vmem_t *, int); +extern void vmem_qcache_reap(vmem_t *vmp); #ifdef __cplusplus }