View | Details | Raw Unified | Return to bug 187594 | Differences between
and this patch

Collapse All | Expand All

(-)sys/cddl/compat/opensolaris/kern/opensolaris_kmem.c (-43 lines)
Lines 126-167 kmem_size_init(void *unused __unused) Link Here
126
}
126
}
127
SYSINIT(kmem_size_init, SI_SUB_KMEM, SI_ORDER_ANY, kmem_size_init, NULL);
127
SYSINIT(kmem_size_init, SI_SUB_KMEM, SI_ORDER_ANY, kmem_size_init, NULL);
128
128
129
/*
130
 * The return values from kmem_free_* are only valid once the pagedaemon
131
 * has been initialised, before then they return 0.
132
 * 
133
 * To ensure the returns are valid the caller can use a SYSINIT with
134
 * subsystem set to SI_SUB_KTHREAD_PAGE and an order of at least
135
 * SI_ORDER_SECOND.
136
 */
137
u_int
138
kmem_free_target(void)
139
{
140
141
	return (vm_cnt.v_free_target);
142
}
143
144
u_int
145
kmem_free_min(void)
146
{
147
148
	return (vm_cnt.v_free_min);
149
}
150
151
u_int
152
kmem_free_count(void)
153
{
154
155
	return (vm_cnt.v_free_count + vm_cnt.v_cache_count);
156
}
157
158
u_int
159
kmem_page_count(void)
160
{
161
162
	return (vm_cnt.v_page_count);
163
}
164
165
uint64_t
129
uint64_t
166
kmem_size(void)
130
kmem_size(void)
167
{
131
{
Lines 169-181 kmem_size(void) Link Here
169
	return (kmem_size_val);
133
	return (kmem_size_val);
170
}
134
}
171
135
172
uint64_t
173
kmem_used(void)
174
{
175
176
	return (vmem_size(kmem_arena, VMEM_ALLOC));
177
}
178
179
static int
136
static int
180
kmem_std_constructor(void *mem, int size __unused, void *private, int flags)
137
kmem_std_constructor(void *mem, int size __unused, void *private, int flags)
181
{
138
{
(-)sys/cddl/compat/opensolaris/sys/kmem.h (-11 / +3 lines)
Lines 66-82 typedef struct kmem_cache { Link Here
66
void *zfs_kmem_alloc(size_t size, int kmflags);
66
void *zfs_kmem_alloc(size_t size, int kmflags);
67
void zfs_kmem_free(void *buf, size_t size);
67
void zfs_kmem_free(void *buf, size_t size);
68
uint64_t kmem_size(void);
68
uint64_t kmem_size(void);
69
uint64_t kmem_used(void);
70
u_int kmem_page_count(void);
71
72
/*
73
 * The return values from kmem_free_* are only valid once the pagedaemon
74
 * has been initialised, before then they return 0.
75
 */
76
u_int kmem_free_count(void);
77
u_int kmem_free_target(void);
78
u_int kmem_free_min(void);
79
80
kmem_cache_t *kmem_cache_create(char *name, size_t bufsize, size_t align,
69
kmem_cache_t *kmem_cache_create(char *name, size_t bufsize, size_t align,
81
    int (*constructor)(void *, void *, int), void (*destructor)(void *, void *),
70
    int (*constructor)(void *, void *, int), void (*destructor)(void *, void *),
82
    void (*reclaim)(void *) __unused, void *private, vmem_t *vmp, int cflags);
71
    void (*reclaim)(void *) __unused, void *private, vmem_t *vmp, int cflags);
Lines 88-93 void kmem_reap(void); Link Here
88
int kmem_debugging(void);
77
int kmem_debugging(void);
89
void *calloc(size_t n, size_t s);
78
void *calloc(size_t n, size_t s);
90
79
80
#define	freemem				(vm_cnt.v_free_count + vm_cnt.v_cache_count)
81
#define	minfree				vm_cnt.v_free_min
82
#define	heap_arena			kmem_arena
91
#define	kmem_alloc(size, kmflags)	zfs_kmem_alloc((size), (kmflags))
83
#define	kmem_alloc(size, kmflags)	zfs_kmem_alloc((size), (kmflags))
92
#define	kmem_zalloc(size, kmflags)	zfs_kmem_alloc((size), (kmflags) | M_ZERO)
84
#define	kmem_zalloc(size, kmflags)	zfs_kmem_alloc((size), (kmflags) | M_ZERO)
93
#define	kmem_free(buf, size)		zfs_kmem_free((buf), (size))
85
#define	kmem_free(buf, size)		zfs_kmem_free((buf), (size))
(-)sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c (-49 / +55 lines)
Lines 138-143 Link Here
138
#include <sys/sdt.h>
138
#include <sys/sdt.h>
139
139
140
#include <vm/vm_pageout.h>
140
#include <vm/vm_pageout.h>
141
#include <machine/vmparam.h>
141
142
142
#ifdef illumos
143
#ifdef illumos
143
#ifndef _KERNEL
144
#ifndef _KERNEL
Lines 201-207 int zfs_arc_shrink_shift = 0; Link Here
201
int zfs_arc_p_min_shift = 0;
202
int zfs_arc_p_min_shift = 0;
202
int zfs_disable_dup_eviction = 0;
203
int zfs_disable_dup_eviction = 0;
203
uint64_t zfs_arc_average_blocksize = 8 * 1024; /* 8KB */
204
uint64_t zfs_arc_average_blocksize = 8 * 1024; /* 8KB */
204
u_int zfs_arc_free_target = (1 << 19); /* default before pagedaemon init only */
205
u_int zfs_arc_free_target = (1 << 16); /* default before pagedaemon init only */
205
206
206
static int sysctl_vfs_zfs_arc_free_target(SYSCTL_HANDLER_ARGS);
207
static int sysctl_vfs_zfs_arc_free_target(SYSCTL_HANDLER_ARGS);
207
208
Lines 210-220 static void Link Here
210
arc_free_target_init(void *unused __unused)
211
arc_free_target_init(void *unused __unused)
211
{
212
{
212
213
213
	zfs_arc_free_target = kmem_free_target();
214
	zfs_arc_free_target = vm_pageout_wakeup_thresh;
214
}
215
}
215
SYSINIT(arc_free_target_init, SI_SUB_KTHREAD_PAGE, SI_ORDER_ANY,
216
SYSINIT(arc_free_target_init, SI_SUB_KTHREAD_PAGE, SI_ORDER_ANY,
216
    arc_free_target_init, NULL);
217
    arc_free_target_init, NULL);
217
#endif
218
218
219
TUNABLE_QUAD("vfs.zfs.arc_meta_limit", &zfs_arc_meta_limit);
219
TUNABLE_QUAD("vfs.zfs.arc_meta_limit", &zfs_arc_meta_limit);
220
SYSCTL_DECL(_vfs_zfs);
220
SYSCTL_DECL(_vfs_zfs);
Lines 245-253 sysctl_vfs_zfs_arc_free_target(SYSCTL_HANDLER_ARGS Link Here
245
	if (err != 0 || req->newptr == NULL)
245
	if (err != 0 || req->newptr == NULL)
246
		return (err);
246
		return (err);
247
247
248
	if (val < kmem_free_min())
248
	if (val < minfree)
249
		return (EINVAL);
249
		return (EINVAL);
250
	if (val > kmem_page_count())
250
	if (val > vm_cnt.v_page_count)
251
		return (EINVAL);
251
		return (EINVAL);
252
252
253
	zfs_arc_free_target = val;
253
	zfs_arc_free_target = val;
Lines 254-259 sysctl_vfs_zfs_arc_free_target(SYSCTL_HANDLER_ARGS Link Here
254
254
255
	return (0);
255
	return (0);
256
}
256
}
257
#endif
257
258
258
/*
259
/*
259
 * Note that buffers can be in one of 6 states:
260
 * Note that buffers can be in one of 6 states:
Lines 2503-2520 arc_reclaim_needed(void) Link Here
2503
		return (1);
2504
		return (1);
2504
	}
2505
	}
2505
2506
2506
	if (kmem_free_count() < zfs_arc_free_target) {
2507
		DTRACE_PROBE2(arc__reclaim_freetarget, uint64_t,
2508
		    kmem_free_count(), uint64_t, zfs_arc_free_target);
2509
		return (1);
2510
	}
2511
2512
	/*
2507
	/*
2513
	 * Cooperate with pagedaemon when it's time for it to scan
2508
	 * Cooperate with pagedaemon when it's time for it to scan
2514
	 * and reclaim some pages.
2509
	 * and reclaim some pages.
2515
	 */
2510
	 */
2516
	if (vm_paging_needed()) {
2511
	if (freemem < zfs_arc_free_target) {
2517
		DTRACE_PROBE(arc__reclaim_paging);
2512
		DTRACE_PROBE2(arc__reclaim_freemem, uint64_t,
2513
		    freemem, uint64_t, zfs_arc_free_target);
2518
		return (1);
2514
		return (1);
2519
	}
2515
	}
2520
2516
Lines 2544-2551 arc_reclaim_needed(void) Link Here
2544
	if (availrmem < swapfs_minfree + swapfs_reserve + extra)
2540
	if (availrmem < swapfs_minfree + swapfs_reserve + extra)
2545
		return (1);
2541
		return (1);
2546
2542
2547
#if defined(__i386)
2548
	/*
2543
	/*
2544
	 * Check that we have enough availrmem that memory locking (e.g., via
2545
	 * mlock(3C) or memcntl(2)) can still succeed.  (pages_pp_maximum
2546
	 * stores the number of pages that cannot be locked; when availrmem
2547
	 * drops below pages_pp_maximum, page locking mechanisms such as
2548
	 * page_pp_lock() will fail.)
2549
	 */
2550
	if (availrmem <= pages_pp_maximum)
2551
		return (1);
2552
2553
#endif	/* sun */
2554
#if defined(__i386) || !defined(UMA_MD_SMALL_ALLOC)
2555
	/*
2549
	 * If we're on an i386 platform, it's possible that we'll exhaust the
2556
	 * If we're on an i386 platform, it's possible that we'll exhaust the
2550
	 * kernel heap space before we ever run out of available physical
2557
	 * kernel heap space before we ever run out of available physical
2551
	 * memory.  Most checks of the size of the heap_area compare against
2558
	 * memory.  Most checks of the size of the heap_area compare against
Lines 2556-2580 arc_reclaim_needed(void) Link Here
2556
	 * heap is allocated.  (Or, in the calculation, if less than 1/4th is
2563
	 * heap is allocated.  (Or, in the calculation, if less than 1/4th is
2557
	 * free)
2564
	 * free)
2558
	 */
2565
	 */
2559
	if (btop(vmem_size(heap_arena, VMEM_FREE)) <
2566
	if (vmem_size(heap_arena, VMEM_FREE) <
2560
	    (btop(vmem_size(heap_arena, VMEM_FREE | VMEM_ALLOC)) >> 2))
2567
	    (vmem_size(heap_arena, VMEM_FREE | VMEM_ALLOC) >> 2)) {
2561
		return (1);
2562
#endif
2563
#else	/* sun */
2564
#ifdef __i386__
2565
	/* i386 has KVA limits that the raw page counts above don't consider */
2566
	if (kmem_used() > (kmem_size() * 3) / 4) {
2567
		DTRACE_PROBE2(arc__reclaim_used, uint64_t,
2568
		DTRACE_PROBE2(arc__reclaim_used, uint64_t,
2568
		    kmem_used(), uint64_t, (kmem_size() * 3) / 4);
2569
		    vmem_size(heap_arena, VMEM_FREE), uint64_t,
2570
		    (vmem_size(heap_arena, VMEM_FREE | VMEM_ALLOC)) >> 2);
2569
		return (1);
2571
		return (1);
2570
	}
2572
	}
2571
#endif
2573
#endif
2574
#ifdef sun
2575
	/*
2576
	 * If zio data pages are being allocated out of a separate heap segment,
2577
	 * then enforce that the size of available vmem for this arena remains
2578
	 * above about 1/16th free.
2579
	 *
2580
	 * Note: The 1/16th arena free requirement was put in place
2581
	 * to aggressively evict memory from the arc in order to avoid
2582
	 * memory fragmentation issues.
2583
	 */
2584
	if (zio_arena != NULL &&
2585
	    vmem_size(zio_arena, VMEM_FREE) <
2586
	    (vmem_size(zio_arena, VMEM_ALLOC) >> 4))
2587
		return (1);
2572
#endif	/* sun */
2588
#endif	/* sun */
2573
2589
#else	/* _KERNEL */
2574
#else
2575
	if (spa_get_random(100) == 0)
2590
	if (spa_get_random(100) == 0)
2576
		return (1);
2591
		return (1);
2577
#endif
2592
#endif	/* _KERNEL */
2578
	DTRACE_PROBE(arc__reclaim_no);
2593
	DTRACE_PROBE(arc__reclaim_no);
2579
2594
2580
	return (0);
2595
	return (0);
Lines 2625-2630 arc_kmem_reap_now(arc_reclaim_strategy_t strat) Link Here
2625
	}
2640
	}
2626
	kmem_cache_reap_now(buf_cache);
2641
	kmem_cache_reap_now(buf_cache);
2627
	kmem_cache_reap_now(hdr_cache);
2642
	kmem_cache_reap_now(hdr_cache);
2643
2644
#ifdef sun
2645
	/*
2646
	 * Ask the vmem areana to reclaim unused memory from its
2647
	 * quantum caches.
2648
	 */
2649
	if (zio_arena != NULL && strat == ARC_RECLAIM_AGGR)
2650
		vmem_qcache_reap(zio_arena);
2651
#endif
2628
}
2652
}
2629
2653
2630
static void
2654
static void
Lines 2774-2793 arc_evict_needed(arc_buf_contents_t type) Link Here
2774
	if (type == ARC_BUFC_METADATA && arc_meta_used >= arc_meta_limit)
2798
	if (type == ARC_BUFC_METADATA && arc_meta_used >= arc_meta_limit)
2775
		return (1);
2799
		return (1);
2776
2800
2777
#ifdef sun
2778
#ifdef _KERNEL
2779
	/*
2780
	 * If zio data pages are being allocated out of a separate heap segment,
2781
	 * then enforce that the size of available vmem for this area remains
2782
	 * above about 1/32nd free.
2783
	 */
2784
	if (type == ARC_BUFC_DATA && zio_arena != NULL &&
2785
	    vmem_size(zio_arena, VMEM_FREE) <
2786
	    (vmem_size(zio_arena, VMEM_ALLOC) >> 5))
2787
		return (1);
2788
#endif
2789
#endif	/* sun */
2790
2791
	if (arc_reclaim_needed())
2801
	if (arc_reclaim_needed())
2792
		return (1);
2802
		return (1);
2793
2803
Lines 3946-3965 static int Link Here
3946
arc_memory_throttle(uint64_t reserve, uint64_t txg)
3956
arc_memory_throttle(uint64_t reserve, uint64_t txg)
3947
{
3957
{
3948
#ifdef _KERNEL
3958
#ifdef _KERNEL
3949
	uint64_t available_memory =
3959
	uint64_t available_memory = ptob(freemem);
3950
	    ptoa((uintmax_t)vm_cnt.v_free_count + vm_cnt.v_cache_count);
3951
	static uint64_t page_load = 0;
3960
	static uint64_t page_load = 0;
3952
	static uint64_t last_txg = 0;
3961
	static uint64_t last_txg = 0;
3953
3962
3954
#ifdef sun
3963
#if defined(__i386) || !defined(UMA_MD_SMALL_ALLOC)
3955
#if defined(__i386)
3956
	available_memory =
3964
	available_memory =
3957
	    MIN(available_memory, vmem_size(heap_arena, VMEM_FREE));
3965
	    MIN(available_memory, ptob(vmem_size(heap_arena, VMEM_FREE)));
3958
#endif
3966
#endif
3959
#endif	/* sun */
3960
3967
3961
	if (vm_cnt.v_free_count + vm_cnt.v_cache_count >
3968
	if (freemem > (uint64_t)physmem * arc_lotsfree_percent / 100)
3962
	    (uint64_t)physmem * arc_lotsfree_percent / 100)
3963
		return (0);
3969
		return (0);
3964
3970
3965
	if (txg > last_txg) {
3971
	if (txg > last_txg) {
Lines 3972-3978 arc_memory_throttle(uint64_t reserve, uint64_t txg Link Here
3972
	 * continue to let page writes occur as quickly as possible.
3978
	 * continue to let page writes occur as quickly as possible.
3973
	 */
3979
	 */
3974
	if (curproc == pageproc) {
3980
	if (curproc == pageproc) {
3975
		if (page_load > available_memory / 4)
3981
		if (page_load > MAX(ptob(minfree), available_memory) / 4)
3976
			return (SET_ERROR(ERESTART));
3982
			return (SET_ERROR(ERESTART));
3977
		/* Note: reserve is inflated, so we deflate */
3983
		/* Note: reserve is inflated, so we deflate */
3978
		page_load += reserve / 8;
3984
		page_load += reserve / 8;

Return to bug 187594