1 #include <darwintest.h>
2 #include <darwintest_utils.h>
4 #include <mach/mach_error.h>
5 #include <mach/mach_init.h>
6 #include <mach/mach_port.h>
7 #include <mach/mach_vm.h>
9 #include <mach/task_info.h>
10 #include <mach/vm_map.h>
14 #include <Kernel/kern/ledger.h>
15 extern int ledger(int cmd
, caddr_t arg1
, caddr_t arg2
, caddr_t arg3
);
17 #if ENTITLED && defined(__arm64__)
18 #define LEGACY_FOOTPRINT 1
19 #else /* ENTITLED && __arm64__ */
20 #define LEGACY_FOOTPRINT 0
21 #endif /* ENTITLED && __arm64__ */
23 #define MEM_SIZE (100 * 1024 * 1024) /* 100 MB */
25 static int64_t ledger_count
= -1;
26 static int footprint_index
= -1;
27 static int pagetable_index
= -1;
28 static struct ledger_entry_info
*lei
= NULL
;
33 static int ledger_inited
= 0;
34 struct ledger_info li
;
35 struct ledger_template_info
*templateInfo
;
47 T_ASSERT_EQ(ledger(LEDGER_INFO
,
48 (caddr_t
)(uintptr_t)getpid(),
52 "ledger(LEDGER_INFO)");
54 templateCnt
= li
.li_entries
;
55 templateInfo
= malloc((size_t)li
.li_entries
* sizeof(struct ledger_template_info
));
58 T_ASSERT_NE(templateInfo
, NULL
, "malloc()");
60 ledger_count
= li
.li_entries
;
65 T_ASSERT_GE(ledger(LEDGER_TEMPLATE_INFO
,
66 (caddr_t
)templateInfo
,
67 (caddr_t
)&templateCnt
,
70 "ledger(LEDGER_TEMPLATE_INFO)");
71 for (i
= 0; i
< templateCnt
; i
++) {
72 if (!strncmp(templateInfo
[i
].lti_name
,
74 strlen("phys_footprint"))) {
76 } else if (!strncmp(templateInfo
[i
].lti_name
,
78 strlen("page_table"))) {
84 lei
= (struct ledger_entry_info
*)
85 malloc((size_t)ledger_count
* sizeof(*lei
));
88 T_ASSERT_NE(lei
, NULL
, "malloc(ledger_entry_info)");
91 T_ASSERT_NE(footprint_index
, -1, "no footprint_index");
93 T_ASSERT_NE(pagetable_index
, -1, "no pagetable_index");
100 uint64_t *phys_footprint
,
101 uint64_t *page_table
)
105 count
= ledger_count
;
108 T_ASSERT_GE(ledger(LEDGER_ENTRY_INFO
,
109 (caddr_t
)(uintptr_t)getpid(),
113 "ledger(LEDGER_ENTRY_INFO)");
115 T_ASSERT_GT(count
, (int64_t)footprint_index
, "no entry for footprint");
117 T_ASSERT_GT(count
, (int64_t)pagetable_index
, "no entry for pagetable");
118 if (phys_footprint
) {
119 *phys_footprint
= (uint64_t)(lei
[footprint_index
].lei_balance
);
122 *page_table
= (uint64_t)(lei
[pagetable_index
].lei_balance
);
126 static mach_vm_address_t
128 mach_vm_size_t vm_size
)
131 mach_vm_address_t vm_addr
;
132 unsigned char BigBufOnStack
[100 * 1024];
133 uint64_t footprint
, page_table
;
135 /* make sure ledgers are ready to be queried */
141 * Touch a few pages ahead on the stack, to make
142 * sure we don't see a footprint increase due to
143 * an extra stack page later.
145 memset(BigBufOnStack
, 0xb, sizeof(BigBufOnStack
));
147 T_EXPECT_EQ(BigBufOnStack
[0], 0xb,
148 "BigBufOnStack[0] == 0x%x",
151 T_EXPECT_EQ(BigBufOnStack
[sizeof(BigBufOnStack
) - 1], 0xb,
152 "BigBufOnStack[%lu] == 0x%x",
153 sizeof(BigBufOnStack
),
154 BigBufOnStack
[sizeof(BigBufOnStack
) - 1]);
157 * Pre-allocate, touch and then release the same amount
158 * of memory we'll be allocating later during the test,
159 * to account for any memory overhead (page tables, global
163 kr
= mach_vm_allocate(mach_task_self(),
168 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_allocate(%lld) error 0x%x (%s)",
169 vm_size
, kr
, mach_error_string(kr
));
170 memset((char *)(uintptr_t)vm_addr
, 'p', (size_t)vm_size
);
171 kr
= mach_vm_deallocate(mach_task_self(),
175 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_deallocate() error 0x%x (%s)",
176 kr
, mach_error_string(kr
));
179 * Exercise the ledger code to make sure it's ready to run
180 * without any extra memory overhead later.
182 get_ledger_info(&footprint
, &page_table
);
187 * Return the start of the virtual range we pre-warmed, so that the
188 * test can check that it's using the same range.
193 T_DECL(phys_footprint_anonymous
,
194 "phys_footprint for anonymous memory",
195 T_META_NAMESPACE("xnu.vm"),
196 T_META_LTEPHASE(LTE_POSTINIT
))
198 uint64_t footprint_before
, pagetable_before
;
199 uint64_t footprint_after
, pagetable_after
;
200 uint64_t footprint_expected
;
202 mach_vm_address_t pre_vm_addr
, vm_addr
;
203 mach_vm_size_t vm_size
, dirty_size
;
205 /* pre-warm to account for page table expansion */
206 pre_vm_addr
= pre_warm(MEM_SIZE
);
208 /* allocating virtual memory... */
209 get_ledger_info(&footprint_before
, &pagetable_before
);
212 kr
= mach_vm_allocate(mach_task_self(), &vm_addr
, vm_size
,
215 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_allocate() error 0x%x (%s)",
216 kr
, mach_error_string(kr
));
218 T_EXPECT_EQ(vm_addr
, pre_vm_addr
, "pre-warm mishap");
219 /* ... should not change footprint */
220 get_ledger_info(&footprint_after
, &pagetable_after
);
221 footprint_expected
= footprint_before
;
222 footprint_expected
+= (pagetable_after
- pagetable_before
);
223 T_LOG("virtual allocation does not change phys_footprint");
224 T_EXPECT_EQ(footprint_after
, footprint_expected
,
225 "virtual allocation of %lld bytes: "
226 "footprint %lld -> %lld expected %lld delta %lld",
227 vm_size
, footprint_before
, footprint_after
,
228 footprint_expected
, footprint_after
- footprint_expected
);
230 /* touching memory... */
231 get_ledger_info(&footprint_before
, &pagetable_before
);
232 dirty_size
= vm_size
/ 2;
233 memset((char *)(uintptr_t)vm_addr
, 'x', (size_t)dirty_size
);
234 /* ... should increase footprint */
235 get_ledger_info(&footprint_after
, &pagetable_after
);
236 footprint_expected
= footprint_before
+ dirty_size
;
237 footprint_expected
+= (pagetable_after
- pagetable_before
);
238 T_LOG("modifying anonymous memory increases phys_footprint");
239 T_EXPECT_EQ(footprint_after
, footprint_expected
,
240 "touched %lld bytes: "
241 "footprint %lld -> %lld expected %lld delta %lld",
242 dirty_size
, footprint_before
, footprint_after
,
243 footprint_expected
, footprint_after
- footprint_expected
);
245 /* deallocating memory... */
246 get_ledger_info(&footprint_before
, &pagetable_before
);
247 kr
= mach_vm_deallocate(mach_task_self(), vm_addr
, vm_size
);
249 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_deallocate() error 0x%x (%s)",
250 kr
, mach_error_string(kr
));
251 /* ... should decrease footprint */
252 get_ledger_info(&footprint_after
, &pagetable_after
);
253 footprint_expected
= footprint_before
- dirty_size
;
254 footprint_expected
+= (pagetable_after
- pagetable_before
);
255 T_LOG("deallocating dirty anonymous memory decreases phys_footprint");
256 T_EXPECT_EQ(footprint_after
, footprint_expected
,
257 "deallocated %lld dirty bytes: "
258 "footprint %lld -> %lld expected %lld delta %lld",
259 dirty_size
, footprint_before
, footprint_after
,
260 footprint_expected
, footprint_after
- footprint_expected
);
263 #define TEMP_FILE_TEMPLATE "/tmp/phys_footprint_data.XXXXXXXX"
264 #define TEMP_FILE_SIZE (1 * 1024 * 1024)
266 T_DECL(phys_footprint_file
,
267 "phys_footprint for mapped file",
268 T_META_NAMESPACE("xnu.vm"),
269 T_META_LTEPHASE(LTE_POSTINIT
))
271 uint64_t footprint_before
, pagetable_before
;
272 uint64_t footprint_after
, pagetable_after
;
273 uint64_t footprint_expected
;
274 mach_vm_address_t pre_vm_addr
;
277 size_t map_size
, dirty_size
;
279 char tmp_file_name
[PATH_MAX
] = TEMP_FILE_TEMPLATE
;
284 buf_size
= TEMP_FILE_SIZE
;
286 T_ASSERT_NOTNULL(buf
= (char *)malloc(buf_size
),
287 "allocate %zu-byte buffer", buf_size
);
288 memset(buf
, 'f', buf_size
);
291 T_ASSERT_NOTNULL(mktemp(tmp_file_name
),
292 "create temporary file name");
295 T_ASSERT_GE(fd
= open(tmp_file_name
, O_CREAT
| O_RDWR
),
300 T_ASSERT_EQ(nbytes
= write(fd
, buf
, buf_size
),
302 "write %zu bytes", buf_size
);
306 /* pre-warm to account for page table expansion */
307 pre_vm_addr
= pre_warm(TEMP_FILE_SIZE
);
309 /* mapping a file does not impact footprint... */
310 get_ledger_info(&footprint_before
, &pagetable_before
);
311 map_size
= TEMP_FILE_SIZE
;
314 T_ASSERT_NOTNULL(map_addr
= (char *)mmap(NULL
, map_size
,
315 PROT_READ
| PROT_WRITE
,
316 MAP_FILE
| MAP_SHARED
, fd
, 0),
319 T_EXPECT_EQ((mach_vm_address_t
)map_addr
, pre_vm_addr
,
321 /* ... should not change footprint */
322 get_ledger_info(&footprint_after
, &pagetable_after
);
323 footprint_expected
= footprint_before
;
324 footprint_expected
+= (pagetable_after
- pagetable_before
);
325 T_LOG("mapping file does not change phys_footprint");
326 T_EXPECT_EQ(footprint_after
, footprint_expected
,
327 "mapping file with %zu bytes: "
328 "footprint %lld -> %lld expected %lld delta %lld",
329 map_size
, footprint_before
, footprint_after
,
330 footprint_expected
, footprint_after
- footprint_expected
);
332 /* touching file-backed memory... */
333 get_ledger_info(&footprint_before
, &pagetable_before
);
334 dirty_size
= map_size
/ 2;
335 memset(map_addr
, 'F', dirty_size
);
336 /* ... should not impact footprint */
337 get_ledger_info(&footprint_after
, &pagetable_after
);
338 footprint_expected
= footprint_before
;
339 footprint_expected
+= (pagetable_after
- pagetable_before
);
340 T_LOG("modifying file-backed memory does not impact phys_footprint");
341 T_EXPECT_EQ(footprint_after
, footprint_expected
,
342 "touched %zu bytes: "
343 "footprint %lld -> %lld expected %lld delta %lld",
344 dirty_size
, footprint_before
, footprint_after
,
345 footprint_expected
, footprint_after
- footprint_expected
);
347 /* deallocating file-backed memory... */
348 get_ledger_info(&footprint_before
, &pagetable_before
);
351 T_ASSERT_EQ(munmap(map_addr
, map_size
),
354 /* ... should not impact footprint */
355 get_ledger_info(&footprint_after
, &pagetable_after
);
356 footprint_expected
= footprint_before
;
357 footprint_expected
+= (pagetable_after
- pagetable_before
);
358 T_LOG("unmapping file-backed memory does not impact phys_footprint");
359 T_EXPECT_EQ(footprint_after
, footprint_expected
,
360 "unmapped %zu dirty bytes: "
361 "footprint %lld -> %lld expected %lld delta %lld",
362 dirty_size
, footprint_before
, footprint_after
,
363 footprint_expected
, footprint_after
- footprint_expected
);
366 T_DECL(phys_footprint_purgeable
,
367 "phys_footprint for purgeable memory",
368 T_META_NAMESPACE("xnu.vm"),
369 T_META_LTEPHASE(LTE_POSTINIT
))
371 uint64_t footprint_before
, pagetable_before
;
372 uint64_t footprint_after
, pagetable_after
;
373 uint64_t footprint_expected
;
375 mach_vm_address_t pre_vm_addr
, vm_addr
;
376 mach_vm_size_t vm_size
, dirty_size
;
379 /* pre-warm to account for page table expansion */
380 pre_vm_addr
= pre_warm(MEM_SIZE
);
382 /* allocating purgeable virtual memory... */
383 get_ledger_info(&footprint_before
, &pagetable_before
);
386 kr
= mach_vm_allocate(mach_task_self(), &vm_addr
, vm_size
,
387 VM_FLAGS_ANYWHERE
| VM_FLAGS_PURGABLE
);
389 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_allocate() error 0x%x (%s)",
390 kr
, mach_error_string(kr
));
392 T_EXPECT_EQ(vm_addr
, pre_vm_addr
, "pre-warm mishap");
393 /* ... should not change footprint */
394 get_ledger_info(&footprint_after
, &pagetable_after
);
395 footprint_expected
= footprint_before
;
396 footprint_expected
+= (pagetable_after
- pagetable_before
);
397 T_LOG("purgeable virtual allocation does not change phys_footprint");
398 T_EXPECT_EQ(footprint_after
, footprint_expected
,
399 "purgeable virtual allocation of %lld bytes: "
400 "footprint %lld -> %lld expected %lld delta %lld",
401 vm_size
, footprint_before
, footprint_after
,
402 footprint_expected
, footprint_after
- footprint_expected
);
404 /* touching memory... */
405 get_ledger_info(&footprint_before
, &pagetable_before
);
406 dirty_size
= vm_size
/ 2;
407 memset((char *)(uintptr_t)vm_addr
, 'x', (size_t)dirty_size
);
408 /* ... should increase footprint */
409 get_ledger_info(&footprint_after
, &pagetable_after
);
410 footprint_expected
= footprint_before
+ dirty_size
;
411 footprint_expected
+= (pagetable_after
- pagetable_before
);
412 T_LOG("modifying anonymous memory increases phys_footprint");
413 T_EXPECT_EQ(footprint_after
, footprint_expected
,
414 "touched %lld bytes: "
415 "footprint %lld -> %lld expected %lld delta %lld",
416 dirty_size
, footprint_before
, footprint_after
,
417 footprint_expected
, footprint_after
- footprint_expected
);
419 /* making it volatile... */
420 get_ledger_info(&footprint_before
, &pagetable_before
);
421 state
= VM_PURGABLE_VOLATILE
;
423 T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
425 VM_PURGABLE_SET_STATE
,
428 "vm_purgable_control(VOLATILE)");
430 T_ASSERT_EQ(state
, VM_PURGABLE_NONVOLATILE
,
431 "memory was non-volatile");
432 /* ... should decrease footprint */
433 get_ledger_info(&footprint_after
, &pagetable_after
);
434 footprint_expected
= footprint_before
- dirty_size
;
435 footprint_expected
+= (pagetable_after
- pagetable_before
);
436 T_LOG("making volatile decreases phys_footprint");
437 T_EXPECT_EQ(footprint_after
, footprint_expected
,
438 "made volatile %lld dirty bytes: "
439 "footprint %lld -> %lld expected %lld delta %lld",
440 dirty_size
, footprint_before
, footprint_after
,
441 footprint_expected
, footprint_after
- footprint_expected
);
443 /* making it non-volatile... */
444 get_ledger_info(&footprint_before
, &pagetable_before
);
445 state
= VM_PURGABLE_NONVOLATILE
;
447 T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
449 VM_PURGABLE_SET_STATE
,
452 "vm_purgable_control(NONVOLATILE)");
454 T_ASSERT_EQ(state
, VM_PURGABLE_VOLATILE
,
455 "memory was volatile");
456 /* ... should increase footprint */
457 get_ledger_info(&footprint_after
, &pagetable_after
);
458 footprint_expected
= footprint_before
+ dirty_size
;
459 footprint_expected
+= (pagetable_after
- pagetable_before
);
460 T_LOG("making non-volatile increases phys_footprint");
461 T_EXPECT_EQ(footprint_after
, footprint_expected
,
462 "made non-volatile %lld dirty bytes: "
463 "footprint %lld -> %lld expected %lld delta %lld",
464 dirty_size
, footprint_before
, footprint_after
,
465 footprint_expected
, footprint_after
- footprint_expected
);
467 /* deallocating memory... */
468 get_ledger_info(&footprint_before
, &pagetable_before
);
469 kr
= mach_vm_deallocate(mach_task_self(), vm_addr
, vm_size
);
471 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_deallocate() error 0x%x (%s)",
472 kr
, mach_error_string(kr
));
473 /* ... should decrease footprint */
474 get_ledger_info(&footprint_after
, &pagetable_after
);
475 footprint_expected
= footprint_before
- dirty_size
;
476 footprint_expected
+= (pagetable_after
- pagetable_before
);
477 T_LOG("deallocating memory decreases phys_footprint");
478 T_EXPECT_EQ(footprint_after
, footprint_expected
,
479 "deallocated %lld dirty bytes: "
480 "footprint %lld -> %lld expected %lld delta %lld",
481 dirty_size
, footprint_before
, footprint_after
,
482 footprint_expected
, footprint_after
- footprint_expected
);
485 T_DECL(phys_footprint_purgeable_ownership
,
486 "phys_footprint for owned purgeable memory",
487 T_META_NAMESPACE("xnu.vm"),
488 T_META_LTEPHASE(LTE_POSTINIT
))
490 uint64_t footprint_before
, pagetable_before
;
491 uint64_t footprint_after
, pagetable_after
;
492 uint64_t footprint_expected
;
494 mach_vm_address_t pre_vm_addr
, vm_addr
;
495 mach_vm_size_t vm_size
, dirty_size
, me_size
;
499 /* pre-warm to account for page table expansion */
500 pre_vm_addr
= pre_warm(MEM_SIZE
);
502 /* allocating purgeable virtual memory... */
503 get_ledger_info(&footprint_before
, &pagetable_before
);
506 kr
= mach_vm_allocate(mach_task_self(), &vm_addr
, vm_size
,
507 VM_FLAGS_ANYWHERE
| VM_FLAGS_PURGABLE
);
509 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_allocate() error 0x%x (%s)",
510 kr
, mach_error_string(kr
));
512 T_EXPECT_EQ(vm_addr
, pre_vm_addr
, "pre-warm mishap");
513 /* ... should not change footprint */
514 get_ledger_info(&footprint_after
, &pagetable_after
);
515 footprint_expected
= footprint_before
;
516 footprint_expected
+= (pagetable_after
- pagetable_before
);
517 T_LOG("purgeable virtual allocation does not change phys_footprint");
518 T_EXPECT_EQ(footprint_after
, footprint_expected
,
519 "purgeable virtual allocation of %lld bytes: "
520 "footprint %lld -> %lld expected %lld delta %lld",
521 vm_size
, footprint_before
, footprint_after
,
522 footprint_expected
, footprint_after
- footprint_expected
);
524 /* touching memory... */
525 get_ledger_info(&footprint_before
, &pagetable_before
);
526 dirty_size
= vm_size
/ 2;
527 memset((char *)(uintptr_t)vm_addr
, 'x', (size_t)dirty_size
);
528 /* ... should increase footprint */
529 get_ledger_info(&footprint_after
, &pagetable_after
);
530 footprint_expected
= footprint_before
+ dirty_size
;
531 footprint_expected
+= (pagetable_after
- pagetable_before
);
532 T_LOG("modifying anonymous memory increases phys_footprint");
533 T_EXPECT_EQ(footprint_after
, footprint_expected
,
534 "touched %lld bytes: "
535 "footprint %lld -> %lld expected %lld delta %lld",
536 dirty_size
, footprint_before
, footprint_after
,
537 footprint_expected
, footprint_after
- footprint_expected
);
539 /* making it volatile... */
540 get_ledger_info(&footprint_before
, &pagetable_before
);
541 state
= VM_PURGABLE_VOLATILE
;
543 T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
545 VM_PURGABLE_SET_STATE
,
548 "vm_purgable_control(VOLATILE)");
550 T_ASSERT_EQ(state
, VM_PURGABLE_NONVOLATILE
,
551 "memory was non-volatile");
552 /* ... should decrease footprint */
553 get_ledger_info(&footprint_after
, &pagetable_after
);
554 footprint_expected
= footprint_before
- dirty_size
;
555 footprint_expected
+= (pagetable_after
- pagetable_before
);
556 T_LOG("making volatile decreases phys_footprint");
557 T_EXPECT_EQ(footprint_after
, footprint_expected
,
558 "made volatile %lld dirty bytes: "
559 "footprint %lld -> %lld expected %lld delta %lld",
560 dirty_size
, footprint_before
, footprint_after
,
561 footprint_expected
, footprint_after
- footprint_expected
);
563 /* making it non-volatile... */
564 get_ledger_info(&footprint_before
, &pagetable_before
);
565 state
= VM_PURGABLE_NONVOLATILE
;
567 T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
569 VM_PURGABLE_SET_STATE
,
572 "vm_purgable_control(NONVOLATILE)");
574 T_ASSERT_EQ(state
, VM_PURGABLE_VOLATILE
,
575 "memory was volatile");
576 /* ... should increase footprint */
577 get_ledger_info(&footprint_after
, &pagetable_after
);
578 footprint_expected
= footprint_before
+ dirty_size
;
579 footprint_expected
+= (pagetable_after
- pagetable_before
);
580 T_LOG("making non-volatile increases phys_footprint");
581 T_EXPECT_EQ(footprint_after
, footprint_expected
,
582 "made non-volatile %lld dirty bytes: "
583 "footprint %lld -> %lld expected %lld delta %lld",
584 dirty_size
, footprint_before
, footprint_after
,
585 footprint_expected
, footprint_after
- footprint_expected
);
587 /* making a memory entry... */
588 get_ledger_info(&footprint_before
, &pagetable_before
);
590 me_port
= MACH_PORT_NULL
;
591 kr
= mach_make_memory_entry_64(mach_task_self(),
594 VM_PROT_READ
| VM_PROT_WRITE
,
598 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "make_memory_entry() error 0x%x (%s)",
599 kr
, mach_error_string(kr
));
601 T_EXPECT_EQ(me_size
, vm_size
, "memory entry size mismatch");
602 /* ... should not change footprint */
603 get_ledger_info(&footprint_after
, &pagetable_after
);
604 footprint_expected
= footprint_before
;
605 footprint_expected
+= (pagetable_after
- pagetable_before
);
606 T_LOG("making a memory entry does not change phys_footprint");
607 T_EXPECT_EQ(footprint_after
, footprint_expected
,
608 "making a memory entry of %lld bytes: "
609 "footprint %lld -> %lld expected %lld delta %lld",
610 vm_size
, footprint_before
, footprint_after
,
611 footprint_expected
, footprint_after
- footprint_expected
);
613 /* deallocating memory while holding memory entry... */
614 get_ledger_info(&footprint_before
, &pagetable_before
);
615 kr
= mach_vm_deallocate(mach_task_self(), vm_addr
, vm_size
);
617 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_deallocate() error 0x%x (%s)",
618 kr
, mach_error_string(kr
));
619 /* ... should not change footprint */
620 get_ledger_info(&footprint_after
, &pagetable_after
);
621 footprint_expected
= footprint_before
;
622 footprint_expected
+= (pagetable_after
- pagetable_before
);
623 T_LOG("deallocating owned memory while holding memory entry "
624 "does not change phys_footprint");
625 T_EXPECT_EQ(footprint_after
, footprint_expected
,
626 "deallocated %lld dirty bytes: "
627 "footprint %lld -> %lld expected %lld delta %lld",
628 dirty_size
, footprint_before
, footprint_after
,
629 footprint_expected
, footprint_after
- footprint_expected
);
631 /* releasing the memory entry... */
632 kr
= mach_port_deallocate(mach_task_self(), me_port
);
634 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "mach_port_deallocate() error 0x%x (%s)",
635 kr
, mach_error_string(kr
));
636 /* ... should decrease footprint */
637 get_ledger_info(&footprint_after
, &pagetable_after
);
638 footprint_expected
= footprint_before
- dirty_size
;
639 footprint_expected
+= (pagetable_after
- pagetable_before
);
640 T_LOG("releasing memory entry decreases phys_footprint");
641 T_EXPECT_EQ(footprint_after
, footprint_expected
,
642 "made volatile %lld dirty bytes: "
643 "footprint %lld -> %lld expected %lld delta %lld",
644 dirty_size
, footprint_before
, footprint_after
,
645 footprint_expected
, footprint_after
- footprint_expected
);
648 #ifdef MAP_MEM_LEDGER_TAGGED
649 T_DECL(phys_footprint_ledger_purgeable_owned
,
650 "phys_footprint for ledger-tagged purgeable memory ownership",
651 T_META_NAMESPACE("xnu.vm"),
652 T_META_LTEPHASE(LTE_POSTINIT
))
654 uint64_t footprint_before
, pagetable_before
;
655 uint64_t footprint_after
, pagetable_after
;
656 uint64_t footprint_expected
;
658 mach_vm_address_t pre_vm_addr
, vm_addr
;
659 mach_vm_size_t vm_size
, dirty_size
, me_size
;
663 /* pre-warm to account for page table expansion */
664 pre_vm_addr
= pre_warm(MEM_SIZE
);
666 /* making a memory entry... */
667 get_ledger_info(&footprint_before
, &pagetable_before
);
670 me_port
= MACH_PORT_NULL
;
671 kr
= mach_make_memory_entry_64(mach_task_self(),
674 (MAP_MEM_NAMED_CREATE
|
675 MAP_MEM_LEDGER_TAGGED
|
677 VM_PROT_READ
| VM_PROT_WRITE
),
681 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "make_memory_entry() error 0x%x (%s)",
682 kr
, mach_error_string(kr
));
684 T_EXPECT_EQ(me_size
, vm_size
, "memory entry size mismatch");
685 /* ... should not change footprint */
686 get_ledger_info(&footprint_after
, &pagetable_after
);
687 footprint_expected
= footprint_before
;
688 footprint_expected
+= (pagetable_after
- pagetable_before
);
689 T_LOG("making a memory entry does not change phys_footprint");
690 T_EXPECT_EQ(footprint_after
, footprint_expected
,
691 "making a memory entry of %lld bytes: "
692 "footprint %lld -> %lld expected %lld delta %lld",
693 vm_size
, footprint_before
, footprint_after
,
694 footprint_expected
, footprint_after
- footprint_expected
);
696 /* mapping ledger-tagged virtual memory... */
697 get_ledger_info(&footprint_before
, &pagetable_before
);
699 kr
= mach_vm_map(mach_task_self(), &vm_addr
, vm_size
,
705 VM_PROT_READ
| VM_PROT_WRITE
,
706 VM_PROT_READ
| VM_PROT_WRITE
,
709 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_map() error 0x%x (%s)",
710 kr
, mach_error_string(kr
));
712 T_EXPECT_EQ(vm_addr
, pre_vm_addr
, "pre-warm mishap");
713 /* ... should not change footprint */
714 get_ledger_info(&footprint_after
, &pagetable_after
);
715 footprint_expected
= footprint_before
;
716 footprint_expected
+= (pagetable_after
- pagetable_before
);
717 T_LOG("mapping ledger-tagged memory does not change phys_footprint");
718 T_EXPECT_EQ(footprint_after
, footprint_expected
,
719 "ledger-tagged mapping of %lld bytes: "
720 "footprint %lld -> %lld expected %lld delta %lld",
721 vm_size
, footprint_before
, footprint_after
,
722 footprint_expected
, footprint_after
- footprint_expected
);
724 /* touching memory... */
725 get_ledger_info(&footprint_before
, &pagetable_before
);
726 dirty_size
= vm_size
/ 2;
727 memset((char *)(uintptr_t)vm_addr
, 'x', (size_t)dirty_size
);
728 /* ... should increase footprint */
729 get_ledger_info(&footprint_after
, &pagetable_after
);
730 footprint_expected
= footprint_before
+ dirty_size
;
731 footprint_expected
+= (pagetable_after
- pagetable_before
);
732 T_LOG("modifying ledger-tagged memory increases phys_footprint");
733 T_EXPECT_EQ(footprint_after
, footprint_expected
,
734 "touched %lld bytes: "
735 "footprint %lld -> %lld expected %lld delta %lld",
736 dirty_size
, footprint_before
, footprint_after
,
737 footprint_expected
, footprint_after
- footprint_expected
);
739 /* making it volatile... */
740 get_ledger_info(&footprint_before
, &pagetable_before
);
741 state
= VM_PURGABLE_VOLATILE
;
743 T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
745 VM_PURGABLE_SET_STATE
,
748 "vm_purgable_control(VOLATILE)");
750 T_ASSERT_EQ(state
, VM_PURGABLE_NONVOLATILE
,
751 "memory was non-volatile");
752 /* ... should decrease footprint */
753 get_ledger_info(&footprint_after
, &pagetable_after
);
754 footprint_expected
= footprint_before
- dirty_size
;
755 footprint_expected
+= (pagetable_after
- pagetable_before
);
756 T_LOG("making volatile decreases phys_footprint");
757 T_EXPECT_EQ(footprint_after
, footprint_expected
,
758 "made volatile %lld dirty bytes: "
759 "footprint %lld -> %lld expected %lld delta %lld",
760 dirty_size
, footprint_before
, footprint_after
,
761 footprint_expected
, footprint_after
- footprint_expected
);
763 /* making it non-volatile... */
764 get_ledger_info(&footprint_before
, &pagetable_before
);
765 state
= VM_PURGABLE_NONVOLATILE
;
767 T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
769 VM_PURGABLE_SET_STATE
,
772 "vm_purgable_control(NONVOLATILE)");
774 T_ASSERT_EQ(state
, VM_PURGABLE_VOLATILE
,
775 "memory was volatile");
776 /* ... should increase footprint */
777 get_ledger_info(&footprint_after
, &pagetable_after
);
778 footprint_expected
= footprint_before
+ dirty_size
;
779 footprint_expected
+= (pagetable_after
- pagetable_before
);
780 T_LOG("making non-volatile increases phys_footprint");
781 T_EXPECT_EQ(footprint_after
, footprint_expected
,
782 "made non-volatile %lld dirty bytes: "
783 "footprint %lld -> %lld expected %lld delta %lld",
784 dirty_size
, footprint_before
, footprint_after
,
785 footprint_expected
, footprint_after
- footprint_expected
);
787 /* deallocating memory while holding memory entry... */
788 get_ledger_info(&footprint_before
, &pagetable_before
);
789 kr
= mach_vm_deallocate(mach_task_self(), vm_addr
, vm_size
);
791 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_deallocate() error 0x%x (%s)",
792 kr
, mach_error_string(kr
));
793 /* ... should not change footprint */
794 get_ledger_info(&footprint_after
, &pagetable_after
);
795 footprint_expected
= footprint_before
;
796 footprint_expected
+= (pagetable_after
- pagetable_before
);
797 T_LOG("deallocating owned memory while holding memory entry "
798 "does not change phys_footprint");
799 T_EXPECT_EQ(footprint_after
, footprint_expected
,
800 "deallocated %lld dirty bytes: "
801 "footprint %lld -> %lld expected %lld delta %lld",
802 dirty_size
, footprint_before
, footprint_after
,
803 footprint_expected
, footprint_after
- footprint_expected
);
805 /* releasing the memory entry... */
806 kr
= mach_port_deallocate(mach_task_self(), me_port
);
808 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "mach_port_deallocate() error 0x%x (%s)",
809 kr
, mach_error_string(kr
));
810 /* ... should decrease footprint */
811 get_ledger_info(&footprint_after
, &pagetable_after
);
812 footprint_expected
= footprint_before
- dirty_size
;
813 footprint_expected
+= (pagetable_after
- pagetable_before
);
814 T_LOG("releasing memory entry decreases phys_footprint");
815 T_EXPECT_EQ(footprint_after
, footprint_expected
,
816 "made volatile %lld dirty bytes: "
817 "footprint %lld -> %lld expected %lld delta %lld",
818 dirty_size
, footprint_before
, footprint_after
,
819 footprint_expected
, footprint_after
- footprint_expected
);
822 T_DECL(phys_footprint_ledger_owned
,
823 "phys_footprint for ledger-tagged memory ownership",
824 T_META_NAMESPACE("xnu.vm"),
825 T_META_LTEPHASE(LTE_POSTINIT
))
827 uint64_t footprint_before
, pagetable_before
;
828 uint64_t footprint_after
, pagetable_after
;
829 uint64_t footprint_expected
;
831 mach_vm_address_t pre_vm_addr
, vm_addr
;
832 mach_vm_size_t vm_size
, dirty_size
, me_size
;
836 /* pre-warm to account for page table expansion */
837 pre_vm_addr
= pre_warm(MEM_SIZE
);
839 /* making a memory entry... */
840 get_ledger_info(&footprint_before
, &pagetable_before
);
843 me_port
= MACH_PORT_NULL
;
844 kr
= mach_make_memory_entry_64(mach_task_self(),
847 (MAP_MEM_NAMED_CREATE
|
848 MAP_MEM_LEDGER_TAGGED
|
849 VM_PROT_READ
| VM_PROT_WRITE
),
853 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "make_memory_entry() error 0x%x (%s)",
854 kr
, mach_error_string(kr
));
856 T_EXPECT_EQ(me_size
, vm_size
, "memory entry size mismatch");
857 /* ... should not change footprint */
858 get_ledger_info(&footprint_after
, &pagetable_after
);
859 footprint_expected
= footprint_before
;
860 footprint_expected
+= (pagetable_after
- pagetable_before
);
861 T_LOG("making a memory entry does not change phys_footprint");
862 T_EXPECT_EQ(footprint_after
, footprint_expected
,
863 "making a memory entry of %lld bytes: "
864 "footprint %lld -> %lld expected %lld delta %lld",
865 vm_size
, footprint_before
, footprint_after
,
866 footprint_expected
, footprint_after
- footprint_expected
);
868 /* mapping ledger-tagged virtual memory... */
869 get_ledger_info(&footprint_before
, &pagetable_before
);
871 kr
= mach_vm_map(mach_task_self(), &vm_addr
, vm_size
,
877 VM_PROT_READ
| VM_PROT_WRITE
,
878 VM_PROT_READ
| VM_PROT_WRITE
,
881 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_map() error 0x%x (%s)",
882 kr
, mach_error_string(kr
));
884 T_EXPECT_EQ(vm_addr
, pre_vm_addr
, "pre-warm mishap");
885 /* ... should not change footprint */
886 get_ledger_info(&footprint_after
, &pagetable_after
);
887 footprint_expected
= footprint_before
;
888 footprint_expected
+= (pagetable_after
- pagetable_before
);
889 T_LOG("mapping ledger-tagged memory does not change phys_footprint");
890 T_EXPECT_EQ(footprint_after
, footprint_expected
,
891 "ledger-tagged mapping of %lld bytes: "
892 "footprint %lld -> %lld expected %lld delta %lld",
893 vm_size
, footprint_before
, footprint_after
,
894 footprint_expected
, footprint_after
- footprint_expected
);
896 /* touching memory... */
897 get_ledger_info(&footprint_before
, &pagetable_before
);
898 dirty_size
= vm_size
/ 2;
899 memset((char *)(uintptr_t)vm_addr
, 'x', (size_t)dirty_size
);
900 /* ... should increase footprint */
901 get_ledger_info(&footprint_after
, &pagetable_after
);
902 footprint_expected
= footprint_before
+ dirty_size
;
903 footprint_expected
+= (pagetable_after
- pagetable_before
);
904 T_LOG("modifying ledger-tagged memory increases phys_footprint");
905 T_EXPECT_EQ(footprint_after
, footprint_expected
,
906 "touched %lld bytes: "
907 "footprint %lld -> %lld expected %lld delta %lld",
908 dirty_size
, footprint_before
, footprint_after
,
909 footprint_expected
, footprint_after
- footprint_expected
);
911 /* deallocating memory while holding memory entry... */
912 get_ledger_info(&footprint_before
, &pagetable_before
);
913 kr
= mach_vm_deallocate(mach_task_self(), vm_addr
, vm_size
);
915 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "vm_deallocate() error 0x%x (%s)",
916 kr
, mach_error_string(kr
));
917 /* ... should not change footprint */
918 get_ledger_info(&footprint_after
, &pagetable_after
);
919 footprint_expected
= footprint_before
;
920 footprint_expected
+= (pagetable_after
- pagetable_before
);
921 T_LOG("deallocating owned memory while holding memory entry "
922 "does not change phys_footprint");
923 T_EXPECT_EQ(footprint_after
, footprint_expected
,
924 "deallocated %lld dirty bytes: "
925 "footprint %lld -> %lld expected %lld delta %lld",
926 dirty_size
, footprint_before
, footprint_after
,
927 footprint_expected
, footprint_after
- footprint_expected
);
929 /* releasing the memory entry... */
930 kr
= mach_port_deallocate(mach_task_self(), me_port
);
932 T_EXPECT_EQ(kr
, KERN_SUCCESS
, "mach_port_deallocate() error 0x%x (%s)",
933 kr
, mach_error_string(kr
));
934 /* ... should decrease footprint */
935 get_ledger_info(&footprint_after
, &pagetable_after
);
936 footprint_expected
= footprint_before
- dirty_size
;
937 footprint_expected
+= (pagetable_after
- pagetable_before
);
938 T_LOG("releasing memory entry decreases phys_footprint");
939 T_EXPECT_EQ(footprint_after
, footprint_expected
,
940 "made volatile %lld dirty bytes: "
941 "footprint %lld -> %lld expected %lld delta %lld",
942 dirty_size
, footprint_before
, footprint_after
,
943 footprint_expected
, footprint_after
- footprint_expected
);
945 #endif /* MAP_MEM_LEDGER_TAGGED */
947 /* IOSurface code from: CoreImage/CoreImageTests/CIRender/SurfaceUtils.c */
948 #include <CoreFoundation/CoreFoundation.h>
949 #include <IOSurface/IOSurface.h>
950 #include <IOSurface/IOSurfacePrivate.h>
952 bytes_per_element(uint32_t format
)
956 case 32: // kCVPixelFormatType_32ARGB (ARGB8)
966 bytes_per_pixel(uint32_t format
)
970 case 32: // kCVPixelFormatType_32ARGB (ARGB8)
980 roundSizeToMultiple(size_t size
, size_t mult
)
982 return ((size
+ mult
- 1) / mult
) * mult
;
985 setIntValue(CFMutableDictionaryRef dict
, const CFStringRef key
, int value
)
987 CFNumberRef number
= CFNumberCreate(0, kCFNumberIntType
, &value
);
988 CFDictionarySetValue(dict
, key
, number
);
991 typedef void (^SurfacePlaneBlock
)(void *data
, size_t planeIndex
, size_t width
, size_t height
, size_t rowbytes
);
993 SurfaceApplyPlaneBlock(IOSurfaceRef surface
, SurfacePlaneBlock block
)
995 if (surface
== nil
|| block
== nil
) {
996 return kIOReturnBadArgument
;
999 IOReturn result
= kIOReturnSuccess
;
1000 size_t planeCount
= IOSurfaceGetPlaneCount(surface
);
1002 if (planeCount
== 0) {
1003 result
= IOSurfaceLock(surface
, 0, NULL
);
1004 if (result
!= kIOReturnSuccess
) {
1008 void* base
= IOSurfaceGetBaseAddress(surface
);
1009 size_t rb
= IOSurfaceGetBytesPerRow(surface
);
1010 size_t w
= IOSurfaceGetWidth(surface
);
1011 size_t h
= IOSurfaceGetHeight(surface
);
1013 if (base
&& rb
&& w
&& h
) {
1014 block(base
, 0, w
, h
, rb
);
1017 IOSurfaceUnlock(surface
, 0, NULL
);
1018 } else if (planeCount
== 2) {
1019 for (size_t i
= 0; i
< planeCount
; i
++) {
1020 result
= IOSurfaceLock(surface
, 0, NULL
);
1021 if (result
!= kIOReturnSuccess
) {
1025 void* base
= IOSurfaceGetBaseAddressOfPlane(surface
, i
);
1026 size_t rb
= IOSurfaceGetBytesPerRowOfPlane(surface
, i
);
1027 size_t w
= IOSurfaceGetWidthOfPlane(surface
, i
);
1028 size_t h
= IOSurfaceGetHeightOfPlane(surface
, i
);
1030 if (base
&& rb
&& w
&& h
) {
1031 block(base
, i
, w
, h
, rb
);
1034 IOSurfaceUnlock(surface
, 0, NULL
);
1040 ClearSurface(IOSurfaceRef surface
)
1043 (void) SurfaceApplyPlaneBlock(surface
, ^(void *p
, size_t i
, __unused
size_t w
, size_t h
, size_t rb
)
1046 memset(p
, zero
, rb
* h
);
1048 memset(p
, 128, rb
* h
);
1053 CreateSurface(uint32_t pixelsWide
, uint32_t pixelsHigh
, uint32_t rowBytesAlignment
, uint32_t fmt
, bool purgeable
, bool clear
)
1055 IOSurfaceRef surface
= nil
;
1057 if (pixelsWide
< 1 || pixelsHigh
< 1 || fmt
== 0) {
1061 size_t bpp
= bytes_per_pixel(fmt
);
1062 size_t bpe
= bytes_per_element(fmt
);
1063 if (bpp
== 0 || bpe
== 0) {
1067 size_t rowbytes
= pixelsWide
* bpp
;
1068 if (rowBytesAlignment
== 0) {
1069 rowBytesAlignment
= 16;
1071 rowbytes
= roundSizeToMultiple(rowbytes
, rowBytesAlignment
);
1073 CFMutableDictionaryRef props
= CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1074 setIntValue(props
, kIOSurfaceBytesPerRow
, (int)rowbytes
);
1075 setIntValue(props
, kIOSurfaceWidth
, (int)pixelsWide
);
1076 setIntValue(props
, kIOSurfaceHeight
, (int)pixelsHigh
);
1077 setIntValue(props
, kIOSurfacePixelFormat
, (int)fmt
);
1078 #if TARGET_OS_IPHONE
1079 setIntValue(props
, kIOSurfaceNonPurgeable
, purgeable
);
1080 #else /* TARGET_OS_IPHONE */
1082 #endif /* TARGET_OS_IPHONE */
1084 if (bpe
!= bpp
) { // i.e. a 422 format such as 'yuvf' etc.
1085 setIntValue(props
, kIOSurfaceElementWidth
, 2);
1086 setIntValue(props
, kIOSurfaceElementHeight
, 1);
1088 setIntValue(props
, kIOSurfaceBytesPerElement
, (int)bpe
);
1091 surface
= IOSurfaceCreate(props
);
1094 ClearSurface(surface
);
1100 T_DECL(phys_footprint_purgeable_iokit
,
1101 "phys_footprint for purgeable IOKit memory",
1102 T_META_NAMESPACE("xnu.vm"),
1103 T_META_LTEPHASE(LTE_POSTINIT
))
1105 uint64_t footprint_before
, pagetable_before
;
1106 uint64_t footprint_after
, pagetable_after
;
1107 uint64_t footprint_expected
;
1108 IOSurfaceRef surface
;
1110 uint64_t surface_size
;
1114 surface
= CreateSurface(1024, 1024, 0, 32, true, true);
1115 IOSurfaceSetPurgeable(surface
, kIOSurfacePurgeableVolatile
, &old_state
);
1116 IOSurfaceSetPurgeable(surface
, kIOSurfacePurgeableNonVolatile
, &old_state
);
1120 surface_size
= 1024 * 1024 * 4;
1122 /* create IOsurface: footprint grows */
1123 get_ledger_info(&footprint_before
, &pagetable_before
);
1124 surface
= CreateSurface(1024, 1024, 0, 32, true, true);
1125 get_ledger_info(&footprint_after
, &pagetable_after
);
1126 #if LEGACY_FOOTPRINT
1127 footprint_expected
= footprint_before
;
1128 footprint_expected
+= (pagetable_after
- pagetable_before
);
1129 T_LOG("LEGACY FOOTPRINT: creating IOSurface: no footprint impact");
1130 T_EXPECT_EQ(footprint_after
, footprint_expected
,
1131 "create IOSurface %lld bytes: "
1132 "footprint %lld -> %lld expected %lld delta %lld",
1133 surface_size
, footprint_before
, footprint_after
,
1134 footprint_expected
, footprint_after
- footprint_expected
);
1135 #else /* LEGACY_FOOTPRINT */
1136 footprint_expected
= footprint_before
+ surface_size
;
1137 footprint_expected
+= (pagetable_after
- pagetable_before
);
1138 T_LOG("creating IOSurface increases phys_footprint");
1139 T_EXPECT_EQ(footprint_after
, footprint_expected
,
1140 "create IOSurface %lld bytes: "
1141 "footprint %lld -> %lld expected %lld delta %lld",
1142 surface_size
, footprint_before
, footprint_after
,
1143 footprint_expected
, footprint_after
- footprint_expected
);
1144 #endif /* LEGACY_FOOTPRINT */
1146 /* make IOSurface volatile: footprint shrinks */
1147 get_ledger_info(&footprint_before
, &pagetable_before
);
1148 IOSurfaceSetPurgeable(surface
, kIOSurfacePurgeableVolatile
, &old_state
);
1149 get_ledger_info(&footprint_after
, &pagetable_after
);
1150 #if LEGACY_FOOTPRINT
1151 footprint_expected
= footprint_before
;
1152 footprint_expected
+= (pagetable_after
- pagetable_before
);
1153 T_LOG("LEGACY FOOTPRINT: volatile IOSurface: no footprint impact");
1154 T_EXPECT_EQ(footprint_after
, footprint_expected
,
1155 "volatile IOSurface %lld bytes: "
1156 "footprint %lld -> %lld expected %lld delta %lld",
1157 surface_size
, footprint_before
, footprint_after
,
1158 footprint_expected
, footprint_after
- footprint_expected
);
1159 #else /* LEGACY_FOOTPRINT */
1160 footprint_expected
= footprint_before
- surface_size
;
1161 footprint_expected
+= (pagetable_after
- pagetable_before
);
1162 T_LOG("making IOSurface volatile decreases phys_footprint");
1163 T_EXPECT_EQ(footprint_after
, footprint_expected
,
1164 "made volatile %lld bytes: "
1165 "footprint %lld -> %lld expected %lld delta %lld",
1166 surface_size
, footprint_before
, footprint_after
,
1167 footprint_expected
, footprint_after
- footprint_expected
);
1168 #endif /* LEGACY_FOOTPRINT */
1170 /* make IOSurface non-volatile: footprint grows */
1171 get_ledger_info(&footprint_before
, &pagetable_before
);
1172 IOSurfaceSetPurgeable(surface
, kIOSurfacePurgeableNonVolatile
, &old_state
);
1173 get_ledger_info(&footprint_after
, &pagetable_after
);
1174 #if LEGACY_FOOTPRINT
1175 footprint_expected
= footprint_before
;
1176 footprint_expected
+= (pagetable_after
- pagetable_before
);
1177 T_LOG("LEGACY FOOTPRINT: non-volatile IOSurface: no footprint impact");
1178 T_EXPECT_EQ(footprint_after
, footprint_expected
,
1179 "non-volatile IOSurface %lld bytes: "
1180 "footprint %lld -> %lld expected %lld delta %lld",
1181 surface_size
, footprint_before
, footprint_after
,
1182 footprint_expected
, footprint_after
- footprint_expected
);
1183 #else /* LEGACY_FOOTPRINT */
1184 footprint_expected
= footprint_before
+ surface_size
;
1185 footprint_expected
+= (pagetable_after
- pagetable_before
);
1186 T_LOG("making IOSurface non-volatile increases phys_footprint");
1187 T_EXPECT_EQ(footprint_after
, footprint_expected
,
1188 "made non-volatile %lld bytes: "
1189 "footprint %lld -> %lld expected %lld delta %lld",
1190 surface_size
, footprint_before
, footprint_after
,
1191 footprint_expected
, footprint_after
- footprint_expected
);
1192 #endif /* LEGACY_FOOTPRINT */
1194 /* accessing IOSurface re-mapping: no footprint impact */
1196 /* deallocating IOSurface re-mapping: no footprint impact */
1198 /* release IOSurface: footprint shrinks */
1199 get_ledger_info(&footprint_before
, &pagetable_before
);
1201 get_ledger_info(&footprint_after
, &pagetable_after
);
1202 #if LEGACY_FOOTPRINT
1203 footprint_expected
= footprint_before
;
1204 footprint_expected
+= (pagetable_after
- pagetable_before
);
1205 T_LOG("LEGACY FOOTPRINT: release IOSurface: no footprint impact");
1206 T_EXPECT_EQ(footprint_after
, footprint_expected
,
1207 "releasing IOSurface %lld bytes: "
1208 "footprint %lld -> %lld expected %lld delta %lld",
1209 surface_size
, footprint_before
, footprint_after
,
1210 footprint_expected
, footprint_after
- footprint_expected
);
1211 #else /* LEGACY_FOOTPRINT */
1212 footprint_expected
= footprint_before
- surface_size
;
1213 footprint_expected
+= (pagetable_after
- pagetable_before
);
1214 T_LOG("releasing IOSurface decreases phys_footprint");
1215 T_EXPECT_EQ(footprint_after
, footprint_expected
,
1216 "released IOSurface %lld bytes: "
1217 "footprint %lld -> %lld expected %lld delta %lld",
1218 surface_size
, footprint_before
, footprint_after
,
1219 footprint_expected
, footprint_after
- footprint_expected
);
1220 #endif /* LEGACY_FOOTPRINT */