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 (-4 / +26 lines)
Lines 126-145 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 returns from kmem_free_*size 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 order of at least
135
 * SI_ORDER_SECOND.
136
 */
129
uint64_t
137
uint64_t
130
kmem_size(void)
138
kmem_free_target_size(void)
131
{
139
{
132
140
133
	return (kmem_size_val);
141
	return ((uint64_t)vm_cnt.v_free_target * PAGE_SIZE);
134
}
142
}
135
143
136
uint64_t
144
uint64_t
137
kmem_used(void)
145
kmem_free_min_size(void)
138
{
146
{
139
147
140
	return (vmem_size(kmem_arena, VMEM_ALLOC));
148
	return ((uint64_t)vm_cnt.v_free_min * PAGE_SIZE);
141
}
149
}
142
150
151
uint64_t
152
kmem_free_size(void)
153
{
154
155
	return ((uint64_t)vm_cnt.v_free_count * PAGE_SIZE);
156
}
157
158
uint64_t
159
kmem_size(void)
160
{
161
162
	return (kmem_size_val);
163
}
164
143
static int
165
static int
144
kmem_std_constructor(void *mem, int size __unused, void *private, int flags)
166
kmem_std_constructor(void *mem, int size __unused, void *private, int flags)
145
{
167
{
(-)sys/cddl/compat/opensolaris/sys/kmem.h (-1 / +6 lines)
Lines 66-72 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);
69
70
/* Return vals from kmem_free_*size are only valid after the pagedaemon init. */
71
uint64_t kmem_free_size(void);
72
uint64_t kmem_free_target_size(void);
73
uint64_t kmem_free_min_size(void);
74
70
kmem_cache_t *kmem_cache_create(char *name, size_t bufsize, size_t align,
75
kmem_cache_t *kmem_cache_create(char *name, size_t bufsize, size_t align,
71
    int (*constructor)(void *, void *, int), void (*destructor)(void *, void *),
76
    int (*constructor)(void *, void *, int), void (*destructor)(void *, void *),
72
    void (*reclaim)(void *) __unused, void *private, vmem_t *vmp, int cflags);
77
    void (*reclaim)(void *) __unused, void *private, vmem_t *vmp, int cflags);
(-)sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c (-9 / +62 lines)
Lines 193-201 extern int zfs_prefetch_disable; Link Here
193
 */
193
 */
194
static boolean_t arc_warm;
194
static boolean_t arc_warm;
195
195
196
/*
197
 * These tunables are for performance analysis.
198
 */
199
uint64_t zfs_arc_max;
196
uint64_t zfs_arc_max;
200
uint64_t zfs_arc_min;
197
uint64_t zfs_arc_min;
201
uint64_t zfs_arc_meta_limit = 0;
198
uint64_t zfs_arc_meta_limit = 0;
Lines 204-210 int zfs_arc_shrink_shift = 0; Link Here
204
int zfs_arc_p_min_shift = 0;
201
int zfs_arc_p_min_shift = 0;
205
int zfs_disable_dup_eviction = 0;
202
int zfs_disable_dup_eviction = 0;
206
uint64_t zfs_arc_average_blocksize = 8 * 1024; /* 8KB */
203
uint64_t zfs_arc_average_blocksize = 8 * 1024; /* 8KB */
204
uint64_t zfs_arc_free_target = (1 << 30); /* 1GB */
207
205
206
static int sysctl_vfs_zfs_arc_free_target(SYSCTL_HANDLER_ARGS);
207
208
#ifdef _KERNEL
209
static void
210
arc_free_target_init(void *unused __unused)
211
{
212
213
	zfs_arc_free_target = kmem_free_target_size() * 3;
214
}
215
SYSINIT(arc_free_target_init, SI_SUB_KTHREAD_PAGE, SI_ORDER_ANY,
216
    arc_free_target_init, NULL);
217
#endif
218
208
TUNABLE_QUAD("vfs.zfs.arc_meta_limit", &zfs_arc_meta_limit);
219
TUNABLE_QUAD("vfs.zfs.arc_meta_limit", &zfs_arc_meta_limit);
209
SYSCTL_DECL(_vfs_zfs);
220
SYSCTL_DECL(_vfs_zfs);
210
SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, arc_max, CTLFLAG_RDTUN, &zfs_arc_max, 0,
221
SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, arc_max, CTLFLAG_RDTUN, &zfs_arc_max, 0,
Lines 214-220 SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, arc_min, CTLFLAG_ Link Here
214
SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, arc_average_blocksize, CTLFLAG_RDTUN,
225
SYSCTL_UQUAD(_vfs_zfs, OID_AUTO, arc_average_blocksize, CTLFLAG_RDTUN,
215
    &zfs_arc_average_blocksize, 0,
226
    &zfs_arc_average_blocksize, 0,
216
    "ARC average blocksize");
227
    "ARC average blocksize");
228
/*
229
 * We don't have a tunable for arc_free_target due to the dependency on
230
 * pagedaemon initialisation.
231
 */
232
SYSCTL_PROC(_vfs_zfs, OID_AUTO, arc_free_target,
233
    CTLTYPE_U64 | CTLFLAG_MPSAFE | CTLFLAG_RW, 0, sizeof(uint64_t),
234
    sysctl_vfs_zfs_arc_free_target, "QU",
235
    "Desired amount of free memory below which ARC triggers reclaim");
217
236
237
static int
238
sysctl_vfs_zfs_arc_free_target(SYSCTL_HANDLER_ARGS)
239
{
240
	uint64_t val;
241
	int err;
242
243
	val = zfs_arc_free_target;
244
	err = sysctl_handle_64(oidp, &val, 0, req);
245
	if (err != 0 || req->newptr == NULL)
246
		return (err);
247
248
	if (val < kmem_free_min_size())
249
		return (EINVAL);
250
251
	zfs_arc_free_target = val;
252
253
	return (0);
254
}
255
218
/*
256
/*
219
 * Note that buffers can be in one of 6 states:
257
 * Note that buffers can be in one of 6 states:
220
 *	ARC_anon	- anonymous (discussed below)
258
 *	ARC_anon	- anonymous (discussed below)
Lines 2418-2426 arc_flush(spa_t *spa) Link Here
2418
void
2456
void
2419
arc_shrink(void)
2457
arc_shrink(void)
2420
{
2458
{
2459
2421
	if (arc_c > arc_c_min) {
2460
	if (arc_c > arc_c_min) {
2422
		uint64_t to_free;
2461
		uint64_t to_free;
2423
2462
2463
		DTRACE_PROBE2(arc__shrink, uint64_t, arc_c, uint64_t,
2464
			arc_c_min);
2424
#ifdef _KERNEL
2465
#ifdef _KERNEL
2425
		to_free = arc_c >> arc_shrink_shift;
2466
		to_free = arc_c >> arc_shrink_shift;
2426
#else
2467
#else
Lines 2440-2447 arc_shrink(void) Link Here
2440
		ASSERT((int64_t)arc_p >= 0);
2481
		ASSERT((int64_t)arc_p >= 0);
2441
	}
2482
	}
2442
2483
2443
	if (arc_size > arc_c)
2484
	if (arc_size > arc_c) {
2485
		DTRACE_PROBE2(arc__shrink_adjust, uint64_t, arc_size,
2486
			uint64_t, arc_c);
2444
		arc_adjust();
2487
		arc_adjust();
2488
	}
2445
}
2489
}
2446
2490
2447
static int needfree = 0;
2491
static int needfree = 0;
Lines 2452-2466 arc_reclaim_needed(void) Link Here
2452
2496
2453
#ifdef _KERNEL
2497
#ifdef _KERNEL
2454
2498
2455
	if (needfree)
2499
	if (needfree) {
2500
		DTRACE_PROBE(arc__reclaim_needfree);
2456
		return (1);
2501
		return (1);
2502
	}
2457
2503
2504
	if (kmem_free_size() < zfs_arc_free_target) {
2505
		DTRACE_PROBE2(arc__reclaim_freetarget, uint64_t,
2506
		    kmem_free_size(), uint64_t, zfs_arc_free_target);
2507
		return (1);
2508
	}
2509
2458
	/*
2510
	/*
2459
	 * Cooperate with pagedaemon when it's time for it to scan
2511
	 * Cooperate with pagedaemon when it's time for it to scan
2460
	 * and reclaim some pages.
2512
	 * and reclaim some pages.
2461
	 */
2513
	 */
2462
	if (vm_paging_needed())
2514
	if (vm_paging_needed()) {
2515
		DTRACE_PROBE(arc__reclaim_paging);
2463
		return (1);
2516
		return (1);
2517
	}
2464
2518
2465
#ifdef sun
2519
#ifdef sun
2466
	/*
2520
	/*
Lines 2504-2512 arc_reclaim_needed(void) Link Here
2504
	    (btop(vmem_size(heap_arena, VMEM_FREE | VMEM_ALLOC)) >> 2))
2558
	    (btop(vmem_size(heap_arena, VMEM_FREE | VMEM_ALLOC)) >> 2))
2505
		return (1);
2559
		return (1);
2506
#endif
2560
#endif
2507
#else	/* !sun */
2508
	if (kmem_used() > (kmem_size() * 3) / 4)
2509
		return (1);
2510
#endif	/* sun */
2561
#endif	/* sun */
2511
2562
2512
#else
2563
#else
Lines 2513-2518 arc_reclaim_needed(void) Link Here
2513
	if (spa_get_random(100) == 0)
2564
	if (spa_get_random(100) == 0)
2514
		return (1);
2565
		return (1);
2515
#endif
2566
#endif
2567
	DTRACE_PROBE(arc__reclaim_no);
2568
2516
	return (0);
2569
	return (0);
2517
}
2570
}
2518
2571
(-)sys/vm/vm_pageout.c (-7 / +18 lines)
Lines 115-124 __FBSDID("$FreeBSD$"); Link Here
115
115
116
/* the kernel process "vm_pageout"*/
116
/* the kernel process "vm_pageout"*/
117
static void vm_pageout(void);
117
static void vm_pageout(void);
118
static void vm_pageout_init(void);
118
static int vm_pageout_clean(vm_page_t);
119
static int vm_pageout_clean(vm_page_t);
119
static void vm_pageout_scan(struct vm_domain *vmd, int pass);
120
static void vm_pageout_scan(struct vm_domain *vmd, int pass);
120
static void vm_pageout_mightbe_oom(struct vm_domain *vmd, int pass);
121
static void vm_pageout_mightbe_oom(struct vm_domain *vmd, int pass);
121
122
123
SYSINIT(pagedaemon_init, SI_SUB_KTHREAD_PAGE, SI_ORDER_FIRST, vm_pageout_init,
124
    NULL);
125
122
struct proc *pageproc;
126
struct proc *pageproc;
123
127
124
static struct kproc_desc page_kp = {
128
static struct kproc_desc page_kp = {
Lines 126-132 static struct kproc_desc page_kp = { Link Here
126
	vm_pageout,
130
	vm_pageout,
127
	&pageproc
131
	&pageproc
128
};
132
};
129
SYSINIT(pagedaemon, SI_SUB_KTHREAD_PAGE, SI_ORDER_FIRST, kproc_start,
133
SYSINIT(pagedaemon, SI_SUB_KTHREAD_PAGE, SI_ORDER_SECOND, kproc_start,
130
    &page_kp);
134
    &page_kp);
131
135
132
#if !defined(NO_SWAPPING)
136
#if !defined(NO_SWAPPING)
Lines 1637-1651 vm_pageout_worker(void *arg) Link Here
1637
}
1641
}
1638
1642
1639
/*
1643
/*
1640
 *	vm_pageout is the high level pageout daemon.
1644
 *	vm_pageout_init initialises basic pageout daemon settings.
1641
 */
1645
 */
1642
static void
1646
static void
1643
vm_pageout(void)
1647
vm_pageout_init(void)
1644
{
1648
{
1645
#if MAXMEMDOM > 1
1646
	int error, i;
1647
#endif
1648
1649
	/*
1649
	/*
1650
	 * Initialize some paging parameters.
1650
	 * Initialize some paging parameters.
1651
	 */
1651
	 */
Lines 1691-1697 static void Link Here
1691
	/* XXX does not really belong here */
1691
	/* XXX does not really belong here */
1692
	if (vm_page_max_wired == 0)
1692
	if (vm_page_max_wired == 0)
1693
		vm_page_max_wired = vm_cnt.v_free_count / 3;
1693
		vm_page_max_wired = vm_cnt.v_free_count / 3;
1694
}
1694
1695
1696
/*
1697
 *     vm_pageout is the high level pageout daemon.
1698
 */
1699
static void
1700
vm_pageout(void)
1701
{
1702
#if MAXMEMDOM > 1
1703
	int error, i;
1704
#endif
1705
1695
	swap_pager_swap_init();
1706
	swap_pager_swap_init();
1696
#if MAXMEMDOM > 1
1707
#if MAXMEMDOM > 1
1697
	for (i = 1; i < vm_ndomains; i++) {
1708
	for (i = 1; i < vm_ndomains; i++) {

Return to bug 187594