Skip to content

Commit 04d51c1

Browse files
committed
Changed the registry name from zfs_abd_prealloc_percent to zfs_prealloc_percent
Setting zfs_prealloc_percent=0 will disable the prealloc feature
1 parent cd0c019 commit 04d51c1

7 files changed

Lines changed: 131 additions & 34 deletions

File tree

include/os/windows/zfs/sys/kstat_windows.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ typedef struct windows_kstat {
150150
kstat_named_t zfs_removal_suspend_progress;
151151
kstat_named_t cpu_avx_supported;
152152
kstat_named_t zvol_io_threads;
153-
kstat_named_t zfs_abd_prealloc_percent;
153+
kstat_named_t zfs_prealloc_percent;
154154
} windows_kstat_t;
155155

156156

@@ -262,7 +262,7 @@ extern int zfs_autoimport_disable;
262262
extern int zfs_removal_suspend_progress;
263263
extern int cpu_avx_supported;
264264
extern int zvol_threads;
265-
extern int zfs_abd_prealloc_percent;
265+
extern int zfs_prealloc_percent;
266266

267267
int kstat_windows_init(void *);
268268
void kstat_windows_fini(void);

module/os/windows/spl/spl-kmem.c

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ extern uint64_t zfs_active_rwlock;
132132
extern uint64_t total_memory;
133133
extern uint64_t real_total_memory;
134134

135+
extern kmem_cache_t *abd_chunk_cache;
136+
extern uint64_t zfs_arc_max;
137+
extern int zfs_prealloc_percent;
138+
135139
#define MULT 1
136140

137141
static const char *KMEM_VA_PREFIX = "kmem_va";
@@ -4304,10 +4308,7 @@ spl_free_set_pressure(int64_t new_p)
43044308
// and any spl_free_set_and_wait_pressure() threads
43054309
cv_broadcast(&spl_free_thread_cv);
43064310
}
4307-
if (new_p > 0)
4308-
spl_free_last_pressure = zfs_lbolt();
4309-
else
4310-
spl_free_last_pressure = zfs_lbolt();
4311+
spl_free_last_pressure = zfs_lbolt();
43114312
}
43124313

43134314
void
@@ -4923,10 +4924,6 @@ spl_event_thread(void *notused)
49234924
thread_exit();
49244925
}
49254926

4926-
extern kmem_cache_t *abd_chunk_cache;
4927-
extern uint64_t zfs_arc_max;
4928-
extern int zfs_abd_prealloc_percent;
4929-
49304927
static void
49314928
spl_abd_prealloc_thread(void *notused)
49324929
{
@@ -4952,13 +4949,14 @@ spl_abd_prealloc_thread(void *notused)
49524949
delay(hz);
49534950
continue;
49544951
}
4955-
node = (abd_prealloc_node_t *)kmem_cache_alloc(abd_chunk_cache, KM_SLEEP);
4956-
list_insert_tail(&abd_prealloc_list, node);
49574952

49584953
if (segkmem_total_mem_allocated >=
4959-
(zfs_arc_max * zfs_abd_prealloc_percent) / 100) {
4954+
(zfs_arc_max * zfs_prealloc_percent) / 100) {
49604955
break;
49614956
}
4957+
4958+
node = (abd_prealloc_node_t *)kmem_cache_alloc(abd_chunk_cache, KM_SLEEP);
4959+
list_insert_tail(&abd_prealloc_list, node);
49624960
}
49634961

49644962
while ((node = list_remove_head(&abd_prealloc_list)) != NULL) {
@@ -4969,7 +4967,7 @@ spl_abd_prealloc_thread(void *notused)
49694967
dprintf("SPL: %s thread_exit\n", __func__);
49704968

49714969
KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "SPL: abd prealloc done segkmem_total_mem_allocated: %lld total_memory: %lld zfs_arc_max: %llu zfs_prealloc_percent: %d%\n",
4972-
segkmem_total_mem_allocated, total_memory, zfs_arc_max, zfs_abd_prealloc_percent));
4970+
segkmem_total_mem_allocated, total_memory, zfs_arc_max, zfs_prealloc_percent));
49734971
thread_exit();
49744972
}
49754973

@@ -5401,11 +5399,13 @@ spl_kmem_thread_init(void)
54015399
(void) thread_create(NULL, 0, spl_free_thread, 0, 0, 0, 0, 92);
54025400
spl_free_thread_running = TRUE;
54035401

5404-
//spl_event_thread_exit = FALSE;
5405-
//(void) thread_create(NULL, 0, spl_event_thread, 0, 0, 0, 0, 92);
5406-
5407-
spl_abd_prealloc_thread_exit = FALSE;
5408-
(void) thread_create(NULL, 0, spl_abd_prealloc_thread, 0, 0, 0, 0, 92);
5402+
if (zfs_prealloc_percent) {
5403+
spl_abd_prealloc_thread_exit = FALSE;
5404+
(void) thread_create(NULL, 0, spl_abd_prealloc_thread, 0, 0, 0, 0, 92);
5405+
} else {
5406+
spl_event_thread_exit = FALSE;
5407+
(void) thread_create(NULL, 0, spl_event_thread, 0, 0, 0, 0, 92);
5408+
}
54095409
}
54105410

54115411
void

module/os/windows/spl/spl-vmem.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,7 @@ extern void spl_free_set_emergency_pressure(int64_t p);
449449
extern uint64_t segkmem_total_mem_allocated;
450450
extern uint64_t total_memory;
451451
extern uint64_t zfs_arc_max;
452+
extern int zfs_prealloc_percent;
452453

453454
/*
454455
* Get a vmem_seg_t from the global segfree list.
@@ -1734,19 +1735,22 @@ vmem_xfree(vmem_t *vmp, void *vaddr, size_t size)
17341735
}
17351736

17361737
// calling vm_source_free will free the memory to windows, we
1737-
// don;t want to do this unless we are near the arc limit
1738-
boolean_t skip_sfree = true;
1739-
if (segkmem_total_mem_allocated >
1740-
(zfs_arc_max * 102) / 100) {
1741-
skip_sfree = false;
1742-
}
1738+
// don't want to do this unless we are crossing the arc limit when
1739+
// zfs_prealloc_percent is enabled.
1740+
boolean_t allow_vm_source_free = true;
1741+
if (zfs_prealloc_percent) {
1742+
if (segkmem_total_mem_allocated <
1743+
(zfs_arc_max * 102) / 100) {
1744+
allow_vm_source_free = false;
1745+
}
1746+
}
17431747

17441748
/*
17451749
* If the entire span is free, return it to the source.
17461750
*/
17471751
if (vsp->vs_aprev->vs_import && vmp->vm_source_free != NULL &&
17481752
vsp->vs_aprev->vs_type == VMEM_SPAN &&
1749-
vsp->vs_anext->vs_type == VMEM_SPAN && !skip_sfree) {
1753+
vsp->vs_anext->vs_type == VMEM_SPAN && allow_vm_source_free) {
17501754
vaddr = (void *)vsp->vs_start;
17511755
size = VS_SIZE(vsp);
17521756
ASSERT(size == VS_SIZE(vsp->vs_aprev));

module/os/windows/spl/spl-windows.c

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,14 @@ volatile unsigned int vm_page_speculative_count = 5500;
5353

5454
uint64_t spl_GetPhysMem(void);
5555
uint64_t spl_GetZfsTotalMemory(PUNICODE_STRING RegistryPath);
56+
uint64_t spl_getZfsPreallocSize(PUNICODE_STRING RegistryPath);
5657

5758
#include <sys/types.h>
5859
#include <Trace.h>
5960

6061
// Size in bytes of the memory allocated in seg_kmem
6162
extern uint64_t segkmem_total_mem_allocated;
63+
extern int zfs_prealloc_percent;
6264
#define MAXHOSTNAMELEN 64
6365
extern char hostname[MAXHOSTNAMELEN];
6466

@@ -528,6 +530,9 @@ spl_start(PUNICODE_STRING RegistryPath)
528530
spl_mutex_subsystem_init();
529531
spl_kmem_init(total_memory);
530532

533+
// lets get the registry value now, because the zfs loads the registry little later
534+
zfs_prealloc_percent = spl_getZfsPreallocSize(RegistryPath);
535+
531536
spl_vnode_init();
532537
spl_kmem_thread_init();
533538
spl_kmem_mp_init();
@@ -755,3 +760,91 @@ spl_GetZfsTotalMemory(PUNICODE_STRING RegistryPath)
755760
ZwClose(h);
756761
return (newvalue);
757762
}
763+
764+
uint64_t
765+
spl_getZfsPreallocSize(PUNICODE_STRING RegistryPath)
766+
{
767+
OBJECT_ATTRIBUTES ObjectAttributes;
768+
HANDLE h;
769+
NTSTATUS status;
770+
uint64_t newvalue = 0;
771+
772+
InitializeObjectAttributes(&ObjectAttributes,
773+
RegistryPath,
774+
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
775+
NULL,
776+
NULL);
777+
778+
status = ZwOpenKey(&h, // KeyHandle
779+
KEY_ALL_ACCESS, // DesiredAccess
780+
&ObjectAttributes); // ObjectAttributes
781+
782+
if (!NT_SUCCESS(status)) {
783+
dprintf("%s: Unable to open Registry %wZ: 0x%x. "
784+
"Going with defaults.\n", __func__, RegistryPath, status);
785+
return (0);
786+
}
787+
788+
ULONG index = 0;
789+
ULONG length = 0;
790+
PKEY_VALUE_FULL_INFORMATION regBuffer = NULL;
791+
792+
for (index = 0; status != STATUS_NO_MORE_ENTRIES; index++) {
793+
// Get the buffer size necessary
794+
status = ZwEnumerateValueKey(h, index, KeyValueFullInformation,
795+
NULL, 0, &length);
796+
797+
if ((status != STATUS_BUFFER_TOO_SMALL) &&
798+
(status != STATUS_BUFFER_OVERFLOW))
799+
break; // Something is wrong - or we finished
800+
801+
// Allocate space to hold
802+
regBuffer = (PKEY_VALUE_FULL_INFORMATION)ExAllocatePoolWithTag(
803+
NonPagedPoolNx, length, 'zfsr');
804+
805+
if (regBuffer == NULL)
806+
break;
807+
808+
status = ZwEnumerateValueKey(h, index, KeyValueFullInformation,
809+
regBuffer, length, &length);
810+
if (!NT_SUCCESS(status)) {
811+
break;
812+
}
813+
// Convert name to straight ascii so we compare with kstat
814+
ULONG outlen = 0;
815+
char keyname[KSTAT_STRLEN + 1] = { 0 };
816+
status = RtlUnicodeToUTF8N(keyname, KSTAT_STRLEN, &outlen,
817+
regBuffer->Name, regBuffer->NameLength);
818+
819+
// Conversion failed? move along..
820+
if (status != STATUS_SUCCESS && status
821+
!= STATUS_SOME_NOT_MAPPED)
822+
break;
823+
824+
// Output string is only null terminated if input is,
825+
// so do so now.
826+
keyname[outlen] = 0;
827+
if (strcasecmp("zfs_prealloc_percent", keyname) == 0) {
828+
if (regBuffer->Type != REG_DWORD ||
829+
regBuffer->DataLength != sizeof (uint32_t)) {
830+
dprintf("%s: registry '%s' did not match. "
831+
"Type needs to be REG_QWORD. (8 bytes)\n",
832+
__func__, keyname);
833+
} else {
834+
newvalue = *(uint32_t *)((uint8_t *)regBuffer
835+
+ regBuffer->DataOffset);
836+
dprintf("%s: zfs_prealloc_percent is set to:"
837+
" %llu\n", __func__, newvalue);
838+
}
839+
break;
840+
}
841+
ExFreePool(regBuffer);
842+
regBuffer = NULL;
843+
}
844+
845+
if (regBuffer)
846+
ExFreePool(regBuffer);
847+
848+
ZwClose(h);
849+
return (newvalue);
850+
}

module/os/windows/zfs/arc_os.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,7 @@ arc_kstat_update_windows(kstat_t *ksp, int rw)
696696
zfs_arc_average_blocksize =
697697
ks->arc_zfs_arc_average_blocksize.value.ui64;
698698
zvol_threads = ks->zvol_io_threads.value.ui32;
699-
zfs_abd_prealloc_percent = ks->zfs_abd_prealloc_percent.value.ui32;
699+
zfs_prealloc_percent = ks->zfs_prealloc_percent.value.ui32;
700700

701701
#ifdef _KERNEL
702702
if (ks->zfs_total_memory_limit.value.ui64 > total_memory &&
@@ -732,7 +732,7 @@ arc_kstat_update_windows(kstat_t *ksp, int rw)
732732
ks->arc_zfs_arc_average_blocksize.value.ui64 =
733733
zfs_arc_average_blocksize;
734734
ks->zvol_io_threads.value.ui32 = zvol_threads;
735-
ks->zfs_abd_prealloc_percent.value.ui32 = zfs_abd_prealloc_percent;
735+
ks->zfs_prealloc_percent.value.ui32 = zfs_prealloc_percent;
736736

737737
#ifdef _KERNEL
738738
ks->zfs_total_memory_limit.value.ui64 = total_memory;

module/os/windows/zfs/zfs_kstat_windows.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ windows_kstat_t windows_kstat = {
174174
{ "zfs_removal_suspend_progress", KSTAT_DATA_INT32 },
175175
{ "cpu_avx_supported", KSTAT_DATA_UINT32 },
176176
{ "zvol_io_threads", KSTAT_DATA_UINT32 },
177-
{ "zfs_abd_prealloc_percent", KSTAT_DATA_UINT32 },
177+
{ "zfs_prealloc_percent", KSTAT_DATA_UINT32 },
178178
};
179179

180180

@@ -384,8 +384,8 @@ windows_kstat_update(kstat_t *ksp, int rw)
384384
ks->zfs_removal_suspend_progress.value.i32;
385385
cpu_avx_supported =
386386
ks->cpu_avx_supported.value.ui32;
387-
zfs_abd_prealloc_percent =
388-
ks->zfs_abd_prealloc_percent.value.ui32;
387+
zfs_prealloc_percent =
388+
ks->zfs_prealloc_percent.value.ui32;
389389
} else {
390390

391391
/* kstat READ */
@@ -576,8 +576,8 @@ windows_kstat_update(kstat_t *ksp, int rw)
576576
cpu_avx_supported;
577577
ks->zvol_io_threads.value.ui32 =
578578
zvol_threads;
579-
ks->zfs_abd_prealloc_percent.value.ui32 =
580-
zfs_abd_prealloc_percent;
579+
ks->zfs_prealloc_percent.value.ui32 =
580+
zfs_prealloc_percent;
581581
}
582582
arc_kstat_update_windows(ksp, rw);
583583
return (0);

module/os/windows/zfs/zvol_os.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ unsigned int zvol_request_sync = 0;
4646
unsigned int zvol_prefetch_bytes = (128 * 1024);
4747
unsigned long zvol_max_discard_blocks = 16384;
4848
int zvol_threads = 0;
49-
int zfs_abd_prealloc_percent = 10;
49+
int zfs_prealloc_percent = 0;
5050

5151
taskq_t *zvol_taskq;
5252

0 commit comments

Comments
 (0)