3 #include <darwintest.h>
4 #include <darwintest_utils.h>
6 #include <mach/mach_error.h>
7 #include <mach/mach_init.h>
8 #include <mach/mach_port.h>
9 #include <mach/mach_vm.h>
10 #include <mach/task.h>
11 #include <mach/task_info.h>
12 #include <mach/vm_map.h>
16 #include <Kernel/kern/ledger.h>
17 extern int ledger(int cmd
, caddr_t arg1
, caddr_t arg2
, caddr_t arg3
);
19 #if ENTITLED && defined(__arm64__)
20 #define LEGACY_FOOTPRINT 1
21 #else /* ENTITLED && __arm64__ */
22 #define LEGACY_FOOTPRINT 0
23 #endif /* ENTITLED && __arm64__ */
25 #define MEM_SIZE (100 * 1024 * 1024) /* 100 MB */
27 static int64_t ledger_count
= -1;
28 static int footprint_index
= -1;
29 static int pagetable_index
= -1;
30 static struct ledger_entry_info
*lei
= NULL
;
35 static int ledger_inited
= 0;
36 struct ledger_info li
;
37 struct ledger_template_info
*templateInfo
;
49 T_ASSERT_EQ(ledger(LEDGER_INFO
,
50 (caddr_t
)(uintptr_t)getpid(),
54 "ledger(LEDGER_INFO)");
56 templateCnt
= li
.li_entries
;
57 templateInfo
= malloc((size_t)li
.li_entries
* sizeof(struct ledger_template_info
));
60 T_ASSERT_NE(templateInfo
, NULL
, "malloc()");
62 ledger_count
= li
.li_entries
;
67 T_ASSERT_GE(ledger(LEDGER_TEMPLATE_INFO
,
68 (caddr_t
)templateInfo
,
69 (caddr_t
)&templateCnt
,
72 "ledger(LEDGER_TEMPLATE_INFO)");
73 for (i
= 0; i
< templateCnt
; i
++) {
74 if (!strncmp(templateInfo
[i
].lti_name
,
76 strlen("phys_footprint"))) {
78 } else if (!strncmp(templateInfo
[i
].lti_name
,
80 strlen("page_table"))) {
86 lei
= (struct ledger_entry_info
*)
87 malloc((size_t)ledger_count
* sizeof(*lei
));
90 T_ASSERT_NE(lei
, NULL
, "malloc(ledger_entry_info)");
93 T_ASSERT_NE(footprint_index
, -1, "no footprint_index");
95 T_ASSERT_NE(pagetable_index
, -1, "no pagetable_index");
102 uint64_t *phys_footprint
,
103 uint64_t *page_table
)
107 count
= ledger_count
;
110 T_ASSERT_GE(ledger(LEDGER_ENTRY_INFO
,
111 (caddr_t
)(uintptr_t)getpid(),
115 "ledger(LEDGER_ENTRY_INFO)");
117 T_ASSERT_GT(count
, (int64_t)footprint_index
, "no entry for footprint");
119 T_ASSERT_GT(count
, (int64_t)pagetable_index
, "no entry for pagetable");
120 if (phys_footprint
) {
121 *phys_footprint
= (uint64_t)(lei
[footprint_index
].lei_balance
);
124 *page_table
= (uint64_t)(lei
[pagetable_index
].lei_balance
);
128 static mach_vm_address_t
130 mach_vm_size_t vm_size
)
133 mach_vm_address_t vm_addr
;
134 unsigned char BigBufOnStack
[100 * 1024];
135 uint64_t footprint
, page_table
;
137 /* make sure ledgers are ready to be queried */
143 * Touch a few pages ahead on the stack, to make
144 * sure we don't see a footprint increase due to
145 * an extra stack page later.
147 memset(BigBufOnStack
, 0xb, sizeof(BigBufOnStack
));
149 T_EXPECT_EQ(BigBufOnStack
[0], 0xb,
150 "BigBufOnStack[0] == 0x%x",
153 T_EXPECT_EQ(BigBufOnStack
[sizeof(BigBufOnStack
) - 1], 0xb,
154 "BigBufOnStack[%lu] == 0x%x",
155 sizeof(BigBufOnStack
),
156 BigBufOnStack
[sizeof(BigBufOnStack
) - 1]);
159 * Pre-allocate, touch and then release the same amount
160 * of memory we'll be allocating later during the test,
161 * to account for any memory overhead (page tables, global
165 kr
= mach_vm_allocate(mach_task_self(),
170 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_allocate(%lld) error 0x%x (%s)",
171 vm_size
, kr
, mach_error_string(kr
));
172 memset((char *)(uintptr_t)vm_addr
, 'p', (size_t)vm_size
);
173 kr
= mach_vm_deallocate(mach_task_self(),
177 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_deallocate() error 0x%x (%s)",
178 kr
, mach_error_string(kr
));
181 * Exercise the ledger code to make sure it's ready to run
182 * without any extra memory overhead later.
184 get_ledger_info(&footprint
, &page_table
);
189 * Return the start of the virtual range we pre-warmed, so that the
190 * test can check that it's using the same range.
195 T_DECL(legacy_phys_footprint_anonymous
,
196 "phys_footprint for anonymous memory",
197 T_META_NAMESPACE("xnu.vm"),
198 T_META_LTEPHASE(LTE_POSTINIT
))
200 uint64_t footprint_before
, pagetable_before
;
201 uint64_t footprint_after
, pagetable_after
;
202 uint64_t footprint_expected
;
204 mach_vm_address_t pre_vm_addr
, vm_addr
;
205 mach_vm_size_t vm_size
, dirty_size
;
207 /* pre-warm to account for page table expansion */
208 pre_vm_addr
= pre_warm(MEM_SIZE
);
210 /* allocating virtual memory... */
211 get_ledger_info(&footprint_before
, &pagetable_before
);
214 kr
= mach_vm_allocate(mach_task_self(), &vm_addr
, vm_size
,
217 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_allocate() error 0x%x (%s)",
218 kr
, mach_error_string(kr
));
220 T_EXPECT_EQ(vm_addr
, pre_vm_addr
, "pre-warm mishap");
221 /* ... should not change footprint */
222 get_ledger_info(&footprint_after
, &pagetable_after
);
223 footprint_expected
= footprint_before
;
224 footprint_expected
+= (pagetable_after
- pagetable_before
);
225 T_LOG("virtual allocation does not change phys_footprint");
226 T_EXPECT_EQ(footprint_after
, footprint_expected
,
227 "virtual allocation of %lld bytes: "
228 "footprint %lld -> %lld expected %lld delta %lld",
229 vm_size
, footprint_before
, footprint_after
,
230 footprint_expected
, footprint_after
- footprint_expected
);
232 /* touching memory... */
233 get_ledger_info(&footprint_before
, &pagetable_before
);
234 dirty_size
= vm_size
/ 2;
235 memset((char *)(uintptr_t)vm_addr
, 'x', (size_t)dirty_size
);
236 /* ... should increase footprint */
237 get_ledger_info(&footprint_after
, &pagetable_after
);
238 footprint_expected
= footprint_before
+ dirty_size
;
239 footprint_expected
+= (pagetable_after
- pagetable_before
);
240 T_LOG("modifying anonymous memory increases phys_footprint");
241 T_EXPECT_EQ(footprint_after
, footprint_expected
,
242 "touched %lld bytes: "
243 "footprint %lld -> %lld expected %lld delta %lld",
244 dirty_size
, footprint_before
, footprint_after
,
245 footprint_expected
, footprint_after
- footprint_expected
);
247 /* deallocating memory... */
248 get_ledger_info(&footprint_before
, &pagetable_before
);
249 kr
= mach_vm_deallocate(mach_task_self(), vm_addr
, vm_size
);
251 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_deallocate() error 0x%x (%s)",
252 kr
, mach_error_string(kr
));
253 /* ... should decrease footprint */
254 get_ledger_info(&footprint_after
, &pagetable_after
);
255 footprint_expected
= footprint_before
- dirty_size
;
256 footprint_expected
+= (pagetable_after
- pagetable_before
);
257 T_LOG("deallocating dirty anonymous memory decreases phys_footprint");
258 T_EXPECT_EQ(footprint_after
, footprint_expected
,
259 "deallocated %lld dirty bytes: "
260 "footprint %lld -> %lld expected %lld delta %lld",
261 dirty_size
, footprint_before
, footprint_after
,
262 footprint_expected
, footprint_after
- footprint_expected
);
265 #define TEMP_FILE_TEMPLATE "/tmp/phys_footprint_data.XXXXXXXX"
266 #define TEMP_FILE_SIZE (1 * 1024 * 1024)
268 T_DECL(legacy_phys_footprint_file
,
269 "phys_footprint for mapped file",
270 T_META_NAMESPACE("xnu.vm"),
271 T_META_LTEPHASE(LTE_POSTINIT
))
273 uint64_t footprint_before
, pagetable_before
;
274 uint64_t footprint_after
, pagetable_after
;
275 uint64_t footprint_expected
;
276 mach_vm_address_t pre_vm_addr
;
279 size_t map_size
, dirty_size
;
281 char tmp_file_name
[PATH_MAX
] = TEMP_FILE_TEMPLATE
;
286 buf_size
= TEMP_FILE_SIZE
;
288 T_ASSERT_NOTNULL(buf
= (char *)malloc(buf_size
),
289 "allocate %zu-byte buffer", buf_size
);
290 memset(buf
, 'f', buf_size
);
293 T_ASSERT_NOTNULL(mktemp(tmp_file_name
),
294 "create temporary file name");
297 T_ASSERT_GE(fd
= open(tmp_file_name
, O_CREAT
| O_RDWR
),
302 T_ASSERT_EQ(nbytes
= write(fd
, buf
, buf_size
),
304 "write %zu bytes", buf_size
);
308 /* pre-warm to account for page table expansion */
309 pre_vm_addr
= pre_warm(TEMP_FILE_SIZE
);
311 /* mapping a file does not impact footprint... */
312 get_ledger_info(&footprint_before
, &pagetable_before
);
313 map_size
= TEMP_FILE_SIZE
;
316 T_ASSERT_NOTNULL(map_addr
= (char *)mmap(NULL
, map_size
,
317 PROT_READ
| PROT_WRITE
,
318 MAP_FILE
| MAP_SHARED
, fd
, 0),
321 T_EXPECT_EQ((mach_vm_address_t
)map_addr
, pre_vm_addr
,
323 /* ... should not change footprint */
324 get_ledger_info(&footprint_after
, &pagetable_after
);
325 footprint_expected
= footprint_before
;
326 footprint_expected
+= (pagetable_after
- pagetable_before
);
327 T_LOG("mapping file does not change phys_footprint");
328 T_EXPECT_EQ(footprint_after
, footprint_expected
,
329 "mapping file with %zu bytes: "
330 "footprint %lld -> %lld expected %lld delta %lld",
331 map_size
, footprint_before
, footprint_after
,
332 footprint_expected
, footprint_after
- footprint_expected
);
334 /* touching file-backed memory... */
335 get_ledger_info(&footprint_before
, &pagetable_before
);
336 dirty_size
= map_size
/ 2;
337 memset(map_addr
, 'F', dirty_size
);
338 /* ... should not impact footprint */
339 get_ledger_info(&footprint_after
, &pagetable_after
);
340 footprint_expected
= footprint_before
;
341 footprint_expected
+= (pagetable_after
- pagetable_before
);
342 T_LOG("modifying file-backed memory does not impact phys_footprint");
343 T_EXPECT_EQ(footprint_after
, footprint_expected
,
344 "touched %zu bytes: "
345 "footprint %lld -> %lld expected %lld delta %lld",
346 dirty_size
, footprint_before
, footprint_after
,
347 footprint_expected
, footprint_after
- footprint_expected
);
349 /* deallocating file-backed memory... */
350 get_ledger_info(&footprint_before
, &pagetable_before
);
353 T_ASSERT_EQ(munmap(map_addr
, map_size
),
356 /* ... should not impact footprint */
357 get_ledger_info(&footprint_after
, &pagetable_after
);
358 footprint_expected
= footprint_before
;
359 footprint_expected
+= (pagetable_after
- pagetable_before
);
360 T_LOG("unmapping file-backed memory does not impact phys_footprint");
361 T_EXPECT_EQ(footprint_after
, footprint_expected
,
362 "unmapped %zu dirty bytes: "
363 "footprint %lld -> %lld expected %lld delta %lld",
364 dirty_size
, footprint_before
, footprint_after
,
365 footprint_expected
, footprint_after
- footprint_expected
);
368 T_DECL(legacy_phys_footprint_purgeable
,
369 "phys_footprint for purgeable memory",
370 T_META_NAMESPACE("xnu.vm"),
371 T_META_LTEPHASE(LTE_POSTINIT
))
373 uint64_t footprint_before
, pagetable_before
;
374 uint64_t footprint_after
, pagetable_after
;
375 uint64_t footprint_expected
;
377 mach_vm_address_t pre_vm_addr
, vm_addr
;
378 mach_vm_size_t vm_size
, dirty_size
;
381 /* pre-warm to account for page table expansion */
382 pre_vm_addr
= pre_warm(MEM_SIZE
);
384 /* allocating purgeable virtual memory... */
385 get_ledger_info(&footprint_before
, &pagetable_before
);
388 kr
= mach_vm_allocate(mach_task_self(), &vm_addr
, vm_size
,
389 VM_FLAGS_ANYWHERE
| VM_FLAGS_PURGABLE
);
391 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_allocate() error 0x%x (%s)",
392 kr
, mach_error_string(kr
));
394 T_EXPECT_EQ(vm_addr
, pre_vm_addr
, "pre-warm mishap");
395 /* ... should not change footprint */
396 get_ledger_info(&footprint_after
, &pagetable_after
);
397 footprint_expected
= footprint_before
;
398 footprint_expected
+= (pagetable_after
- pagetable_before
);
399 T_LOG("purgeable virtual allocation does not change phys_footprint");
400 T_EXPECT_EQ(footprint_after
, footprint_expected
,
401 "purgeable virtual allocation of %lld bytes: "
402 "footprint %lld -> %lld expected %lld delta %lld",
403 vm_size
, footprint_before
, footprint_after
,
404 footprint_expected
, footprint_after
- footprint_expected
);
406 /* touching memory... */
407 get_ledger_info(&footprint_before
, &pagetable_before
);
408 dirty_size
= vm_size
/ 2;
409 memset((char *)(uintptr_t)vm_addr
, 'x', (size_t)dirty_size
);
410 /* ... should increase footprint */
411 get_ledger_info(&footprint_after
, &pagetable_after
);
412 footprint_expected
= footprint_before
+ dirty_size
;
413 footprint_expected
+= (pagetable_after
- pagetable_before
);
414 T_LOG("modifying anonymous memory increases phys_footprint");
415 T_EXPECT_EQ(footprint_after
, footprint_expected
,
416 "touched %lld bytes: "
417 "footprint %lld -> %lld expected %lld delta %lld",
418 dirty_size
, footprint_before
, footprint_after
,
419 footprint_expected
, footprint_after
- footprint_expected
);
421 /* making it volatile... */
422 get_ledger_info(&footprint_before
, &pagetable_before
);
423 state
= VM_PURGABLE_VOLATILE
;
425 T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
427 VM_PURGABLE_SET_STATE
,
430 "vm_purgable_control(VOLATILE)");
432 T_ASSERT_EQ(state
, VM_PURGABLE_NONVOLATILE
,
433 "memory was non-volatile");
434 /* ... should decrease footprint */
435 get_ledger_info(&footprint_after
, &pagetable_after
);
436 footprint_expected
= footprint_before
- dirty_size
;
437 footprint_expected
+= (pagetable_after
- pagetable_before
);
438 T_LOG("making volatile decreases phys_footprint");
439 T_EXPECT_EQ(footprint_after
, footprint_expected
,
440 "made volatile %lld dirty bytes: "
441 "footprint %lld -> %lld expected %lld delta %lld",
442 dirty_size
, footprint_before
, footprint_after
,
443 footprint_expected
, footprint_after
- footprint_expected
);
445 /* making it non-volatile... */
446 get_ledger_info(&footprint_before
, &pagetable_before
);
447 state
= VM_PURGABLE_NONVOLATILE
;
449 T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
451 VM_PURGABLE_SET_STATE
,
454 "vm_purgable_control(NONVOLATILE)");
456 T_ASSERT_EQ(state
, VM_PURGABLE_VOLATILE
,
457 "memory was volatile");
458 /* ... should increase footprint */
459 get_ledger_info(&footprint_after
, &pagetable_after
);
460 footprint_expected
= footprint_before
+ dirty_size
;
461 footprint_expected
+= (pagetable_after
- pagetable_before
);
462 T_LOG("making non-volatile increases phys_footprint");
463 T_EXPECT_EQ(footprint_after
, footprint_expected
,
464 "made non-volatile %lld dirty bytes: "
465 "footprint %lld -> %lld expected %lld delta %lld",
466 dirty_size
, footprint_before
, footprint_after
,
467 footprint_expected
, footprint_after
- footprint_expected
);
469 /* deallocating memory... */
470 get_ledger_info(&footprint_before
, &pagetable_before
);
471 kr
= mach_vm_deallocate(mach_task_self(), vm_addr
, vm_size
);
473 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_deallocate() error 0x%x (%s)",
474 kr
, mach_error_string(kr
));
475 /* ... should decrease footprint */
476 get_ledger_info(&footprint_after
, &pagetable_after
);
477 footprint_expected
= footprint_before
- dirty_size
;
478 footprint_expected
+= (pagetable_after
- pagetable_before
);
479 T_LOG("deallocating memory decreases phys_footprint");
480 T_EXPECT_EQ(footprint_after
, footprint_expected
,
481 "deallocated %lld dirty bytes: "
482 "footprint %lld -> %lld expected %lld delta %lld",
483 dirty_size
, footprint_before
, footprint_after
,
484 footprint_expected
, footprint_after
- footprint_expected
);
487 T_DECL(legacy_phys_footprint_purgeable_ownership
,
488 "phys_footprint for owned purgeable memory",
489 T_META_NAMESPACE("xnu.vm"),
490 T_META_LTEPHASE(LTE_POSTINIT
))
492 uint64_t footprint_before
, pagetable_before
;
493 uint64_t footprint_after
, pagetable_after
;
494 uint64_t footprint_expected
;
496 mach_vm_address_t pre_vm_addr
, vm_addr
;
497 mach_vm_size_t vm_size
, dirty_size
, me_size
;
501 /* pre-warm to account for page table expansion */
502 pre_vm_addr
= pre_warm(MEM_SIZE
);
504 /* allocating purgeable virtual memory... */
505 get_ledger_info(&footprint_before
, &pagetable_before
);
508 kr
= mach_vm_allocate(mach_task_self(), &vm_addr
, vm_size
,
509 VM_FLAGS_ANYWHERE
| VM_FLAGS_PURGABLE
);
511 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_allocate() error 0x%x (%s)",
512 kr
, mach_error_string(kr
));
514 T_EXPECT_EQ(vm_addr
, pre_vm_addr
, "pre-warm mishap");
515 /* ... should not change footprint */
516 get_ledger_info(&footprint_after
, &pagetable_after
);
517 footprint_expected
= footprint_before
;
518 footprint_expected
+= (pagetable_after
- pagetable_before
);
519 T_LOG("purgeable virtual allocation does not change phys_footprint");
520 T_EXPECT_EQ(footprint_after
, footprint_expected
,
521 "purgeable virtual allocation of %lld bytes: "
522 "footprint %lld -> %lld expected %lld delta %lld",
523 vm_size
, footprint_before
, footprint_after
,
524 footprint_expected
, footprint_after
- footprint_expected
);
526 /* touching memory... */
527 get_ledger_info(&footprint_before
, &pagetable_before
);
528 dirty_size
= vm_size
/ 2;
529 memset((char *)(uintptr_t)vm_addr
, 'x', (size_t)dirty_size
);
530 /* ... should increase footprint */
531 get_ledger_info(&footprint_after
, &pagetable_after
);
532 footprint_expected
= footprint_before
+ dirty_size
;
533 footprint_expected
+= (pagetable_after
- pagetable_before
);
534 T_LOG("modifying anonymous memory increases phys_footprint");
535 T_EXPECT_EQ(footprint_after
, footprint_expected
,
536 "touched %lld bytes: "
537 "footprint %lld -> %lld expected %lld delta %lld",
538 dirty_size
, footprint_before
, footprint_after
,
539 footprint_expected
, footprint_after
- footprint_expected
);
541 /* making it volatile... */
542 get_ledger_info(&footprint_before
, &pagetable_before
);
543 state
= VM_PURGABLE_VOLATILE
;
545 T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
547 VM_PURGABLE_SET_STATE
,
550 "vm_purgable_control(VOLATILE)");
552 T_ASSERT_EQ(state
, VM_PURGABLE_NONVOLATILE
,
553 "memory was non-volatile");
554 /* ... should decrease footprint */
555 get_ledger_info(&footprint_after
, &pagetable_after
);
556 footprint_expected
= footprint_before
- dirty_size
;
557 footprint_expected
+= (pagetable_after
- pagetable_before
);
558 T_LOG("making volatile decreases phys_footprint");
559 T_EXPECT_EQ(footprint_after
, footprint_expected
,
560 "made volatile %lld dirty bytes: "
561 "footprint %lld -> %lld expected %lld delta %lld",
562 dirty_size
, footprint_before
, footprint_after
,
563 footprint_expected
, footprint_after
- footprint_expected
);
565 /* making it non-volatile... */
566 get_ledger_info(&footprint_before
, &pagetable_before
);
567 state
= VM_PURGABLE_NONVOLATILE
;
569 T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
571 VM_PURGABLE_SET_STATE
,
574 "vm_purgable_control(NONVOLATILE)");
576 T_ASSERT_EQ(state
, VM_PURGABLE_VOLATILE
,
577 "memory was volatile");
578 /* ... should increase footprint */
579 get_ledger_info(&footprint_after
, &pagetable_after
);
580 footprint_expected
= footprint_before
+ dirty_size
;
581 footprint_expected
+= (pagetable_after
- pagetable_before
);
582 T_LOG("making non-volatile increases phys_footprint");
583 T_EXPECT_EQ(footprint_after
, footprint_expected
,
584 "made non-volatile %lld dirty bytes: "
585 "footprint %lld -> %lld expected %lld delta %lld",
586 dirty_size
, footprint_before
, footprint_after
,
587 footprint_expected
, footprint_after
- footprint_expected
);
589 /* making a memory entry... */
590 get_ledger_info(&footprint_before
, &pagetable_before
);
592 me_port
= MACH_PORT_NULL
;
593 kr
= mach_make_memory_entry_64(mach_task_self(),
596 VM_PROT_READ
| VM_PROT_WRITE
,
600 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "make_memory_entry() error 0x%x (%s)",
601 kr
, mach_error_string(kr
));
603 T_EXPECT_EQ(me_size
, vm_size
, "memory entry size mismatch");
604 /* ... should not change footprint */
605 get_ledger_info(&footprint_after
, &pagetable_after
);
606 footprint_expected
= footprint_before
;
607 footprint_expected
+= (pagetable_after
- pagetable_before
);
608 T_LOG("making a memory entry does not change phys_footprint");
609 T_EXPECT_EQ(footprint_after
, footprint_expected
,
610 "making a memory entry of %lld bytes: "
611 "footprint %lld -> %lld expected %lld delta %lld",
612 vm_size
, footprint_before
, footprint_after
,
613 footprint_expected
, footprint_after
- footprint_expected
);
615 /* deallocating memory while holding memory entry... */
616 get_ledger_info(&footprint_before
, &pagetable_before
);
617 kr
= mach_vm_deallocate(mach_task_self(), vm_addr
, vm_size
);
619 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_deallocate() error 0x%x (%s)",
620 kr
, mach_error_string(kr
));
621 /* ... should not change footprint */
622 get_ledger_info(&footprint_after
, &pagetable_after
);
623 footprint_expected
= footprint_before
;
624 footprint_expected
+= (pagetable_after
- pagetable_before
);
625 T_LOG("deallocating owned memory while holding memory entry "
626 "does not change phys_footprint");
627 T_EXPECT_EQ(footprint_after
, footprint_expected
,
628 "deallocated %lld dirty bytes: "
629 "footprint %lld -> %lld expected %lld delta %lld",
630 dirty_size
, footprint_before
, footprint_after
,
631 footprint_expected
, footprint_after
- footprint_expected
);
633 /* releasing the memory entry... */
634 kr
= mach_port_deallocate(mach_task_self(), me_port
);
636 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "mach_port_deallocate() error 0x%x (%s)",
637 kr
, mach_error_string(kr
));
638 /* ... should decrease footprint */
639 get_ledger_info(&footprint_after
, &pagetable_after
);
640 footprint_expected
= footprint_before
- dirty_size
;
641 footprint_expected
+= (pagetable_after
- pagetable_before
);
642 T_LOG("releasing memory entry decreases phys_footprint");
643 T_EXPECT_EQ(footprint_after
, footprint_expected
,
644 "made volatile %lld dirty bytes: "
645 "footprint %lld -> %lld expected %lld delta %lld",
646 dirty_size
, footprint_before
, footprint_after
,
647 footprint_expected
, footprint_after
- footprint_expected
);
650 #ifdef MAP_MEM_LEDGER_TAGGED
651 T_DECL(legacy_phys_footprint_ledger_purgeable_owned
,
652 "phys_footprint for ledger-tagged purgeable memory ownership",
653 T_META_NAMESPACE("xnu.vm"),
654 T_META_LTEPHASE(LTE_POSTINIT
))
656 uint64_t footprint_before
, pagetable_before
;
657 uint64_t footprint_after
, pagetable_after
;
658 uint64_t footprint_expected
;
660 mach_vm_address_t pre_vm_addr
, vm_addr
;
661 mach_vm_size_t vm_size
, dirty_size
, me_size
;
665 /* pre-warm to account for page table expansion */
666 pre_vm_addr
= pre_warm(MEM_SIZE
);
668 /* making a memory entry... */
669 get_ledger_info(&footprint_before
, &pagetable_before
);
672 me_port
= MACH_PORT_NULL
;
673 kr
= mach_make_memory_entry_64(mach_task_self(),
676 (MAP_MEM_NAMED_CREATE
|
677 MAP_MEM_LEDGER_TAGGED
|
679 VM_PROT_READ
| VM_PROT_WRITE
),
683 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "make_memory_entry() error 0x%x (%s)",
684 kr
, mach_error_string(kr
));
686 T_EXPECT_EQ(me_size
, vm_size
, "memory entry size mismatch");
687 /* ... should not change footprint */
688 get_ledger_info(&footprint_after
, &pagetable_after
);
689 footprint_expected
= footprint_before
;
690 footprint_expected
+= (pagetable_after
- pagetable_before
);
691 T_LOG("making a memory entry does not change phys_footprint");
692 T_EXPECT_EQ(footprint_after
, footprint_expected
,
693 "making a memory entry of %lld bytes: "
694 "footprint %lld -> %lld expected %lld delta %lld",
695 vm_size
, footprint_before
, footprint_after
,
696 footprint_expected
, footprint_after
- footprint_expected
);
698 /* mapping ledger-tagged virtual memory... */
699 get_ledger_info(&footprint_before
, &pagetable_before
);
701 kr
= mach_vm_map(mach_task_self(), &vm_addr
, vm_size
,
707 VM_PROT_READ
| VM_PROT_WRITE
,
708 VM_PROT_READ
| VM_PROT_WRITE
,
711 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_map() error 0x%x (%s)",
712 kr
, mach_error_string(kr
));
714 T_EXPECT_EQ(vm_addr
, pre_vm_addr
, "pre-warm mishap");
715 /* ... should not change footprint */
716 get_ledger_info(&footprint_after
, &pagetable_after
);
717 footprint_expected
= footprint_before
;
718 footprint_expected
+= (pagetable_after
- pagetable_before
);
719 T_LOG("mapping ledger-tagged memory does not change phys_footprint");
720 T_EXPECT_EQ(footprint_after
, footprint_expected
,
721 "ledger-tagged mapping of %lld bytes: "
722 "footprint %lld -> %lld expected %lld delta %lld",
723 vm_size
, footprint_before
, footprint_after
,
724 footprint_expected
, footprint_after
- footprint_expected
);
726 /* touching memory... */
727 get_ledger_info(&footprint_before
, &pagetable_before
);
728 dirty_size
= vm_size
/ 2;
729 memset((char *)(uintptr_t)vm_addr
, 'x', (size_t)dirty_size
);
730 /* ... should increase footprint */
731 get_ledger_info(&footprint_after
, &pagetable_after
);
732 footprint_expected
= footprint_before
+ dirty_size
;
733 footprint_expected
+= (pagetable_after
- pagetable_before
);
734 T_LOG("modifying ledger-tagged memory increases phys_footprint");
735 T_EXPECT_EQ(footprint_after
, footprint_expected
,
736 "touched %lld bytes: "
737 "footprint %lld -> %lld expected %lld delta %lld",
738 dirty_size
, footprint_before
, footprint_after
,
739 footprint_expected
, footprint_after
- footprint_expected
);
741 /* making it volatile... */
742 get_ledger_info(&footprint_before
, &pagetable_before
);
743 state
= VM_PURGABLE_VOLATILE
;
745 T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
747 VM_PURGABLE_SET_STATE
,
750 "vm_purgable_control(VOLATILE)");
752 T_ASSERT_EQ(state
, VM_PURGABLE_NONVOLATILE
,
753 "memory was non-volatile");
754 /* ... should decrease footprint */
755 get_ledger_info(&footprint_after
, &pagetable_after
);
756 footprint_expected
= footprint_before
- dirty_size
;
757 footprint_expected
+= (pagetable_after
- pagetable_before
);
758 T_LOG("making volatile decreases phys_footprint");
759 T_EXPECT_EQ(footprint_after
, footprint_expected
,
760 "made volatile %lld dirty bytes: "
761 "footprint %lld -> %lld expected %lld delta %lld",
762 dirty_size
, footprint_before
, footprint_after
,
763 footprint_expected
, footprint_after
- footprint_expected
);
765 /* making it non-volatile... */
766 get_ledger_info(&footprint_before
, &pagetable_before
);
767 state
= VM_PURGABLE_NONVOLATILE
;
769 T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
771 VM_PURGABLE_SET_STATE
,
774 "vm_purgable_control(NONVOLATILE)");
776 T_ASSERT_EQ(state
, VM_PURGABLE_VOLATILE
,
777 "memory was volatile");
778 /* ... should increase footprint */
779 get_ledger_info(&footprint_after
, &pagetable_after
);
780 footprint_expected
= footprint_before
+ dirty_size
;
781 footprint_expected
+= (pagetable_after
- pagetable_before
);
782 T_LOG("making non-volatile increases phys_footprint");
783 T_EXPECT_EQ(footprint_after
, footprint_expected
,
784 "made non-volatile %lld dirty bytes: "
785 "footprint %lld -> %lld expected %lld delta %lld",
786 dirty_size
, footprint_before
, footprint_after
,
787 footprint_expected
, footprint_after
- footprint_expected
);
789 /* deallocating memory while holding memory entry... */
790 get_ledger_info(&footprint_before
, &pagetable_before
);
791 kr
= mach_vm_deallocate(mach_task_self(), vm_addr
, vm_size
);
793 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_deallocate() error 0x%x (%s)",
794 kr
, mach_error_string(kr
));
795 /* ... should not change footprint */
796 get_ledger_info(&footprint_after
, &pagetable_after
);
797 footprint_expected
= footprint_before
;
798 footprint_expected
+= (pagetable_after
- pagetable_before
);
799 T_LOG("deallocating owned memory while holding memory entry "
800 "does not change phys_footprint");
801 T_EXPECT_EQ(footprint_after
, footprint_expected
,
802 "deallocated %lld dirty bytes: "
803 "footprint %lld -> %lld expected %lld delta %lld",
804 dirty_size
, footprint_before
, footprint_after
,
805 footprint_expected
, footprint_after
- footprint_expected
);
807 /* releasing the memory entry... */
808 kr
= mach_port_deallocate(mach_task_self(), me_port
);
810 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "mach_port_deallocate() error 0x%x (%s)",
811 kr
, mach_error_string(kr
));
812 /* ... should decrease footprint */
813 get_ledger_info(&footprint_after
, &pagetable_after
);
814 footprint_expected
= footprint_before
- dirty_size
;
815 footprint_expected
+= (pagetable_after
- pagetable_before
);
816 T_LOG("releasing memory entry decreases phys_footprint");
817 T_EXPECT_EQ(footprint_after
, footprint_expected
,
818 "made volatile %lld dirty bytes: "
819 "footprint %lld -> %lld expected %lld delta %lld",
820 dirty_size
, footprint_before
, footprint_after
,
821 footprint_expected
, footprint_after
- footprint_expected
);
824 T_DECL(legacy_phys_footprint_ledger_owned
,
825 "phys_footprint for ledger-tagged memory ownership",
826 T_META_NAMESPACE("xnu.vm"),
827 T_META_LTEPHASE(LTE_POSTINIT
))
829 uint64_t footprint_before
, pagetable_before
;
830 uint64_t footprint_after
, pagetable_after
;
831 uint64_t footprint_expected
;
833 mach_vm_address_t pre_vm_addr
, vm_addr
;
834 mach_vm_size_t vm_size
, dirty_size
, me_size
;
838 /* pre-warm to account for page table expansion */
839 pre_vm_addr
= pre_warm(MEM_SIZE
);
841 /* making a memory entry... */
842 get_ledger_info(&footprint_before
, &pagetable_before
);
845 me_port
= MACH_PORT_NULL
;
846 kr
= mach_make_memory_entry_64(mach_task_self(),
849 (MAP_MEM_NAMED_CREATE
|
850 MAP_MEM_LEDGER_TAGGED
|
851 VM_PROT_READ
| VM_PROT_WRITE
),
855 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "make_memory_entry() error 0x%x (%s)",
856 kr
, mach_error_string(kr
));
858 T_EXPECT_EQ(me_size
, vm_size
, "memory entry size mismatch");
859 /* ... should not change footprint */
860 get_ledger_info(&footprint_after
, &pagetable_after
);
861 footprint_expected
= footprint_before
;
862 footprint_expected
+= (pagetable_after
- pagetable_before
);
863 T_LOG("making a memory entry does not change phys_footprint");
864 T_EXPECT_EQ(footprint_after
, footprint_expected
,
865 "making a memory entry of %lld bytes: "
866 "footprint %lld -> %lld expected %lld delta %lld",
867 vm_size
, footprint_before
, footprint_after
,
868 footprint_expected
, footprint_after
- footprint_expected
);
870 /* mapping ledger-tagged virtual memory... */
871 get_ledger_info(&footprint_before
, &pagetable_before
);
873 kr
= mach_vm_map(mach_task_self(), &vm_addr
, vm_size
,
879 VM_PROT_READ
| VM_PROT_WRITE
,
880 VM_PROT_READ
| VM_PROT_WRITE
,
883 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_map() error 0x%x (%s)",
884 kr
, mach_error_string(kr
));
886 T_EXPECT_EQ(vm_addr
, pre_vm_addr
, "pre-warm mishap");
887 /* ... should not change footprint */
888 get_ledger_info(&footprint_after
, &pagetable_after
);
889 footprint_expected
= footprint_before
;
890 footprint_expected
+= (pagetable_after
- pagetable_before
);
891 T_LOG("mapping ledger-tagged memory does not change phys_footprint");
892 T_EXPECT_EQ(footprint_after
, footprint_expected
,
893 "ledger-tagged mapping of %lld bytes: "
894 "footprint %lld -> %lld expected %lld delta %lld",
895 vm_size
, footprint_before
, footprint_after
,
896 footprint_expected
, footprint_after
- footprint_expected
);
898 /* touching memory... */
899 get_ledger_info(&footprint_before
, &pagetable_before
);
900 dirty_size
= vm_size
/ 2;
901 memset((char *)(uintptr_t)vm_addr
, 'x', (size_t)dirty_size
);
902 /* ... should increase footprint */
903 get_ledger_info(&footprint_after
, &pagetable_after
);
904 footprint_expected
= footprint_before
+ dirty_size
;
905 footprint_expected
+= (pagetable_after
- pagetable_before
);
906 T_LOG("modifying ledger-tagged memory increases phys_footprint");
907 T_EXPECT_EQ(footprint_after
, footprint_expected
,
908 "touched %lld bytes: "
909 "footprint %lld -> %lld expected %lld delta %lld",
910 dirty_size
, footprint_before
, footprint_after
,
911 footprint_expected
, footprint_after
- footprint_expected
);
913 /* deallocating memory while holding memory entry... */
914 get_ledger_info(&footprint_before
, &pagetable_before
);
915 kr
= mach_vm_deallocate(mach_task_self(), vm_addr
, vm_size
);
917 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_deallocate() error 0x%x (%s)",
918 kr
, mach_error_string(kr
));
919 /* ... should not change footprint */
920 get_ledger_info(&footprint_after
, &pagetable_after
);
921 footprint_expected
= footprint_before
;
922 footprint_expected
+= (pagetable_after
- pagetable_before
);
923 T_LOG("deallocating owned memory while holding memory entry "
924 "does not change phys_footprint");
925 T_EXPECT_EQ(footprint_after
, footprint_expected
,
926 "deallocated %lld dirty bytes: "
927 "footprint %lld -> %lld expected %lld delta %lld",
928 dirty_size
, footprint_before
, footprint_after
,
929 footprint_expected
, footprint_after
- footprint_expected
);
931 /* releasing the memory entry... */
932 kr
= mach_port_deallocate(mach_task_self(), me_port
);
934 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "mach_port_deallocate() error 0x%x (%s)",
935 kr
, mach_error_string(kr
));
936 /* ... should decrease footprint */
937 get_ledger_info(&footprint_after
, &pagetable_after
);
938 footprint_expected
= footprint_before
- dirty_size
;
939 footprint_expected
+= (pagetable_after
- pagetable_before
);
940 T_LOG("releasing memory entry decreases phys_footprint");
941 T_EXPECT_EQ(footprint_after
, footprint_expected
,
942 "made volatile %lld dirty bytes: "
943 "footprint %lld -> %lld expected %lld delta %lld",
944 dirty_size
, footprint_before
, footprint_after
,
945 footprint_expected
, footprint_after
- footprint_expected
);
947 #endif /* MAP_MEM_LEDGER_TAGGED */
949 /* IOSurface code from: CoreImage/CoreImageTests/CIRender/SurfaceUtils.c */
950 #include <CoreFoundation/CoreFoundation.h>
951 #include <IOSurface/IOSurface.h>
952 #include <IOSurface/IOSurfacePrivate.h>
954 bytes_per_element(uint32_t format
)
958 case 32: // kCVPixelFormatType_32ARGB (ARGB8)
968 bytes_per_pixel(uint32_t format
)
972 case 32: // kCVPixelFormatType_32ARGB (ARGB8)
982 roundSizeToMultiple(size_t size
, size_t mult
)
984 return ((size
+ mult
- 1) / mult
) * mult
;
987 setIntValue(CFMutableDictionaryRef dict
, const CFStringRef key
, int value
)
989 CFNumberRef number
= CFNumberCreate(0, kCFNumberIntType
, &value
);
990 CFDictionarySetValue(dict
, key
, number
);
993 typedef void (^SurfacePlaneBlock
)(void *data
, size_t planeIndex
, size_t width
, size_t height
, size_t rowbytes
);
995 SurfaceApplyPlaneBlock(IOSurfaceRef surface
, SurfacePlaneBlock block
)
997 if (surface
== nil
|| block
== nil
) {
998 return kIOReturnBadArgument
;
1001 IOReturn result
= kIOReturnSuccess
;
1002 size_t planeCount
= IOSurfaceGetPlaneCount(surface
);
1004 if (planeCount
== 0) {
1005 result
= IOSurfaceLock(surface
, 0, NULL
);
1006 if (result
!= kIOReturnSuccess
) {
1010 void* base
= IOSurfaceGetBaseAddress(surface
);
1011 size_t rb
= IOSurfaceGetBytesPerRow(surface
);
1012 size_t w
= IOSurfaceGetWidth(surface
);
1013 size_t h
= IOSurfaceGetHeight(surface
);
1015 if (base
&& rb
&& w
&& h
) {
1016 block(base
, 0, w
, h
, rb
);
1019 IOSurfaceUnlock(surface
, 0, NULL
);
1020 } else if (planeCount
== 2) {
1021 for (size_t i
= 0; i
< planeCount
; i
++) {
1022 result
= IOSurfaceLock(surface
, 0, NULL
);
1023 if (result
!= kIOReturnSuccess
) {
1027 void* base
= IOSurfaceGetBaseAddressOfPlane(surface
, i
);
1028 size_t rb
= IOSurfaceGetBytesPerRowOfPlane(surface
, i
);
1029 size_t w
= IOSurfaceGetWidthOfPlane(surface
, i
);
1030 size_t h
= IOSurfaceGetHeightOfPlane(surface
, i
);
1032 if (base
&& rb
&& w
&& h
) {
1033 block(base
, i
, w
, h
, rb
);
1036 IOSurfaceUnlock(surface
, 0, NULL
);
1042 ClearSurface(IOSurfaceRef surface
)
1045 (void) SurfaceApplyPlaneBlock(surface
, ^(void *p
, size_t i
, __unused
size_t w
, size_t h
, size_t rb
)
1048 memset(p
, zero
, rb
* h
);
1050 memset(p
, 128, rb
* h
);
1055 CreateSurface(uint32_t pixelsWide
, uint32_t pixelsHigh
, uint32_t rowBytesAlignment
, uint32_t fmt
, bool purgeable
, bool clear
)
1057 IOSurfaceRef surface
= nil
;
1059 if (pixelsWide
< 1 || pixelsHigh
< 1 || fmt
== 0) {
1063 size_t bpp
= bytes_per_pixel(fmt
);
1064 size_t bpe
= bytes_per_element(fmt
);
1065 if (bpp
== 0 || bpe
== 0) {
1069 size_t rowbytes
= pixelsWide
* bpp
;
1070 if (rowBytesAlignment
== 0) {
1071 rowBytesAlignment
= 16;
1073 rowbytes
= roundSizeToMultiple(rowbytes
, rowBytesAlignment
);
1075 CFMutableDictionaryRef props
= CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1076 setIntValue(props
, kIOSurfaceBytesPerRow
, (int)rowbytes
);
1077 setIntValue(props
, kIOSurfaceWidth
, (int)pixelsWide
);
1078 setIntValue(props
, kIOSurfaceHeight
, (int)pixelsHigh
);
1079 setIntValue(props
, kIOSurfacePixelFormat
, (int)fmt
);
1080 #if TARGET_OS_IPHONE
1081 setIntValue(props
, kIOSurfaceNonPurgeable
, purgeable
);
1082 #else /* TARGET_OS_IPHONE */
1084 #endif /* TARGET_OS_IPHONE */
1086 if (bpe
!= bpp
) { // i.e. a 422 format such as 'yuvf' etc.
1087 setIntValue(props
, kIOSurfaceElementWidth
, 2);
1088 setIntValue(props
, kIOSurfaceElementHeight
, 1);
1090 setIntValue(props
, kIOSurfaceBytesPerElement
, (int)bpe
);
1093 surface
= IOSurfaceCreate(props
);
1096 ClearSurface(surface
);
1102 T_DECL(legacy_phys_footprint_purgeable_iokit
,
1103 "phys_footprint for purgeable IOKit memory",
1104 T_META_NAMESPACE("xnu.vm"),
1105 T_META_LTEPHASE(LTE_POSTINIT
))
1107 uint64_t footprint_before
, pagetable_before
;
1108 uint64_t footprint_after
, pagetable_after
;
1109 uint64_t footprint_expected
;
1110 IOSurfaceRef surface
;
1112 uint64_t surface_size
;
1116 surface
= CreateSurface(1024, 1024, 0, 32, true, true);
1117 IOSurfaceSetPurgeable(surface
, kIOSurfacePurgeableVolatile
, &old_state
);
1118 IOSurfaceSetPurgeable(surface
, kIOSurfacePurgeableNonVolatile
, &old_state
);
1122 surface_size
= 1024 * 1024 * 4;
1124 /* create IOsurface: footprint grows */
1125 get_ledger_info(&footprint_before
, &pagetable_before
);
1126 surface
= CreateSurface(1024, 1024, 0, 32, true, true);
1127 get_ledger_info(&footprint_after
, &pagetable_after
);
1128 #if LEGACY_FOOTPRINT
1129 footprint_expected
= footprint_before
;
1130 footprint_expected
+= (pagetable_after
- pagetable_before
);
1131 T_LOG("LEGACY FOOTPRINT: creating IOSurface: no footprint impact");
1132 T_EXPECT_EQ(footprint_after
, footprint_expected
,
1133 "create IOSurface %lld bytes: "
1134 "footprint %lld -> %lld expected %lld delta %lld",
1135 surface_size
, footprint_before
, footprint_after
,
1136 footprint_expected
, footprint_after
- footprint_expected
);
1137 #else /* LEGACY_FOOTPRINT */
1138 footprint_expected
= footprint_before
+ surface_size
;
1139 footprint_expected
+= (pagetable_after
- pagetable_before
);
1140 T_LOG("creating IOSurface increases phys_footprint");
1141 T_EXPECT_EQ(footprint_after
, footprint_expected
,
1142 "create IOSurface %lld bytes: "
1143 "footprint %lld -> %lld expected %lld delta %lld",
1144 surface_size
, footprint_before
, footprint_after
,
1145 footprint_expected
, footprint_after
- footprint_expected
);
1146 #endif /* LEGACY_FOOTPRINT */
1148 /* make IOSurface volatile: footprint shrinks */
1149 get_ledger_info(&footprint_before
, &pagetable_before
);
1150 IOSurfaceSetPurgeable(surface
, kIOSurfacePurgeableVolatile
, &old_state
);
1151 get_ledger_info(&footprint_after
, &pagetable_after
);
1152 #if LEGACY_FOOTPRINT
1153 footprint_expected
= footprint_before
;
1154 footprint_expected
+= (pagetable_after
- pagetable_before
);
1155 T_LOG("LEGACY FOOTPRINT: volatile IOSurface: no footprint impact");
1156 T_EXPECT_EQ(footprint_after
, footprint_expected
,
1157 "volatile IOSurface %lld bytes: "
1158 "footprint %lld -> %lld expected %lld delta %lld",
1159 surface_size
, footprint_before
, footprint_after
,
1160 footprint_expected
, footprint_after
- footprint_expected
);
1161 #else /* LEGACY_FOOTPRINT */
1162 footprint_expected
= footprint_before
- surface_size
;
1163 footprint_expected
+= (pagetable_after
- pagetable_before
);
1164 T_LOG("making IOSurface volatile decreases phys_footprint");
1165 T_EXPECT_EQ(footprint_after
, footprint_expected
,
1166 "made volatile %lld bytes: "
1167 "footprint %lld -> %lld expected %lld delta %lld",
1168 surface_size
, footprint_before
, footprint_after
,
1169 footprint_expected
, footprint_after
- footprint_expected
);
1170 #endif /* LEGACY_FOOTPRINT */
1172 /* make IOSurface non-volatile: footprint grows */
1173 get_ledger_info(&footprint_before
, &pagetable_before
);
1174 IOSurfaceSetPurgeable(surface
, kIOSurfacePurgeableNonVolatile
, &old_state
);
1175 get_ledger_info(&footprint_after
, &pagetable_after
);
1176 #if LEGACY_FOOTPRINT
1177 footprint_expected
= footprint_before
;
1178 footprint_expected
+= (pagetable_after
- pagetable_before
);
1179 T_LOG("LEGACY FOOTPRINT: non-volatile IOSurface: no footprint impact");
1180 T_EXPECT_EQ(footprint_after
, footprint_expected
,
1181 "non-volatile IOSurface %lld bytes: "
1182 "footprint %lld -> %lld expected %lld delta %lld",
1183 surface_size
, footprint_before
, footprint_after
,
1184 footprint_expected
, footprint_after
- footprint_expected
);
1185 #else /* LEGACY_FOOTPRINT */
1186 footprint_expected
= footprint_before
+ surface_size
;
1187 footprint_expected
+= (pagetable_after
- pagetable_before
);
1188 T_LOG("making IOSurface non-volatile increases phys_footprint");
1189 T_EXPECT_EQ(footprint_after
, footprint_expected
,
1190 "made non-volatile %lld bytes: "
1191 "footprint %lld -> %lld expected %lld delta %lld",
1192 surface_size
, footprint_before
, footprint_after
,
1193 footprint_expected
, footprint_after
- footprint_expected
);
1194 #endif /* LEGACY_FOOTPRINT */
1196 /* accessing IOSurface re-mapping: no footprint impact */
1198 /* deallocating IOSurface re-mapping: no footprint impact */
1200 /* release IOSurface: footprint shrinks */
1201 get_ledger_info(&footprint_before
, &pagetable_before
);
1203 get_ledger_info(&footprint_after
, &pagetable_after
);
1204 #if LEGACY_FOOTPRINT
1205 footprint_expected
= footprint_before
;
1206 footprint_expected
+= (pagetable_after
- pagetable_before
);
1207 T_LOG("LEGACY FOOTPRINT: release IOSurface: no footprint impact");
1208 T_EXPECT_EQ(footprint_after
, footprint_expected
,
1209 "releasing IOSurface %lld bytes: "
1210 "footprint %lld -> %lld expected %lld delta %lld",
1211 surface_size
, footprint_before
, footprint_after
,
1212 footprint_expected
, footprint_after
- footprint_expected
);
1213 #else /* LEGACY_FOOTPRINT */
1214 footprint_expected
= footprint_before
- surface_size
;
1215 footprint_expected
+= (pagetable_after
- pagetable_before
);
1216 T_LOG("releasing IOSurface decreases phys_footprint");
1217 T_EXPECT_EQ(footprint_after
, footprint_expected
,
1218 "released IOSurface %lld bytes: "
1219 "footprint %lld -> %lld expected %lld delta %lld",
1220 surface_size
, footprint_before
, footprint_after
,
1221 footprint_expected
, footprint_after
- footprint_expected
);
1222 #endif /* LEGACY_FOOTPRINT */