]> git.saurik.com Git - apple/xnu.git/blame - tests/memorystatus_zone_test.c
xnu-4903.241.1.tar.gz
[apple/xnu.git] / tests / memorystatus_zone_test.c
CommitLineData
5ba3f43e
A
1#include <stdio.h>
2#include <mach/mach_vm.h>
3#include <mach/mach_port.h>
4#include <mach/mach_host.h>
a39ff7e2 5#include <mach/mach_error.h>
5ba3f43e
A
6#include <mach-o/dyld.h>
7#include <sys/sysctl.h>
8#include <sys/kdebug.h>
9#include <sys/mman.h>
10#include <sys/kern_memorystatus.h>
11#include <ktrace/session.h>
12#include <dispatch/private.h>
13
14#ifdef T_NAMESPACE
15#undef T_NAMESPACE
16#endif
17#include <darwintest.h>
18#include <darwintest_utils.h>
19
20T_GLOBAL_META(
21 T_META_NAMESPACE("xnu.vm"),
22 T_META_CHECK_LEAKS(false)
23);
24
a39ff7e2 25#define TIMEOUT_SECS 1500
5ba3f43e
A
26
27#if TARGET_OS_EMBEDDED
a39ff7e2
A
28#define ALLOCATION_SIZE_VM_REGION (16*1024) /* 16 KB */
29#define ALLOCATION_SIZE_VM_OBJECT ALLOCATION_SIZE_VM_REGION
5ba3f43e 30#else
a39ff7e2
A
31#define ALLOCATION_SIZE_VM_REGION (1024*1024*100) /* 100 MB */
32#define ALLOCATION_SIZE_VM_OBJECT (16*1024) /* 16 KB */
5ba3f43e 33#endif
a39ff7e2 34#define MAX_CHILD_PROCS 100
5ba3f43e 35
a39ff7e2 36#define ZONEMAP_JETSAM_LIMIT_SYSCTL "kern.zone_map_jetsam_limit=60"
5ba3f43e 37
a39ff7e2
A
38#define VME_ZONE_TEST_OPT "allocate_vm_regions"
39#define VM_OBJECTS_ZONE_TEST_OPT "allocate_vm_objects"
40#define GENERIC_ZONE_TEST_OPT "allocate_from_generic_zone"
5ba3f43e 41
a39ff7e2
A
42#define VME_ZONE "VM map entries"
43#define VMOBJECTS_ZONE "vm objects"
44#define VMENTRY_TO_VMOBJECT_COMPARISON_RATIO 98
45
46#define VM_TAG1 100
47#define VM_TAG2 101
5ba3f43e
A
48
49enum {
50 VME_ZONE_TEST = 0,
51 VM_OBJECTS_ZONE_TEST,
52 GENERIC_ZONE_TEST,
53};
54
a39ff7e2
A
55typedef struct test_config_struct {
56 int test_index;
57 int num_zones;
58 const char *helper_func;
59 mach_zone_name_array_t zone_names;
60} test_config_struct;
61
62static test_config_struct current_test;
5ba3f43e
A
63static int num_children = 0;
64static bool test_ending = false;
a39ff7e2
A
65static bool within_dispatch_signal_handler = false;
66static bool within_dispatch_timer_handler = false;
5ba3f43e 67static dispatch_source_t ds_signal = NULL;
a39ff7e2 68static dispatch_source_t ds_timer = NULL;
5ba3f43e
A
69static ktrace_session_t session = NULL;
70
a39ff7e2
A
71static mach_zone_info_array_t zone_info_array = NULL;
72static mach_zone_name_t largest_zone_name;
73static mach_zone_info_t largest_zone_info;
74
5ba3f43e
A
75static char testpath[PATH_MAX];
76static pid_t child_pids[MAX_CHILD_PROCS];
77static pthread_mutex_t test_ending_mtx;
78
79static void allocate_vm_regions(void);
80static void allocate_vm_objects(void);
81static void allocate_from_generic_zone(void);
82static void cleanup_and_end_test(void);
83static void setup_ktrace_session(void);
84static void spawn_child_process(void);
a39ff7e2
A
85static void run_test(void);
86static bool verify_generic_jetsam_criteria(void);
87static bool vme_zone_compares_to_vm_objects(void);
88static void print_zone_map_size(void);
89static void query_zone_info(void);
90static void print_zone_info(mach_zone_name_t *zn, mach_zone_info_t *zi);
5ba3f43e
A
91
92extern void mach_zone_force_gc(host_t host);
a39ff7e2
A
93extern kern_return_t mach_zone_info_for_largest_zone(
94 host_priv_t host,
95 mach_zone_name_t *name,
96 mach_zone_info_t *info
97);
5ba3f43e
A
98
99static void allocate_vm_regions(void)
100{
101 uint64_t alloc_size = ALLOCATION_SIZE_VM_REGION, i = 0;
102
103 printf("[%d] Allocating VM regions, each of size %lld KB\n", getpid(), (alloc_size>>10));
104 for (i = 0; ; i++) {
105 mach_vm_address_t addr = (mach_vm_address_t)NULL;
106
107 /* Alternate VM tags between consecutive regions to prevent coalescing */
108 int flags = VM_MAKE_TAG((i % 2)? VM_TAG1: VM_TAG2) | VM_FLAGS_ANYWHERE;
109
110 if ((mach_vm_allocate(mach_task_self(), &addr, (mach_vm_size_t)alloc_size, flags)) != KERN_SUCCESS) {
111 break;
112 }
113 }
114 printf("[%d] Number of allocations: %lld\n", getpid(), i);
115
116 /* Signal to the parent that we're done allocating */
117 kill(getppid(), SIGUSR1);
118
119 while (1) {
120 pause();
121 }
122}
123
124static void allocate_vm_objects(void)
125{
126 uint64_t alloc_size = ALLOCATION_SIZE_VM_OBJECT, i = 0;
127
128 printf("[%d] Allocating VM regions, each of size %lld KB, each backed by a VM object\n", getpid(), (alloc_size>>10));
129 for (i = 0; ; i++) {
130 mach_vm_address_t addr = (mach_vm_address_t)NULL;
131
132 /* Alternate VM tags between consecutive regions to prevent coalescing */
133 int flags = VM_MAKE_TAG((i % 2)? VM_TAG1: VM_TAG2) | VM_FLAGS_ANYWHERE;
134
135 if ((mach_vm_allocate(mach_task_self(), &addr, (mach_vm_size_t)alloc_size, flags)) != KERN_SUCCESS) {
136 break;
137 }
138 /* Touch the region so the VM object can actually be created */
139 *((int *)addr) = 0;
140 /* OK to free this page. Keeps us from holding a lot of dirty pages */
141 madvise((void *)addr, (size_t)alloc_size, MADV_FREE);
142 }
143 printf("[%d] Number of allocations: %lld\n", getpid(), i);
144
145 /* Signal to the parent that we're done allocating */
146 kill(getppid(), SIGUSR1);
147
148 while (1) {
149 pause();
150 }
151}
152
153static void allocate_from_generic_zone(void)
154{
155 uint64_t i = 0;
156
157 printf("[%d] Allocating mach_ports\n", getpid());
158 for (i = 0; ; i++) {
159 mach_port_t port;
160
161 if ((mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port)) != KERN_SUCCESS) {
162 break;
163 }
164 }
165 printf("[%d] Number of allocations: %lld\n", getpid(), i);
166
167 /* Signal to the parent that we're done allocating */
168 kill(getppid(), SIGUSR1);
169
170 while (1) {
171 pause();
172 }
173}
174
a39ff7e2
A
175static void print_zone_info(mach_zone_name_t *zn, mach_zone_info_t *zi)
176{
177 T_LOG("ZONE NAME: %-35sSIZE: %-25lluELEMENTS: %llu",
178 zn->mzn_name, zi->mzi_cur_size, zi->mzi_count);
179}
180
181static void query_zone_info(void)
182{
183 int i;
184 kern_return_t kr;
185 static uint64_t num_calls = 0;
186
187 for (i = 0; i < current_test.num_zones; i++) {
188 kr = mach_zone_info_for_zone(mach_host_self(), current_test.zone_names[i], &(zone_info_array[i]));
189 T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_zone_info_for_zone(%s) returned %d [%s]", current_test.zone_names[i].mzn_name, kr, mach_error_string(kr));
190 }
191 kr = mach_zone_info_for_largest_zone(mach_host_self(), &largest_zone_name, &largest_zone_info);
192 T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "mach_zone_info_for_largest_zone returned %d [%s]", kr, mach_error_string(kr));
193
194 num_calls++;
195 if (num_calls % 10 != 0) {
196 return;
197 }
198
199 /* Print out size and element count for zones relevant to the test */
200 for (i = 0; i < current_test.num_zones; i++) {
201 print_zone_info(&(current_test.zone_names[i]), &(zone_info_array[i]));
202 }
203}
204
205static bool vme_zone_compares_to_vm_objects(void)
206{
207 int i;
208 uint64_t vm_object_element_count = 0, vm_map_entry_element_count = 0;
209
210 T_LOG("Comparing element counts of \"VM map entries\" and \"vm objects\" zones");
211 for (i = 0; i < current_test.num_zones; i++) {
212 if (!strcmp(current_test.zone_names[i].mzn_name, VME_ZONE)) {
213 vm_map_entry_element_count = zone_info_array[i].mzi_count;
214 } else if (!strcmp(current_test.zone_names[i].mzn_name, VMOBJECTS_ZONE)) {
215 vm_object_element_count = zone_info_array[i].mzi_count;
216 }
217 print_zone_info(&(current_test.zone_names[i]), &(zone_info_array[i]));
218 }
219
220 T_LOG("# VM map entries as percentage of # vm objects = %llu", (vm_map_entry_element_count * 100)/ vm_object_element_count);
221 if (vm_map_entry_element_count >= ((vm_object_element_count * VMENTRY_TO_VMOBJECT_COMPARISON_RATIO) / 100)) {
222 T_LOG("Number of VM map entries is comparable to vm objects\n\n");
223 return true;
224 }
225 T_LOG("Number of VM map entries is NOT comparable to vm objects\n\n");
226 return false;
227}
228
229static bool verify_generic_jetsam_criteria(void)
230{
231 T_LOG("Largest zone info");
232 print_zone_info(&largest_zone_name, &largest_zone_info);
233
234 /* If VM map entries is not the largest zone */
235 if (strcmp(largest_zone_name.mzn_name, VME_ZONE)) {
236 /* If vm objects is the largest zone and the VM map entries zone had comparable # of elements, return false */
237 if (!strcmp(largest_zone_name.mzn_name, VMOBJECTS_ZONE) && vme_zone_compares_to_vm_objects()) {
238 return false;
239 }
240 return true;
241 }
242 return false;
243}
244
5ba3f43e
A
245static void cleanup_and_end_test(void)
246{
247 int i;
248
249 /*
250 * The atend handler executes on a different dispatch queue.
251 * We want to do the cleanup only once.
252 */
253 pthread_mutex_lock(&test_ending_mtx);
254 if (test_ending) {
255 pthread_mutex_unlock(&test_ending_mtx);
256 return;
257 }
258 test_ending = true;
259 pthread_mutex_unlock(&test_ending_mtx);
260
261 T_LOG("Number of processes spawned: %d", num_children);
262 T_LOG("Cleaning up...");
263
a39ff7e2
A
264 /* Disable the timer that queries and prints zone info periodically */
265 if (ds_timer != NULL && !within_dispatch_timer_handler) {
266 dispatch_source_cancel(ds_timer);
267 }
268
5ba3f43e 269 /* Disable signal handler that spawns child processes, only if we're not in the event handler's context */
a39ff7e2 270 if (ds_signal != NULL && !within_dispatch_signal_handler) {
5ba3f43e
A
271 dispatch_source_cancel_and_wait(ds_signal);
272 }
273
274 /* Kill all the child processes that were spawned */
275 for (i = 0; i < num_children; i++) {
276 kill(child_pids[i], SIGKILL);
d9a64523
A
277 /*
278 * Sleep between kills to avoid hogging the VM map entries zone lock (on the task_terminate path).
279 * Without this we were seeing hw_lock_bit timeouts in BATS.
280 */
281 sleep(1);
5ba3f43e
A
282 }
283 for (i = 0; i < num_children; i++) {
284 int status = 0;
285 if (waitpid(child_pids[i], &status, 0) < 0) {
286 T_LOG("waitpid returned status %d", status);
287 }
288 }
289 sleep(1);
290
291 /* Force zone_gc before starting test for another zone or exiting */
292 mach_zone_force_gc(mach_host_self());
293
294 /* End ktrace session */
295 if (session != NULL) {
296 ktrace_end(session, 1);
297 }
a39ff7e2
A
298
299 for (i = 0; i < current_test.num_zones; i++) {
300 print_zone_info(&(current_test.zone_names[i]), &(zone_info_array[i]));
301 }
5ba3f43e
A
302}
303
304static void setup_ktrace_session(void)
305{
306 int ret = 0;
307
308 T_LOG("Setting up ktrace session...");
309 session = ktrace_session_create();
310 T_QUIET; T_ASSERT_NOTNULL(session, "ktrace_session_create");
311
a39ff7e2
A
312 ktrace_set_interactive(session);
313
5ba3f43e
A
314 ktrace_set_completion_handler(session, ^{
315 ktrace_session_destroy(session);
316 T_END;
317 });
318
319 /* Listen for memorystatus_do_kill trace events */
320 ret = ktrace_events_single(session, (BSDDBG_CODE(DBG_BSD_MEMSTAT, BSD_MEMSTAT_DO_KILL)) | DBG_FUNC_END, ^(ktrace_event_t event) {
321 int i;
322 bool received_jetsam_event = false;
323
324 /* We don't care about jetsams for any other reason except zone-map-exhaustion */
325 if (event->arg2 == kMemorystatusKilledZoneMapExhaustion) {
a39ff7e2
A
326 cleanup_and_end_test();
327 T_LOG("[memorystatus_do_kill] jetsam reason: zone-map-exhaustion, pid: %lu\n\n", event->arg1);
328 if (current_test.test_index == VME_ZONE_TEST || current_test.test_index == VM_OBJECTS_ZONE_TEST) {
5ba3f43e
A
329 /*
330 * For the VM map entries zone we try to kill the leaking process.
331 * Verify that we jetsammed one of the processes we spawned.
a39ff7e2
A
332 *
333 * For the vm objects zone we pick the leaking process via the VM map entries
334 * zone, if the number of vm objects and VM map entries are comparable.
335 * The test simulates this scenario, we should see a targeted jetsam for the
336 * vm objects zone too.
5ba3f43e
A
337 */
338 for (i = 0; i < num_children; i++) {
339 if (child_pids[i] == (pid_t)event->arg1) {
340 received_jetsam_event = true;
341 break;
342 }
343 }
a39ff7e2
A
344 /*
345 * If we didn't see a targeted jetsam, verify that the largest zone actually
346 * fulfilled the criteria for generic jetsams.
347 */
348 if (!received_jetsam_event && verify_generic_jetsam_criteria()) {
349 received_jetsam_event = true;
350 }
5ba3f43e
A
351 } else {
352 received_jetsam_event = true;
353 }
354
a39ff7e2 355 T_ASSERT_TRUE(received_jetsam_event, "Received zone-map-exhaustion jetsam event as expected");
5ba3f43e
A
356 }
357 });
358 T_QUIET; T_ASSERT_POSIX_ZERO(ret, "ktrace_events_single");
359
360 ret = ktrace_start(session, dispatch_get_main_queue());
361 T_QUIET; T_ASSERT_POSIX_ZERO(ret, "ktrace_start");
362}
363
a39ff7e2
A
364static void print_zone_map_size(void)
365{
366 int ret;
367 uint64_t zstats[2];
368 size_t zstats_size = sizeof(zstats);
369
370 ret = sysctlbyname("kern.zone_map_size_and_capacity", &zstats, &zstats_size, NULL, 0);
371 T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "sysctl kern.zone_map_size_and_capacity failed");
372
373 T_LOG("Zone map capacity: %-30lldZone map size: %lld [%lld%% full]", zstats[1], zstats[0], (zstats[0] * 100)/zstats[1]);
374}
375
5ba3f43e
A
376static void spawn_child_process(void)
377{
378 pid_t pid = -1;
a39ff7e2 379 char helper_func[50];
5ba3f43e 380 char *launch_tool_args[4];
5ba3f43e
A
381
382 T_QUIET; T_ASSERT_LT(num_children, MAX_CHILD_PROCS, "Spawned %d children. Timing out...", MAX_CHILD_PROCS);
383
a39ff7e2 384 strlcpy(helper_func, current_test.helper_func, sizeof(helper_func));
5ba3f43e
A
385 launch_tool_args[0] = testpath;
386 launch_tool_args[1] = "-n";
a39ff7e2 387 launch_tool_args[2] = helper_func;
5ba3f43e
A
388 launch_tool_args[3] = NULL;
389
5ba3f43e
A
390 /* Spawn the child process */
391 int rc = dt_launch_tool(&pid, launch_tool_args, false, NULL, NULL);
392 if (rc != 0) {
393 T_LOG("dt_launch tool returned %d with error code %d", rc, errno);
394 }
395 T_QUIET; T_ASSERT_POSIX_SUCCESS(pid, "dt_launch_tool");
396
397 child_pids[num_children++] = pid;
5ba3f43e
A
398}
399
a39ff7e2 400static void run_test(void)
5ba3f43e 401{
a39ff7e2
A
402 uint64_t mem;
403 uint32_t testpath_buf_size, pages;
404 int ret, dev, pgsz;
405 size_t sysctl_size;
5ba3f43e
A
406
407 T_ATEND(cleanup_and_end_test);
408 T_SETUPBEGIN;
409
a39ff7e2
A
410 dev = 0;
411 sysctl_size = sizeof(dev);
412 ret = sysctlbyname("kern.development", &dev, &sysctl_size, NULL, 0);
5ba3f43e
A
413 T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "sysctl kern.development failed");
414 if (dev == 0) {
415 T_SKIP("Skipping test on release kernel");
416 }
417
a39ff7e2 418 testpath_buf_size = sizeof(testpath);
5ba3f43e
A
419 ret = _NSGetExecutablePath(testpath, &testpath_buf_size);
420 T_QUIET; T_ASSERT_POSIX_ZERO(ret, "_NSGetExecutablePath");
421 T_LOG("Executable path: %s", testpath);
422
a39ff7e2
A
423 sysctl_size = sizeof(mem);
424 ret = sysctlbyname("hw.memsize", &mem, &sysctl_size, NULL, 0);
425 T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "sysctl hw.memsize failed");
426 T_LOG("hw.memsize: %llu", mem);
427
428 sysctl_size = sizeof(pgsz);
429 ret = sysctlbyname("vm.pagesize", &pgsz, &sysctl_size, NULL, 0);
430 T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "sysctl vm.pagesize failed");
431 T_LOG("vm.pagesize: %d", pgsz);
432
433 sysctl_size = sizeof(pages);
434 ret = sysctlbyname("vm.pages", &pages, &sysctl_size, NULL, 0);
435 T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "sysctl vm.pages failed");
436 T_LOG("vm.pages: %d", pages);
437
438 zone_info_array = (mach_zone_info_array_t) calloc((unsigned long)current_test.num_zones, sizeof *zone_info_array);
439
440 print_zone_map_size();
441
5ba3f43e
A
442 /*
443 * If the timeout specified by T_META_TIMEOUT is hit, the atend handler does not get called.
444 * So we're queueing a dispatch block to fire after TIMEOUT_SECS seconds, so we can exit cleanly.
445 */
446 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, TIMEOUT_SECS * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
447 T_ASSERT_FAIL("Timed out after %d seconds", TIMEOUT_SECS);
448 });
449
450 /*
451 * Create a dispatch source for the signal SIGUSR1. When a child is done allocating zone memory, it
452 * sends SIGUSR1 to the parent. Only then does the parent spawn another child. This prevents us from
453 * spawning many children at once and creating a lot of memory pressure.
454 */
455 signal(SIGUSR1, SIG_IGN);
456 ds_signal = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, SIGUSR1, 0, dispatch_get_main_queue());
a39ff7e2 457 T_QUIET; T_ASSERT_NOTNULL(ds_signal, "dispatch_source_create: signal");
5ba3f43e
A
458
459 dispatch_source_set_event_handler(ds_signal, ^{
a39ff7e2
A
460 within_dispatch_signal_handler = true;
461 print_zone_map_size();
462
5ba3f43e
A
463 /* Wait a few seconds before spawning another child. Keeps us from allocating too aggressively */
464 sleep(5);
465 spawn_child_process();
a39ff7e2 466 within_dispatch_signal_handler = false;
5ba3f43e
A
467 });
468 dispatch_activate(ds_signal);
469
a39ff7e2
A
470 /* Timer to query jetsam-relevant zone info every second. Print it every 10 seconds. */
471 ds_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_queue_create("timer_queue", NULL));
472 T_QUIET; T_ASSERT_NOTNULL(ds_timer, "dispatch_source_create: timer");
473 dispatch_source_set_timer(ds_timer, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC), NSEC_PER_SEC, 0);
474
475 dispatch_source_set_event_handler(ds_timer, ^{
476 within_dispatch_timer_handler = true;
477 query_zone_info();
478 within_dispatch_timer_handler = false;
479 });
480 dispatch_activate(ds_timer);
481
5ba3f43e
A
482 /* Set up a ktrace session to listen for jetsam events */
483 setup_ktrace_session();
484
485 T_SETUPEND;
486
487 /* Spawn the first child process */
488 T_LOG("Spawning child processes to allocate zone memory...\n\n");
489 spawn_child_process();
490
491 dispatch_main();
492}
493
a39ff7e2 494static void move_to_idle_band(void)
5ba3f43e
A
495{
496 memorystatus_priority_properties_t props;
497
498 /*
499 * We want to move the processes we spawn into the idle band, so that jetsam can target them first.
500 * This prevents other important BATS tasks from getting killed, specially in LTE where we have very few
501 * processes running.
a39ff7e2
A
502 *
503 * This is only needed for tests which (are likely to) lead us down the generic jetsam path.
5ba3f43e
A
504 */
505 props.priority = JETSAM_PRIORITY_IDLE;
506 props.user_data = 0;
507
508 if (memorystatus_control(MEMORYSTATUS_CMD_SET_PRIORITY_PROPERTIES, getpid(), 0, &props, sizeof(props))) {
509 printf("memorystatus call to change jetsam priority failed\n");
510 exit(-1);
511 }
a39ff7e2
A
512}
513
514T_HELPER_DECL(allocate_vm_regions, "allocates VM regions")
515{
516 allocate_vm_regions();
517}
518
519T_HELPER_DECL(allocate_vm_objects, "allocates VM objects and VM regions")
520{
521 move_to_idle_band();
522 allocate_vm_objects();
523}
5ba3f43e 524
a39ff7e2
A
525T_HELPER_DECL(allocate_from_generic_zone, "allocates from a generic zone")
526{
527 move_to_idle_band();
5ba3f43e
A
528 allocate_from_generic_zone();
529}
530
531/*
532 * T_META_SYSCTL_INT(ZONEMAP_JETSAM_LIMIT_SYSCTL) changes the zone_map_jetsam_limit to a
533 * lower value, so that the test can complete faster.
534 * The test allocates zone memory pretty aggressively which can cause the system to panic
535 * if the jetsam limit is quite high; a lower value keeps us from panicking.
536 */
537T_DECL( memorystatus_vme_zone_test,
538 "allocates elements from the VM map entries zone, verifies zone-map-exhaustion jetsams",
539 T_META_ASROOT(true),
540 T_META_TIMEOUT(1800),
541/* T_META_LTEPHASE(LTE_POSTINIT),
542 */
543 T_META_SYSCTL_INT(ZONEMAP_JETSAM_LIMIT_SYSCTL))
544{
a39ff7e2
A
545 current_test = (test_config_struct) {
546 .test_index = VME_ZONE_TEST,
547 .helper_func = VME_ZONE_TEST_OPT,
548 .num_zones = 1,
549 .zone_names = (mach_zone_name_t []){
550 { .mzn_name = VME_ZONE }
551 }
552 };
553 run_test();
5ba3f43e
A
554}
555
556T_DECL( memorystatus_vm_objects_zone_test,
557 "allocates elements from the VM objects and the VM map entries zones, verifies zone-map-exhaustion jetsams",
558 T_META_ASROOT(true),
559 T_META_TIMEOUT(1800),
560/* T_META_LTEPHASE(LTE_POSTINIT),
561 */
562 T_META_SYSCTL_INT(ZONEMAP_JETSAM_LIMIT_SYSCTL))
563{
a39ff7e2
A
564 current_test = (test_config_struct) {
565 .test_index = VM_OBJECTS_ZONE_TEST,
566 .helper_func = VM_OBJECTS_ZONE_TEST_OPT,
567 .num_zones = 2,
568 .zone_names = (mach_zone_name_t []){
569 { .mzn_name = VME_ZONE },
570 { .mzn_name = VMOBJECTS_ZONE}
571 }
572 };
573 run_test();
5ba3f43e
A
574}
575
576T_DECL( memorystatus_generic_zone_test,
577 "allocates elements from a zone that doesn't have an optimized jetsam path, verifies zone-map-exhaustion jetsams",
578 T_META_ASROOT(true),
579 T_META_TIMEOUT(1800),
580/* T_META_LTEPHASE(LTE_POSTINIT),
581 */
582 T_META_SYSCTL_INT(ZONEMAP_JETSAM_LIMIT_SYSCTL))
583{
a39ff7e2
A
584 current_test = (test_config_struct) {
585 .test_index = GENERIC_ZONE_TEST,
586 .helper_func = GENERIC_ZONE_TEST_OPT,
587 .num_zones = 0,
588 .zone_names = NULL
589 };
590 run_test();
5ba3f43e 591}