FreeBSD Bugzilla – Attachment 146178 Details for
Bug 187594
[zfs] [patch] ZFS ARC behavior problem and fix
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
refactor arc reclaim logic
arc-reclaim.patch (text/plain), 6.79 KB, created by
Steven Hartland
on 2014-08-23 14:18:50 UTC
(
hide
)
Description:
refactor arc reclaim logic
Filename:
MIME Type:
Creator:
Steven Hartland
Created:
2014-08-23 14:18:50 UTC
Size:
6.79 KB
patch
obsolete
>Index: sys/cddl/compat/opensolaris/kern/opensolaris_kmem.c >=================================================================== >--- sys/cddl/compat/opensolaris/kern/opensolaris_kmem.c (revision 270315) >+++ sys/cddl/compat/opensolaris/kern/opensolaris_kmem.c (working copy) >@@ -126,20 +126,42 @@ > } > SYSINIT(kmem_size_init, SI_SUB_KMEM, SI_ORDER_ANY, kmem_size_init, NULL); > >+/* >+ * The returns from kmem_free_*size are only valid once the pagedaemon >+ * has been initialised, before then they return 0. >+ * >+ * To ensure the returns are valid the caller can use a SYSINIT with >+ * subsystem set to SI_SUB_KTHREAD_PAGE and order of at least >+ * SI_ORDER_SECOND. >+ */ > uint64_t >-kmem_size(void) >+kmem_free_target_size(void) > { > >- return (kmem_size_val); >+ return ((uint64_t)cnt.v_free_target * PAGE_SIZE); > } > > uint64_t >-kmem_used(void) >+kmem_free_min_size(void) > { > >- return (vmem_size(kmem_arena, VMEM_ALLOC)); >+ return ((uint64_t)cnt.v_free_min * PAGE_SIZE); > } > >+uint64_t >+kmem_free_size(void) >+{ >+ >+ return ((uint64_t)cnt.v_free_count * PAGE_SIZE); >+} >+ >+uint64_t >+kmem_size(void) >+{ >+ >+ return (kmem_size_val); >+} >+ > static int > kmem_std_constructor(void *mem, int size __unused, void *private, int flags) > { >Index: sys/cddl/compat/opensolaris/sys/kmem.h >=================================================================== >--- sys/cddl/compat/opensolaris/sys/kmem.h (revision 270315) >+++ sys/cddl/compat/opensolaris/sys/kmem.h (working copy) >@@ -66,7 +66,12 @@ > void *zfs_kmem_alloc(size_t size, int kmflags); > void zfs_kmem_free(void *buf, size_t size); > uint64_t kmem_size(void); >-uint64_t kmem_used(void); >+ >+/* Return vals from kmem_free_*size are only valid after the pagedaemon init. */ >+uint64_t kmem_free_size(void); >+uint64_t kmem_free_target_size(void); >+uint64_t kmem_free_min_size(void); >+ > kmem_cache_t *kmem_cache_create(char *name, size_t bufsize, size_t align, > int (*constructor)(void *, void *, int), void (*destructor)(void *, void *), > void (*reclaim)(void *) __unused, void *private, vmem_t *vmp, int cflags); >Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c >=================================================================== >--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c (revision 270315) >+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c (working copy) >@@ -193,9 +193,6 @@ > */ > static boolean_t arc_warm; > >-/* >- * These tunables are for performance analysis. >- */ > uint64_t zfs_arc_max; > uint64_t zfs_arc_min; > uint64_t zfs_arc_meta_limit = 0; >@@ -204,7 +201,20 @@ > int zfs_arc_p_min_shift = 0; > int zfs_disable_dup_eviction = 0; > uint64_t zfs_arc_average_blocksize = 8 * 1024; /* 8KB */ >+uint64_t zfs_arc_free_target = (1 << 30); /* 1GB */ > >+static int sysctl_vfs_zfs_arc_free_target(SYSCTL_HANDLER_ARGS); >+ >+static void >+arc_free_target_init(void *unused __unused) >+{ >+ >+ zfs_arc_free_target = kmem_free_target_size() * 3; >+} >+SYSINIT(arc_free_target_init, SI_SUB_KTHREAD_PAGE, SI_ORDER_ANY, >+ arc_free_target_init, NULL); >+ >+ > TUNABLE_QUAD("vfs.zfs.arc_max", &zfs_arc_max); > TUNABLE_QUAD("vfs.zfs.arc_min", &zfs_arc_min); > TUNABLE_QUAD("vfs.zfs.arc_meta_limit", &zfs_arc_meta_limit); >@@ -217,7 +227,34 @@ > SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, arc_average_blocksize, CTLFLAG_RDTUN, > &zfs_arc_average_blocksize, 0, > "ARC average blocksize"); >+/* >+ * We don't have a tunable for arc_free_target due to the dependency on >+ * pagedaemon initialisation. >+ */ >+SYSCTL_PROC(_vfs_zfs, OID_AUTO, arc_free_target, >+ CTLTYPE_U64 | CTLFLAG_MPSAFE | CTLFLAG_RW, 0, sizeof(uint64_t), >+ sysctl_vfs_zfs_arc_free_target, "QU", >+ "Desired amount of free memory below which ARC triggers reclaim"); > >+static int >+sysctl_vfs_zfs_arc_free_target(SYSCTL_HANDLER_ARGS) >+{ >+ uint64_t val; >+ int err; >+ >+ val = zfs_arc_free_target; >+ err = sysctl_handle_64(oidp, &val, 0, req); >+ if (err != 0 || req->newptr == NULL) >+ return (err); >+ >+ if (val < kmem_free_min_size()) >+ return (EINVAL); >+ >+ zfs_arc_free_target = val; >+ >+ return (0); >+} >+ > /* > * Note that buffers can be in one of 6 states: > * ARC_anon - anonymous (discussed below) >@@ -2421,9 +2458,12 @@ > void > arc_shrink(void) > { >+ > if (arc_c > arc_c_min) { > uint64_t to_free; > >+ DTRACE_PROBE2(arc__shrink, uint64_t, arc_c, uint64_t, >+ arc_c_min); > #ifdef _KERNEL > to_free = arc_c >> arc_shrink_shift; > #else >@@ -2443,8 +2483,11 @@ > ASSERT((int64_t)arc_p >= 0); > } > >- if (arc_size > arc_c) >+ if (arc_size > arc_c) { >+ DTRACE_PROBE2(arc__shrink_adjust, uint64_t, arc_size, >+ uint64_t, arc_c); > arc_adjust(); >+ } > } > > static int needfree = 0; >@@ -2455,15 +2498,24 @@ > > #ifdef _KERNEL > >- if (needfree) >+ if (needfree) { >+ DTRACE_PROBE(arc__reclaim_needfree); > return (1); >+ } > >+ if (kmem_free_size() < zfs_arc_free_target) { >+ DTRACE_PROBE(arc__reclaim_freetarget); >+ return (1); >+ } >+ > /* > * Cooperate with pagedaemon when it's time for it to scan > * and reclaim some pages. > */ >- if (vm_paging_needed()) >+ if (vm_paging_needed()) { >+ DTRACE_PROBE(arc__reclaim_paging); > return (1); >+ } > > #ifdef sun > /* >@@ -2507,9 +2559,6 @@ > (btop(vmem_size(heap_arena, VMEM_FREE | VMEM_ALLOC)) >> 2)) > return (1); > #endif >-#else /* !sun */ >- if (kmem_used() > (kmem_size() * 3) / 4) >- return (1); > #endif /* sun */ > > #else >@@ -2516,6 +2565,8 @@ > if (spa_get_random(100) == 0) > return (1); > #endif >+ DTRACE_PROBE(arc__reclaim_no); >+ > return (0); > } > >Index: sys/vm/vm_pageout.c >=================================================================== >--- sys/vm/vm_pageout.c (revision 270315) >+++ sys/vm/vm_pageout.c (working copy) >@@ -115,10 +115,14 @@ > > /* the kernel process "vm_pageout"*/ > static void vm_pageout(void); >+static void vm_pageout_init(void); > static int vm_pageout_clean(vm_page_t); > static void vm_pageout_scan(struct vm_domain *vmd, int pass); > static void vm_pageout_mightbe_oom(struct vm_domain *vmd, int pass); > >+SYSINIT(pagedaemon_init, SI_SUB_KTHREAD_PAGE, SI_ORDER_FIRST, vm_pageout_init, >+ NULL); >+ > struct proc *pageproc; > > static struct kproc_desc page_kp = { >@@ -126,7 +130,7 @@ > vm_pageout, > &pageproc > }; >-SYSINIT(pagedaemon, SI_SUB_KTHREAD_PAGE, SI_ORDER_FIRST, kproc_start, >+SYSINIT(pagedaemon, SI_SUB_KTHREAD_PAGE, SI_ORDER_SECOND, kproc_start, > &page_kp); > > #if !defined(NO_SWAPPING) >@@ -1647,15 +1651,11 @@ > } > > /* >- * vm_pageout is the high level pageout daemon. >+ * vm_pageout_init initialises basic pageout daemon settings. > */ > static void >-vm_pageout(void) >+vm_pageout_init(void) > { >-#if MAXMEMDOM > 1 >- int error, i; >-#endif >- > /* > * Initialize some paging parameters. > */ >@@ -1701,7 +1701,18 @@ > /* XXX does not really belong here */ > if (vm_page_max_wired == 0) > vm_page_max_wired = cnt.v_free_count / 3; >+} > >+/* >+ * vm_pageout is the high level pageout daemon. >+ */ >+static void >+vm_pageout(void) >+{ >+#if MAXMEMDOM > 1 >+ int error, i; >+#endif >+ > swap_pager_swap_init(); > #if MAXMEMDOM > 1 > for (i = 1; i < vm_ndomains; i++) {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 187594
:
140882
|
140883
|
140884
|
140885
|
140886
|
140887
|
140888
|
140889
|
140890
|
140891
|
140892
|
146178
|
146203
|
146249
|
146251
|
146287
|
146300
|
146373
|
146423
|
146424
|
146456
|
146816
|
146817
|
146851
|
146852
|
146854
|
146859
|
146861
|
146946
|
146947
|
146948
|
146949
|
147014
|
147068
|
147069
|
147070
|
147265
|
147274
|
147275
|
147276
|
147286
|
147459
|
147607
|
147609
|
147733
|
147738
|
147754
|
147815
|
152852
|
158809
|
159207
|
159688
|
159859
|
159905
|
161691
|
161692
|
161943
|
164051
|
174197
|
174198
|
174231
|
174232
|
174254
|
186818