1*94d3b452SApple OSS Distributions #include <darwintest.h>
2*94d3b452SApple OSS Distributions #include <darwintest_utils.h>
3*94d3b452SApple OSS Distributions
4*94d3b452SApple OSS Distributions #include <mach/mach_error.h>
5*94d3b452SApple OSS Distributions #include <mach/mach_init.h>
6*94d3b452SApple OSS Distributions #include <mach/memory_entry.h>
7*94d3b452SApple OSS Distributions #include <mach/mach_port.h>
8*94d3b452SApple OSS Distributions #include <mach/mach_vm.h>
9*94d3b452SApple OSS Distributions #include <mach/memory_entry.h>
10*94d3b452SApple OSS Distributions #include <mach/task.h>
11*94d3b452SApple OSS Distributions #include <mach/task_info.h>
12*94d3b452SApple OSS Distributions #include <mach/vm_map.h>
13*94d3b452SApple OSS Distributions
14*94d3b452SApple OSS Distributions #include <sys/kern_memorystatus.h>
15*94d3b452SApple OSS Distributions #include <sys/mman.h>
16*94d3b452SApple OSS Distributions #include <sys/types.h>
17*94d3b452SApple OSS Distributions #include <sys/sysctl.h>
18*94d3b452SApple OSS Distributions
19*94d3b452SApple OSS Distributions #include <TargetConditionals.h>
20*94d3b452SApple OSS Distributions
21*94d3b452SApple OSS Distributions #include <Kernel/kern/ledger.h>
22*94d3b452SApple OSS Distributions extern int ledger(int cmd, caddr_t arg1, caddr_t arg2, caddr_t arg3);
23*94d3b452SApple OSS Distributions
24*94d3b452SApple OSS Distributions T_GLOBAL_META(T_META_RUN_CONCURRENTLY(true));
25*94d3b452SApple OSS Distributions static boolean_t legacy_footprint = FALSE;
26*94d3b452SApple OSS Distributions
27*94d3b452SApple OSS Distributions #if LEGACY_FOOTPRINT_ENTITLED && defined(__arm64__)
28*94d3b452SApple OSS Distributions #define TEST_VM_NAMESPACE "xnu.vm_legacy"
29*94d3b452SApple OSS Distributions #else /* ENTITLED && __arm64__ */
30*94d3b452SApple OSS Distributions #define TEST_VM_NAMESPACE "xnu.vm"
31*94d3b452SApple OSS Distributions #endif /* ENTITLED && __arm64__ */
32*94d3b452SApple OSS Distributions
33*94d3b452SApple OSS Distributions T_GLOBAL_META(
34*94d3b452SApple OSS Distributions T_META_NAMESPACE(TEST_VM_NAMESPACE),
35*94d3b452SApple OSS Distributions T_META_RADAR_COMPONENT_NAME("xnu"),
36*94d3b452SApple OSS Distributions T_META_RADAR_COMPONENT_VERSION("VM"),
37*94d3b452SApple OSS Distributions T_META_RUN_CONCURRENTLY(true));
38*94d3b452SApple OSS Distributions
39*94d3b452SApple OSS Distributions #define MEM_SIZE (100 * 1024 * 1024) /* 100 MB */
40*94d3b452SApple OSS Distributions
41*94d3b452SApple OSS Distributions static int64_t ledger_count = -1;
42*94d3b452SApple OSS Distributions static int footprint_index = -1;
43*94d3b452SApple OSS Distributions static int pagetable_index = -1;
44*94d3b452SApple OSS Distributions static struct ledger_entry_info *lei = NULL;
45*94d3b452SApple OSS Distributions
46*94d3b452SApple OSS Distributions static void
ledger_init(void)47*94d3b452SApple OSS Distributions ledger_init(void)
48*94d3b452SApple OSS Distributions {
49*94d3b452SApple OSS Distributions static int ledger_inited = 0;
50*94d3b452SApple OSS Distributions struct ledger_info li;
51*94d3b452SApple OSS Distributions struct ledger_template_info *templateInfo;
52*94d3b452SApple OSS Distributions int64_t templateCnt;
53*94d3b452SApple OSS Distributions int i;
54*94d3b452SApple OSS Distributions
55*94d3b452SApple OSS Distributions if (ledger_inited) {
56*94d3b452SApple OSS Distributions return;
57*94d3b452SApple OSS Distributions }
58*94d3b452SApple OSS Distributions ledger_inited = 1;
59*94d3b452SApple OSS Distributions
60*94d3b452SApple OSS Distributions T_SETUPBEGIN;
61*94d3b452SApple OSS Distributions
62*94d3b452SApple OSS Distributions legacy_footprint = FALSE;
63*94d3b452SApple OSS Distributions #if LEGACY_FOOTPRINT_ENTITLED
64*94d3b452SApple OSS Distributions int legacy_footprint_entitlement_mode;
65*94d3b452SApple OSS Distributions size_t oldlen;
66*94d3b452SApple OSS Distributions int ret;
67*94d3b452SApple OSS Distributions
68*94d3b452SApple OSS Distributions T_QUIET;
69*94d3b452SApple OSS Distributions T_WITH_ERRNO;
70*94d3b452SApple OSS Distributions oldlen = sizeof(legacy_footprint_entitlement_mode);
71*94d3b452SApple OSS Distributions ret = sysctlbyname("kern.legacy_footprint_entitlement_mode",
72*94d3b452SApple OSS Distributions &legacy_footprint_entitlement_mode,
73*94d3b452SApple OSS Distributions &oldlen,
74*94d3b452SApple OSS Distributions NULL,
75*94d3b452SApple OSS Distributions 0);
76*94d3b452SApple OSS Distributions if (ret == 0 && legacy_footprint_entitlement_mode == 2) {
77*94d3b452SApple OSS Distributions legacy_footprint = TRUE;
78*94d3b452SApple OSS Distributions }
79*94d3b452SApple OSS Distributions #endif /* LEGACY_FOOTPRINT_ENTITLED */
80*94d3b452SApple OSS Distributions
81*94d3b452SApple OSS Distributions T_QUIET;
82*94d3b452SApple OSS Distributions T_WITH_ERRNO;
83*94d3b452SApple OSS Distributions T_ASSERT_EQ(ledger(LEDGER_INFO,
84*94d3b452SApple OSS Distributions (caddr_t)(uintptr_t)getpid(),
85*94d3b452SApple OSS Distributions (caddr_t)&li,
86*94d3b452SApple OSS Distributions NULL),
87*94d3b452SApple OSS Distributions 0,
88*94d3b452SApple OSS Distributions "ledger(LEDGER_INFO)");
89*94d3b452SApple OSS Distributions
90*94d3b452SApple OSS Distributions templateCnt = li.li_entries;
91*94d3b452SApple OSS Distributions templateInfo = malloc((size_t)li.li_entries * sizeof(struct ledger_template_info));
92*94d3b452SApple OSS Distributions T_QUIET;
93*94d3b452SApple OSS Distributions T_WITH_ERRNO;
94*94d3b452SApple OSS Distributions T_ASSERT_NE(templateInfo, NULL, "malloc()");
95*94d3b452SApple OSS Distributions
96*94d3b452SApple OSS Distributions ledger_count = li.li_entries;
97*94d3b452SApple OSS Distributions footprint_index = -1;
98*94d3b452SApple OSS Distributions pagetable_index = -1;
99*94d3b452SApple OSS Distributions T_QUIET;
100*94d3b452SApple OSS Distributions T_WITH_ERRNO;
101*94d3b452SApple OSS Distributions T_ASSERT_GE(ledger(LEDGER_TEMPLATE_INFO,
102*94d3b452SApple OSS Distributions (caddr_t)templateInfo,
103*94d3b452SApple OSS Distributions (caddr_t)&templateCnt,
104*94d3b452SApple OSS Distributions NULL),
105*94d3b452SApple OSS Distributions 0,
106*94d3b452SApple OSS Distributions "ledger(LEDGER_TEMPLATE_INFO)");
107*94d3b452SApple OSS Distributions for (i = 0; i < templateCnt; i++) {
108*94d3b452SApple OSS Distributions if (!strncmp(templateInfo[i].lti_name,
109*94d3b452SApple OSS Distributions "phys_footprint",
110*94d3b452SApple OSS Distributions strlen("phys_footprint"))) {
111*94d3b452SApple OSS Distributions footprint_index = i;
112*94d3b452SApple OSS Distributions } else if (!strncmp(templateInfo[i].lti_name,
113*94d3b452SApple OSS Distributions "page_table",
114*94d3b452SApple OSS Distributions strlen("page_table"))) {
115*94d3b452SApple OSS Distributions pagetable_index = i;
116*94d3b452SApple OSS Distributions }
117*94d3b452SApple OSS Distributions }
118*94d3b452SApple OSS Distributions free(templateInfo);
119*94d3b452SApple OSS Distributions
120*94d3b452SApple OSS Distributions lei = (struct ledger_entry_info *)
121*94d3b452SApple OSS Distributions malloc((size_t)ledger_count * sizeof(*lei));
122*94d3b452SApple OSS Distributions T_QUIET;
123*94d3b452SApple OSS Distributions T_WITH_ERRNO;
124*94d3b452SApple OSS Distributions T_ASSERT_NE(lei, NULL, "malloc(ledger_entry_info)");
125*94d3b452SApple OSS Distributions
126*94d3b452SApple OSS Distributions T_QUIET;
127*94d3b452SApple OSS Distributions T_ASSERT_NE(footprint_index, -1, "no footprint_index");
128*94d3b452SApple OSS Distributions T_QUIET;
129*94d3b452SApple OSS Distributions T_ASSERT_NE(pagetable_index, -1, "no pagetable_index");
130*94d3b452SApple OSS Distributions
131*94d3b452SApple OSS Distributions T_SETUPEND;
132*94d3b452SApple OSS Distributions }
133*94d3b452SApple OSS Distributions
134*94d3b452SApple OSS Distributions static void
get_ledger_info(uint64_t * phys_footprint,uint64_t * page_table)135*94d3b452SApple OSS Distributions get_ledger_info(
136*94d3b452SApple OSS Distributions uint64_t *phys_footprint,
137*94d3b452SApple OSS Distributions uint64_t *page_table)
138*94d3b452SApple OSS Distributions {
139*94d3b452SApple OSS Distributions int64_t count;
140*94d3b452SApple OSS Distributions
141*94d3b452SApple OSS Distributions count = ledger_count;
142*94d3b452SApple OSS Distributions T_QUIET;
143*94d3b452SApple OSS Distributions T_WITH_ERRNO;
144*94d3b452SApple OSS Distributions T_ASSERT_GE(ledger(LEDGER_ENTRY_INFO,
145*94d3b452SApple OSS Distributions (caddr_t)(uintptr_t)getpid(),
146*94d3b452SApple OSS Distributions (caddr_t)lei,
147*94d3b452SApple OSS Distributions (caddr_t)&count),
148*94d3b452SApple OSS Distributions 0,
149*94d3b452SApple OSS Distributions "ledger(LEDGER_ENTRY_INFO)");
150*94d3b452SApple OSS Distributions T_QUIET;
151*94d3b452SApple OSS Distributions T_ASSERT_GT(count, (int64_t)footprint_index, "no entry for footprint");
152*94d3b452SApple OSS Distributions T_QUIET;
153*94d3b452SApple OSS Distributions T_ASSERT_GT(count, (int64_t)pagetable_index, "no entry for pagetable");
154*94d3b452SApple OSS Distributions if (phys_footprint) {
155*94d3b452SApple OSS Distributions *phys_footprint = (uint64_t)(lei[footprint_index].lei_balance);
156*94d3b452SApple OSS Distributions }
157*94d3b452SApple OSS Distributions if (page_table) {
158*94d3b452SApple OSS Distributions *page_table = (uint64_t)(lei[pagetable_index].lei_balance);
159*94d3b452SApple OSS Distributions }
160*94d3b452SApple OSS Distributions }
161*94d3b452SApple OSS Distributions
162*94d3b452SApple OSS Distributions static mach_vm_address_t
pre_warm_with_tag(mach_vm_size_t vm_size,int tag)163*94d3b452SApple OSS Distributions pre_warm_with_tag(
164*94d3b452SApple OSS Distributions mach_vm_size_t vm_size,
165*94d3b452SApple OSS Distributions int tag)
166*94d3b452SApple OSS Distributions {
167*94d3b452SApple OSS Distributions kern_return_t kr;
168*94d3b452SApple OSS Distributions mach_vm_address_t vm_addr;
169*94d3b452SApple OSS Distributions unsigned char BigBufOnStack[100 * 1024];
170*94d3b452SApple OSS Distributions uint64_t footprint, page_table;
171*94d3b452SApple OSS Distributions
172*94d3b452SApple OSS Distributions /* make sure ledgers are ready to be queried */
173*94d3b452SApple OSS Distributions ledger_init();
174*94d3b452SApple OSS Distributions
175*94d3b452SApple OSS Distributions T_SETUPBEGIN;
176*94d3b452SApple OSS Distributions
177*94d3b452SApple OSS Distributions /*
178*94d3b452SApple OSS Distributions * Touch a few pages ahead on the stack, to make
179*94d3b452SApple OSS Distributions * sure we don't see a footprint increase due to
180*94d3b452SApple OSS Distributions * an extra stack page later.
181*94d3b452SApple OSS Distributions */
182*94d3b452SApple OSS Distributions memset(BigBufOnStack, 0xb, sizeof(BigBufOnStack));
183*94d3b452SApple OSS Distributions T_QUIET;
184*94d3b452SApple OSS Distributions T_EXPECT_EQ(BigBufOnStack[0], 0xb,
185*94d3b452SApple OSS Distributions "BigBufOnStack[0] == 0x%x",
186*94d3b452SApple OSS Distributions BigBufOnStack[0]);
187*94d3b452SApple OSS Distributions T_QUIET;
188*94d3b452SApple OSS Distributions T_EXPECT_EQ(BigBufOnStack[sizeof(BigBufOnStack) - 1], 0xb,
189*94d3b452SApple OSS Distributions "BigBufOnStack[%lu] == 0x%x",
190*94d3b452SApple OSS Distributions sizeof(BigBufOnStack),
191*94d3b452SApple OSS Distributions BigBufOnStack[sizeof(BigBufOnStack) - 1]);
192*94d3b452SApple OSS Distributions
193*94d3b452SApple OSS Distributions /*
194*94d3b452SApple OSS Distributions * Pre-allocate, touch and then release the same amount
195*94d3b452SApple OSS Distributions * of memory we'll be allocating later during the test,
196*94d3b452SApple OSS Distributions * to account for any memory overhead (page tables, global
197*94d3b452SApple OSS Distributions * variables, ...). Supplied VM tag should ensure memory
198*94d3b452SApple OSS Distributions * is allocated in the appropriate VM range.
199*94d3b452SApple OSS Distributions */
200*94d3b452SApple OSS Distributions vm_addr = 0;
201*94d3b452SApple OSS Distributions kr = mach_vm_allocate(mach_task_self(),
202*94d3b452SApple OSS Distributions &vm_addr,
203*94d3b452SApple OSS Distributions vm_size,
204*94d3b452SApple OSS Distributions VM_FLAGS_ANYWHERE | VM_MAKE_TAG(tag));
205*94d3b452SApple OSS Distributions T_QUIET;
206*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_allocate(%lld) error 0x%x (%s)",
207*94d3b452SApple OSS Distributions vm_size, kr, mach_error_string(kr));
208*94d3b452SApple OSS Distributions memset((char *)(uintptr_t)vm_addr, 'p', (size_t)vm_size);
209*94d3b452SApple OSS Distributions kr = mach_vm_deallocate(mach_task_self(),
210*94d3b452SApple OSS Distributions vm_addr,
211*94d3b452SApple OSS Distributions vm_size);
212*94d3b452SApple OSS Distributions T_QUIET;
213*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_deallocate() error 0x%x (%s)",
214*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
215*94d3b452SApple OSS Distributions
216*94d3b452SApple OSS Distributions /*
217*94d3b452SApple OSS Distributions * Exercise the ledger code to make sure it's ready to run
218*94d3b452SApple OSS Distributions * without any extra memory overhead later.
219*94d3b452SApple OSS Distributions */
220*94d3b452SApple OSS Distributions get_ledger_info(&footprint, &page_table);
221*94d3b452SApple OSS Distributions
222*94d3b452SApple OSS Distributions T_SETUPEND;
223*94d3b452SApple OSS Distributions
224*94d3b452SApple OSS Distributions /*
225*94d3b452SApple OSS Distributions * Return the start of the virtual range we pre-warmed, so that the
226*94d3b452SApple OSS Distributions * test can check that it's using the same range.
227*94d3b452SApple OSS Distributions */
228*94d3b452SApple OSS Distributions return vm_addr;
229*94d3b452SApple OSS Distributions }
230*94d3b452SApple OSS Distributions
231*94d3b452SApple OSS Distributions static mach_vm_address_t
pre_warm(mach_vm_size_t vm_size)232*94d3b452SApple OSS Distributions pre_warm(
233*94d3b452SApple OSS Distributions mach_vm_size_t vm_size)
234*94d3b452SApple OSS Distributions {
235*94d3b452SApple OSS Distributions /*
236*94d3b452SApple OSS Distributions * Default to not tagging pre_warm memory.
237*94d3b452SApple OSS Distributions */
238*94d3b452SApple OSS Distributions return pre_warm_with_tag(vm_size, 0);
239*94d3b452SApple OSS Distributions }
240*94d3b452SApple OSS Distributions
241*94d3b452SApple OSS Distributions T_DECL(phys_footprint_anonymous,
242*94d3b452SApple OSS Distributions "phys_footprint for anonymous memory",
243*94d3b452SApple OSS Distributions T_META_LTEPHASE(LTE_POSTINIT))
244*94d3b452SApple OSS Distributions {
245*94d3b452SApple OSS Distributions uint64_t footprint_before, pagetable_before;
246*94d3b452SApple OSS Distributions uint64_t footprint_after, pagetable_after;
247*94d3b452SApple OSS Distributions uint64_t footprint_expected;
248*94d3b452SApple OSS Distributions kern_return_t kr;
249*94d3b452SApple OSS Distributions mach_vm_address_t pre_vm_addr, vm_addr;
250*94d3b452SApple OSS Distributions mach_vm_size_t vm_size, dirty_size;
251*94d3b452SApple OSS Distributions
252*94d3b452SApple OSS Distributions /* pre-warm to account for page table expansion */
253*94d3b452SApple OSS Distributions pre_vm_addr = pre_warm(MEM_SIZE);
254*94d3b452SApple OSS Distributions
255*94d3b452SApple OSS Distributions /* allocating virtual memory... */
256*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
257*94d3b452SApple OSS Distributions vm_addr = 0;
258*94d3b452SApple OSS Distributions vm_size = MEM_SIZE;
259*94d3b452SApple OSS Distributions kr = mach_vm_allocate(mach_task_self(), &vm_addr, vm_size,
260*94d3b452SApple OSS Distributions VM_FLAGS_ANYWHERE);
261*94d3b452SApple OSS Distributions T_QUIET;
262*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_allocate() error 0x%x (%s)",
263*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
264*94d3b452SApple OSS Distributions T_QUIET;
265*94d3b452SApple OSS Distributions T_EXPECT_EQ(vm_addr, pre_vm_addr, "pre-warm mishap");
266*94d3b452SApple OSS Distributions /* ... should not change footprint */
267*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
268*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
269*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
270*94d3b452SApple OSS Distributions T_LOG("virtual allocation does not change phys_footprint");
271*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
272*94d3b452SApple OSS Distributions "virtual allocation of %lld bytes: "
273*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
274*94d3b452SApple OSS Distributions vm_size, footprint_before, footprint_after,
275*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
276*94d3b452SApple OSS Distributions
277*94d3b452SApple OSS Distributions /* touching memory... */
278*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
279*94d3b452SApple OSS Distributions dirty_size = vm_size / 2;
280*94d3b452SApple OSS Distributions memset((char *)(uintptr_t)vm_addr, 'x', (size_t)dirty_size);
281*94d3b452SApple OSS Distributions /* ... should increase footprint */
282*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
283*94d3b452SApple OSS Distributions footprint_expected = footprint_before + dirty_size;
284*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
285*94d3b452SApple OSS Distributions T_LOG("modifying anonymous memory increases phys_footprint");
286*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
287*94d3b452SApple OSS Distributions "touched %lld bytes: "
288*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
289*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
290*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
291*94d3b452SApple OSS Distributions
292*94d3b452SApple OSS Distributions /* deallocating memory... */
293*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
294*94d3b452SApple OSS Distributions kr = mach_vm_deallocate(mach_task_self(), vm_addr, vm_size);
295*94d3b452SApple OSS Distributions T_QUIET;
296*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_deallocate() error 0x%x (%s)",
297*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
298*94d3b452SApple OSS Distributions /* ... should decrease footprint */
299*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
300*94d3b452SApple OSS Distributions footprint_expected = footprint_before - dirty_size;
301*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
302*94d3b452SApple OSS Distributions T_LOG("deallocating dirty anonymous memory decreases phys_footprint");
303*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
304*94d3b452SApple OSS Distributions "deallocated %lld dirty bytes: "
305*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
306*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
307*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
308*94d3b452SApple OSS Distributions }
309*94d3b452SApple OSS Distributions
310*94d3b452SApple OSS Distributions #define TEMP_FILE_TEMPLATE "/tmp/phys_footprint_data.XXXXXXXX"
311*94d3b452SApple OSS Distributions #define TEMP_FILE_SIZE (1 * 1024 * 1024)
312*94d3b452SApple OSS Distributions
313*94d3b452SApple OSS Distributions T_DECL(phys_footprint_file,
314*94d3b452SApple OSS Distributions "phys_footprint for mapped file",
315*94d3b452SApple OSS Distributions T_META_LTEPHASE(LTE_POSTINIT))
316*94d3b452SApple OSS Distributions {
317*94d3b452SApple OSS Distributions uint64_t footprint_before, pagetable_before;
318*94d3b452SApple OSS Distributions uint64_t footprint_after, pagetable_after;
319*94d3b452SApple OSS Distributions uint64_t footprint_expected;
320*94d3b452SApple OSS Distributions mach_vm_address_t pre_vm_addr;
321*94d3b452SApple OSS Distributions int fd;
322*94d3b452SApple OSS Distributions char *map_addr;
323*94d3b452SApple OSS Distributions size_t map_size, dirty_size;
324*94d3b452SApple OSS Distributions ssize_t nbytes;
325*94d3b452SApple OSS Distributions char tmp_file_name[PATH_MAX] = TEMP_FILE_TEMPLATE;
326*94d3b452SApple OSS Distributions char *buf;
327*94d3b452SApple OSS Distributions size_t buf_size;
328*94d3b452SApple OSS Distributions
329*94d3b452SApple OSS Distributions T_SETUPBEGIN;
330*94d3b452SApple OSS Distributions buf_size = TEMP_FILE_SIZE;
331*94d3b452SApple OSS Distributions T_QUIET;
332*94d3b452SApple OSS Distributions T_ASSERT_NOTNULL(buf = (char *)malloc(buf_size),
333*94d3b452SApple OSS Distributions "allocate %zu-byte buffer", buf_size);
334*94d3b452SApple OSS Distributions memset(buf, 'f', buf_size);
335*94d3b452SApple OSS Distributions T_WITH_ERRNO;
336*94d3b452SApple OSS Distributions T_QUIET;
337*94d3b452SApple OSS Distributions T_ASSERT_NOTNULL(mktemp(tmp_file_name),
338*94d3b452SApple OSS Distributions "create temporary file name");
339*94d3b452SApple OSS Distributions T_WITH_ERRNO;
340*94d3b452SApple OSS Distributions T_QUIET;
341*94d3b452SApple OSS Distributions T_ASSERT_GE(fd = open(tmp_file_name, O_CREAT | O_RDWR),
342*94d3b452SApple OSS Distributions 0,
343*94d3b452SApple OSS Distributions "create temp file");
344*94d3b452SApple OSS Distributions T_WITH_ERRNO;
345*94d3b452SApple OSS Distributions T_QUIET;
346*94d3b452SApple OSS Distributions T_ASSERT_EQ(nbytes = write(fd, buf, buf_size),
347*94d3b452SApple OSS Distributions (ssize_t)buf_size,
348*94d3b452SApple OSS Distributions "write %zu bytes", buf_size);
349*94d3b452SApple OSS Distributions free(buf);
350*94d3b452SApple OSS Distributions T_SETUPEND;
351*94d3b452SApple OSS Distributions
352*94d3b452SApple OSS Distributions /* pre-warm to account for page table expansion */
353*94d3b452SApple OSS Distributions #if TARGET_OS_OSX
354*94d3b452SApple OSS Distributions pre_vm_addr = pre_warm_with_tag(TEMP_FILE_SIZE, VM_MEMORY_MALLOC);
355*94d3b452SApple OSS Distributions #else
356*94d3b452SApple OSS Distributions pre_vm_addr = pre_warm_with_tag(TEMP_FILE_SIZE, VM_MEMORY_MALLOC_TINY);
357*94d3b452SApple OSS Distributions #endif
358*94d3b452SApple OSS Distributions
359*94d3b452SApple OSS Distributions /* mapping a file does not impact footprint... */
360*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
361*94d3b452SApple OSS Distributions map_size = TEMP_FILE_SIZE;
362*94d3b452SApple OSS Distributions T_WITH_ERRNO;
363*94d3b452SApple OSS Distributions T_QUIET;
364*94d3b452SApple OSS Distributions T_ASSERT_NOTNULL(map_addr = (char *)mmap(NULL, map_size,
365*94d3b452SApple OSS Distributions PROT_READ | PROT_WRITE,
366*94d3b452SApple OSS Distributions MAP_FILE | MAP_SHARED, fd, 0),
367*94d3b452SApple OSS Distributions "mmap()");
368*94d3b452SApple OSS Distributions T_QUIET;
369*94d3b452SApple OSS Distributions T_EXPECT_EQ((mach_vm_address_t)map_addr, pre_vm_addr,
370*94d3b452SApple OSS Distributions "pre-warm mishap");
371*94d3b452SApple OSS Distributions /* ... should not change footprint */
372*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
373*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
374*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
375*94d3b452SApple OSS Distributions T_LOG("mapping file does not change phys_footprint");
376*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
377*94d3b452SApple OSS Distributions "mapping file with %zu bytes: "
378*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
379*94d3b452SApple OSS Distributions map_size, footprint_before, footprint_after,
380*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
381*94d3b452SApple OSS Distributions
382*94d3b452SApple OSS Distributions /* touching file-backed memory... */
383*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
384*94d3b452SApple OSS Distributions dirty_size = map_size / 2;
385*94d3b452SApple OSS Distributions memset(map_addr, 'F', dirty_size);
386*94d3b452SApple OSS Distributions /* ... should not impact footprint */
387*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
388*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
389*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
390*94d3b452SApple OSS Distributions T_LOG("modifying file-backed memory does not impact phys_footprint");
391*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
392*94d3b452SApple OSS Distributions "touched %zu bytes: "
393*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
394*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
395*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
396*94d3b452SApple OSS Distributions
397*94d3b452SApple OSS Distributions /* deallocating file-backed memory... */
398*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
399*94d3b452SApple OSS Distributions T_WITH_ERRNO;
400*94d3b452SApple OSS Distributions T_QUIET;
401*94d3b452SApple OSS Distributions T_ASSERT_EQ(munmap(map_addr, map_size),
402*94d3b452SApple OSS Distributions 0,
403*94d3b452SApple OSS Distributions "unmap file");
404*94d3b452SApple OSS Distributions /* ... should not impact footprint */
405*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
406*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
407*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
408*94d3b452SApple OSS Distributions T_LOG("unmapping file-backed memory does not impact phys_footprint");
409*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
410*94d3b452SApple OSS Distributions "unmapped %zu dirty bytes: "
411*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
412*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
413*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
414*94d3b452SApple OSS Distributions }
415*94d3b452SApple OSS Distributions
416*94d3b452SApple OSS Distributions T_DECL(phys_footprint_purgeable,
417*94d3b452SApple OSS Distributions "phys_footprint for purgeable memory",
418*94d3b452SApple OSS Distributions T_META_LTEPHASE(LTE_POSTINIT))
419*94d3b452SApple OSS Distributions {
420*94d3b452SApple OSS Distributions uint64_t footprint_before, pagetable_before;
421*94d3b452SApple OSS Distributions uint64_t footprint_after, pagetable_after;
422*94d3b452SApple OSS Distributions uint64_t footprint_expected;
423*94d3b452SApple OSS Distributions kern_return_t kr;
424*94d3b452SApple OSS Distributions mach_vm_address_t pre_vm_addr, vm_addr;
425*94d3b452SApple OSS Distributions mach_vm_size_t vm_size, dirty_size;
426*94d3b452SApple OSS Distributions int state;
427*94d3b452SApple OSS Distributions
428*94d3b452SApple OSS Distributions /* pre-warm to account for page table expansion */
429*94d3b452SApple OSS Distributions pre_vm_addr = pre_warm(MEM_SIZE);
430*94d3b452SApple OSS Distributions
431*94d3b452SApple OSS Distributions /* allocating purgeable virtual memory... */
432*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
433*94d3b452SApple OSS Distributions vm_addr = 0;
434*94d3b452SApple OSS Distributions vm_size = MEM_SIZE;
435*94d3b452SApple OSS Distributions kr = mach_vm_allocate(mach_task_self(), &vm_addr, vm_size,
436*94d3b452SApple OSS Distributions VM_FLAGS_ANYWHERE | VM_FLAGS_PURGABLE);
437*94d3b452SApple OSS Distributions T_QUIET;
438*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_allocate() error 0x%x (%s)",
439*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
440*94d3b452SApple OSS Distributions T_QUIET;
441*94d3b452SApple OSS Distributions T_EXPECT_EQ(vm_addr, pre_vm_addr, "pre-warm mishap");
442*94d3b452SApple OSS Distributions /* ... should not change footprint */
443*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
444*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
445*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
446*94d3b452SApple OSS Distributions T_LOG("purgeable virtual allocation does not change phys_footprint");
447*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
448*94d3b452SApple OSS Distributions "purgeable virtual allocation of %lld bytes: "
449*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
450*94d3b452SApple OSS Distributions vm_size, footprint_before, footprint_after,
451*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
452*94d3b452SApple OSS Distributions
453*94d3b452SApple OSS Distributions /* touching memory... */
454*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
455*94d3b452SApple OSS Distributions dirty_size = vm_size / 2;
456*94d3b452SApple OSS Distributions memset((char *)(uintptr_t)vm_addr, 'x', (size_t)dirty_size);
457*94d3b452SApple OSS Distributions /* ... should increase footprint */
458*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
459*94d3b452SApple OSS Distributions footprint_expected = footprint_before + dirty_size;
460*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
461*94d3b452SApple OSS Distributions T_LOG("modifying anonymous memory increases phys_footprint");
462*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
463*94d3b452SApple OSS Distributions "touched %lld bytes: "
464*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
465*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
466*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
467*94d3b452SApple OSS Distributions
468*94d3b452SApple OSS Distributions /* making it volatile... */
469*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
470*94d3b452SApple OSS Distributions state = VM_PURGABLE_VOLATILE;
471*94d3b452SApple OSS Distributions T_QUIET;
472*94d3b452SApple OSS Distributions T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
473*94d3b452SApple OSS Distributions vm_addr,
474*94d3b452SApple OSS Distributions VM_PURGABLE_SET_STATE,
475*94d3b452SApple OSS Distributions &state),
476*94d3b452SApple OSS Distributions KERN_SUCCESS,
477*94d3b452SApple OSS Distributions "vm_purgable_control(VOLATILE)");
478*94d3b452SApple OSS Distributions T_QUIET;
479*94d3b452SApple OSS Distributions T_ASSERT_EQ(state, VM_PURGABLE_NONVOLATILE,
480*94d3b452SApple OSS Distributions "memory was non-volatile");
481*94d3b452SApple OSS Distributions /* ... should decrease footprint */
482*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
483*94d3b452SApple OSS Distributions footprint_expected = footprint_before - dirty_size;
484*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
485*94d3b452SApple OSS Distributions T_LOG("making volatile decreases phys_footprint");
486*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
487*94d3b452SApple OSS Distributions "made volatile %lld dirty bytes: "
488*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
489*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
490*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
491*94d3b452SApple OSS Distributions
492*94d3b452SApple OSS Distributions /* making it non-volatile... */
493*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
494*94d3b452SApple OSS Distributions state = VM_PURGABLE_NONVOLATILE;
495*94d3b452SApple OSS Distributions T_QUIET;
496*94d3b452SApple OSS Distributions T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
497*94d3b452SApple OSS Distributions vm_addr,
498*94d3b452SApple OSS Distributions VM_PURGABLE_SET_STATE,
499*94d3b452SApple OSS Distributions &state),
500*94d3b452SApple OSS Distributions KERN_SUCCESS,
501*94d3b452SApple OSS Distributions "vm_purgable_control(NONVOLATILE)");
502*94d3b452SApple OSS Distributions T_QUIET;
503*94d3b452SApple OSS Distributions T_ASSERT_EQ(state, VM_PURGABLE_VOLATILE,
504*94d3b452SApple OSS Distributions "memory was volatile");
505*94d3b452SApple OSS Distributions /* ... should increase footprint */
506*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
507*94d3b452SApple OSS Distributions footprint_expected = footprint_before + dirty_size;
508*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
509*94d3b452SApple OSS Distributions T_LOG("making non-volatile increases phys_footprint");
510*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
511*94d3b452SApple OSS Distributions "made non-volatile %lld dirty bytes: "
512*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
513*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
514*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
515*94d3b452SApple OSS Distributions
516*94d3b452SApple OSS Distributions /* deallocating memory... */
517*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
518*94d3b452SApple OSS Distributions kr = mach_vm_deallocate(mach_task_self(), vm_addr, vm_size);
519*94d3b452SApple OSS Distributions T_QUIET;
520*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_deallocate() error 0x%x (%s)",
521*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
522*94d3b452SApple OSS Distributions /* ... should decrease footprint */
523*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
524*94d3b452SApple OSS Distributions footprint_expected = footprint_before - dirty_size;
525*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
526*94d3b452SApple OSS Distributions T_LOG("deallocating memory decreases phys_footprint");
527*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
528*94d3b452SApple OSS Distributions "deallocated %lld dirty bytes: "
529*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
530*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
531*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
532*94d3b452SApple OSS Distributions }
533*94d3b452SApple OSS Distributions
534*94d3b452SApple OSS Distributions T_DECL(phys_footprint_purgeable_ownership,
535*94d3b452SApple OSS Distributions "phys_footprint for owned purgeable memory",
536*94d3b452SApple OSS Distributions T_META_LTEPHASE(LTE_POSTINIT))
537*94d3b452SApple OSS Distributions {
538*94d3b452SApple OSS Distributions uint64_t footprint_before, pagetable_before;
539*94d3b452SApple OSS Distributions uint64_t footprint_after, pagetable_after;
540*94d3b452SApple OSS Distributions uint64_t footprint_expected;
541*94d3b452SApple OSS Distributions kern_return_t kr;
542*94d3b452SApple OSS Distributions mach_vm_address_t pre_vm_addr, vm_addr;
543*94d3b452SApple OSS Distributions mach_vm_size_t vm_size, dirty_size, me_size;
544*94d3b452SApple OSS Distributions int state;
545*94d3b452SApple OSS Distributions mach_port_t me_port;
546*94d3b452SApple OSS Distributions
547*94d3b452SApple OSS Distributions /* pre-warm to account for page table expansion */
548*94d3b452SApple OSS Distributions pre_vm_addr = pre_warm(MEM_SIZE);
549*94d3b452SApple OSS Distributions
550*94d3b452SApple OSS Distributions /* allocating purgeable virtual memory... */
551*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
552*94d3b452SApple OSS Distributions vm_addr = 0;
553*94d3b452SApple OSS Distributions vm_size = MEM_SIZE;
554*94d3b452SApple OSS Distributions kr = mach_vm_allocate(mach_task_self(), &vm_addr, vm_size,
555*94d3b452SApple OSS Distributions VM_FLAGS_ANYWHERE | VM_FLAGS_PURGABLE);
556*94d3b452SApple OSS Distributions T_QUIET;
557*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_allocate() error 0x%x (%s)",
558*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
559*94d3b452SApple OSS Distributions T_QUIET;
560*94d3b452SApple OSS Distributions T_EXPECT_EQ(vm_addr, pre_vm_addr, "pre-warm mishap");
561*94d3b452SApple OSS Distributions /* ... should not change footprint */
562*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
563*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
564*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
565*94d3b452SApple OSS Distributions T_LOG("purgeable virtual allocation does not change phys_footprint");
566*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
567*94d3b452SApple OSS Distributions "purgeable virtual allocation of %lld bytes: "
568*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
569*94d3b452SApple OSS Distributions vm_size, footprint_before, footprint_after,
570*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
571*94d3b452SApple OSS Distributions
572*94d3b452SApple OSS Distributions /* touching memory... */
573*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
574*94d3b452SApple OSS Distributions dirty_size = vm_size / 2;
575*94d3b452SApple OSS Distributions memset((char *)(uintptr_t)vm_addr, 'x', (size_t)dirty_size);
576*94d3b452SApple OSS Distributions /* ... should increase footprint */
577*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
578*94d3b452SApple OSS Distributions footprint_expected = footprint_before + dirty_size;
579*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
580*94d3b452SApple OSS Distributions T_LOG("modifying anonymous memory increases phys_footprint");
581*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
582*94d3b452SApple OSS Distributions "touched %lld bytes: "
583*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
584*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
585*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
586*94d3b452SApple OSS Distributions
587*94d3b452SApple OSS Distributions /* making it volatile... */
588*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
589*94d3b452SApple OSS Distributions state = VM_PURGABLE_VOLATILE;
590*94d3b452SApple OSS Distributions T_QUIET;
591*94d3b452SApple OSS Distributions T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
592*94d3b452SApple OSS Distributions vm_addr,
593*94d3b452SApple OSS Distributions VM_PURGABLE_SET_STATE,
594*94d3b452SApple OSS Distributions &state),
595*94d3b452SApple OSS Distributions KERN_SUCCESS,
596*94d3b452SApple OSS Distributions "vm_purgable_control(VOLATILE)");
597*94d3b452SApple OSS Distributions T_QUIET;
598*94d3b452SApple OSS Distributions T_ASSERT_EQ(state, VM_PURGABLE_NONVOLATILE,
599*94d3b452SApple OSS Distributions "memory was non-volatile");
600*94d3b452SApple OSS Distributions /* ... should decrease footprint */
601*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
602*94d3b452SApple OSS Distributions footprint_expected = footprint_before - dirty_size;
603*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
604*94d3b452SApple OSS Distributions T_LOG("making volatile decreases phys_footprint");
605*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
606*94d3b452SApple OSS Distributions "made volatile %lld dirty bytes: "
607*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
608*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
609*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
610*94d3b452SApple OSS Distributions
611*94d3b452SApple OSS Distributions /* making it non-volatile... */
612*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
613*94d3b452SApple OSS Distributions state = VM_PURGABLE_NONVOLATILE;
614*94d3b452SApple OSS Distributions T_QUIET;
615*94d3b452SApple OSS Distributions T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
616*94d3b452SApple OSS Distributions vm_addr,
617*94d3b452SApple OSS Distributions VM_PURGABLE_SET_STATE,
618*94d3b452SApple OSS Distributions &state),
619*94d3b452SApple OSS Distributions KERN_SUCCESS,
620*94d3b452SApple OSS Distributions "vm_purgable_control(NONVOLATILE)");
621*94d3b452SApple OSS Distributions T_QUIET;
622*94d3b452SApple OSS Distributions T_ASSERT_EQ(state, VM_PURGABLE_VOLATILE,
623*94d3b452SApple OSS Distributions "memory was volatile");
624*94d3b452SApple OSS Distributions /* ... should increase footprint */
625*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
626*94d3b452SApple OSS Distributions footprint_expected = footprint_before + dirty_size;
627*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
628*94d3b452SApple OSS Distributions T_LOG("making non-volatile increases phys_footprint");
629*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
630*94d3b452SApple OSS Distributions "made non-volatile %lld dirty bytes: "
631*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
632*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
633*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
634*94d3b452SApple OSS Distributions
635*94d3b452SApple OSS Distributions /* making a memory entry... */
636*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
637*94d3b452SApple OSS Distributions me_size = vm_size;
638*94d3b452SApple OSS Distributions me_port = MACH_PORT_NULL;
639*94d3b452SApple OSS Distributions kr = mach_make_memory_entry_64(mach_task_self(),
640*94d3b452SApple OSS Distributions &me_size,
641*94d3b452SApple OSS Distributions vm_addr,
642*94d3b452SApple OSS Distributions VM_PROT_READ | VM_PROT_WRITE,
643*94d3b452SApple OSS Distributions &me_port,
644*94d3b452SApple OSS Distributions MACH_PORT_NULL);
645*94d3b452SApple OSS Distributions T_QUIET;
646*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "make_memory_entry() error 0x%x (%s)",
647*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
648*94d3b452SApple OSS Distributions T_QUIET;
649*94d3b452SApple OSS Distributions T_EXPECT_EQ(me_size, vm_size, "memory entry size mismatch");
650*94d3b452SApple OSS Distributions /* ... should not change footprint */
651*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
652*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
653*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
654*94d3b452SApple OSS Distributions T_LOG("making a memory entry does not change phys_footprint");
655*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
656*94d3b452SApple OSS Distributions "making a memory entry of %lld bytes: "
657*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
658*94d3b452SApple OSS Distributions vm_size, footprint_before, footprint_after,
659*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
660*94d3b452SApple OSS Distributions
661*94d3b452SApple OSS Distributions /* deallocating memory while holding memory entry... */
662*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
663*94d3b452SApple OSS Distributions kr = mach_vm_deallocate(mach_task_self(), vm_addr, vm_size);
664*94d3b452SApple OSS Distributions T_QUIET;
665*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_deallocate() error 0x%x (%s)",
666*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
667*94d3b452SApple OSS Distributions /* ... should not change footprint */
668*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
669*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
670*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
671*94d3b452SApple OSS Distributions T_LOG("deallocating owned memory while holding memory entry "
672*94d3b452SApple OSS Distributions "does not change phys_footprint");
673*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
674*94d3b452SApple OSS Distributions "deallocated %lld dirty bytes: "
675*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
676*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
677*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
678*94d3b452SApple OSS Distributions
679*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
680*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
681*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
682*94d3b452SApple OSS Distributions T_LOG("deallocating owned memory while holding memory entry "
683*94d3b452SApple OSS Distributions "does not change phys_footprint");
684*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
685*94d3b452SApple OSS Distributions "deallocated %lld dirty bytes: "
686*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
687*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
688*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
689*94d3b452SApple OSS Distributions
690*94d3b452SApple OSS Distributions /* changing ownership of memory entry (from self to self)... */
691*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
692*94d3b452SApple OSS Distributions kr = mach_memory_entry_ownership(me_port,
693*94d3b452SApple OSS Distributions #if VM_LEDGER_TAG_UNCHANGED
694*94d3b452SApple OSS Distributions MACH_PORT_NULL, /* owner remains unchanged */
695*94d3b452SApple OSS Distributions VM_LEDGER_TAG_UNCHANGED, /* ledger-tag remains unchanged */
696*94d3b452SApple OSS Distributions #else /* VM_LEDGER_TAG_UNCHANGED */
697*94d3b452SApple OSS Distributions mach_task_self(),
698*94d3b452SApple OSS Distributions VM_LEDGER_TAG_DEFAULT,
699*94d3b452SApple OSS Distributions #endif /* VM_LEDGER_TAG_UNCHANGED */
700*94d3b452SApple OSS Distributions 0);
701*94d3b452SApple OSS Distributions T_QUIET;
702*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS,
703*94d3b452SApple OSS Distributions "mach_memory_entry_ownership() error 0x%x (%s)",
704*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
705*94d3b452SApple OSS Distributions /* ... should not change footprint */
706*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
707*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
708*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
709*94d3b452SApple OSS Distributions T_LOG("changing ownership from self to self "
710*94d3b452SApple OSS Distributions "does not change phys_footprint");
711*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
712*94d3b452SApple OSS Distributions "changed ownership of %lld dirty bytes: "
713*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
714*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
715*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
716*94d3b452SApple OSS Distributions
717*94d3b452SApple OSS Distributions /* releasing the memory entry... */
718*94d3b452SApple OSS Distributions kr = mach_port_deallocate(mach_task_self(), me_port);
719*94d3b452SApple OSS Distributions T_QUIET;
720*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "mach_port_deallocate() error 0x%x (%s)",
721*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
722*94d3b452SApple OSS Distributions /* ... should decrease footprint */
723*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
724*94d3b452SApple OSS Distributions footprint_expected = footprint_before - dirty_size;
725*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
726*94d3b452SApple OSS Distributions T_LOG("releasing memory entry decreases phys_footprint");
727*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
728*94d3b452SApple OSS Distributions "made volatile %lld dirty bytes: "
729*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
730*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
731*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
732*94d3b452SApple OSS Distributions }
733*94d3b452SApple OSS Distributions
734*94d3b452SApple OSS Distributions #if VM_LEDGER_TAG_UNCHANGED
735*94d3b452SApple OSS Distributions T_DECL(phys_footprint_multiple_purgeable_ownership,
736*94d3b452SApple OSS Distributions "phys_footprint for owned purgeable memory (MAP_MEM_VM_SHARE)",
737*94d3b452SApple OSS Distributions T_META_NAMESPACE(TEST_VM_NAMESPACE),
738*94d3b452SApple OSS Distributions T_META_LTEPHASE(LTE_POSTINIT))
739*94d3b452SApple OSS Distributions {
740*94d3b452SApple OSS Distributions uint64_t footprint_before, pagetable_before;
741*94d3b452SApple OSS Distributions uint64_t footprint_after, pagetable_after;
742*94d3b452SApple OSS Distributions uint64_t footprint_expected;
743*94d3b452SApple OSS Distributions kern_return_t kr;
744*94d3b452SApple OSS Distributions mach_vm_address_t pre_vm_addr, vm_addr;
745*94d3b452SApple OSS Distributions mach_vm_size_t vm_size, dirty_size, me_size;
746*94d3b452SApple OSS Distributions int state;
747*94d3b452SApple OSS Distributions mach_port_t me_port;
748*94d3b452SApple OSS Distributions
749*94d3b452SApple OSS Distributions /* pre-warm to account for page table expansion */
750*94d3b452SApple OSS Distributions pre_vm_addr = pre_warm(MEM_SIZE);
751*94d3b452SApple OSS Distributions
752*94d3b452SApple OSS Distributions /* allocating purgeable virtual memory... */
753*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
754*94d3b452SApple OSS Distributions vm_addr = 0;
755*94d3b452SApple OSS Distributions vm_size = MEM_SIZE;
756*94d3b452SApple OSS Distributions kr = mach_vm_allocate(mach_task_self(), &vm_addr, vm_size,
757*94d3b452SApple OSS Distributions VM_FLAGS_ANYWHERE | VM_FLAGS_PURGABLE);
758*94d3b452SApple OSS Distributions T_QUIET;
759*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_allocate() error 0x%x (%s)",
760*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
761*94d3b452SApple OSS Distributions T_QUIET;
762*94d3b452SApple OSS Distributions T_EXPECT_EQ(vm_addr, pre_vm_addr, "pre-warm mishap");
763*94d3b452SApple OSS Distributions /* ... should not change footprint */
764*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
765*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
766*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
767*94d3b452SApple OSS Distributions T_LOG("purgeable virtual allocation does not change phys_footprint");
768*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
769*94d3b452SApple OSS Distributions "purgeable virtual allocation of %lld bytes: "
770*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
771*94d3b452SApple OSS Distributions vm_size, footprint_before, footprint_after,
772*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
773*94d3b452SApple OSS Distributions
774*94d3b452SApple OSS Distributions /* touching memory... */
775*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
776*94d3b452SApple OSS Distributions dirty_size = vm_size / 2;
777*94d3b452SApple OSS Distributions memset((char *)(uintptr_t)vm_addr, 'x', (size_t)dirty_size);
778*94d3b452SApple OSS Distributions /* ... should increase footprint */
779*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
780*94d3b452SApple OSS Distributions footprint_expected = footprint_before + dirty_size;
781*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
782*94d3b452SApple OSS Distributions T_LOG("modifying anonymous memory increases phys_footprint");
783*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
784*94d3b452SApple OSS Distributions "touched %lld bytes: "
785*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
786*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
787*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
788*94d3b452SApple OSS Distributions
789*94d3b452SApple OSS Distributions /* making it volatile... */
790*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
791*94d3b452SApple OSS Distributions state = VM_PURGABLE_VOLATILE;
792*94d3b452SApple OSS Distributions T_QUIET;
793*94d3b452SApple OSS Distributions T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
794*94d3b452SApple OSS Distributions vm_addr,
795*94d3b452SApple OSS Distributions VM_PURGABLE_SET_STATE,
796*94d3b452SApple OSS Distributions &state),
797*94d3b452SApple OSS Distributions KERN_SUCCESS,
798*94d3b452SApple OSS Distributions "vm_purgable_control(VOLATILE)");
799*94d3b452SApple OSS Distributions T_QUIET;
800*94d3b452SApple OSS Distributions T_ASSERT_EQ(state, VM_PURGABLE_NONVOLATILE,
801*94d3b452SApple OSS Distributions "memory was non-volatile");
802*94d3b452SApple OSS Distributions /* ... should decrease footprint */
803*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
804*94d3b452SApple OSS Distributions footprint_expected = footprint_before - dirty_size;
805*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
806*94d3b452SApple OSS Distributions T_LOG("making volatile decreases phys_footprint");
807*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
808*94d3b452SApple OSS Distributions "made volatile %lld dirty bytes: "
809*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
810*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
811*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
812*94d3b452SApple OSS Distributions
813*94d3b452SApple OSS Distributions /* making it non-volatile... */
814*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
815*94d3b452SApple OSS Distributions state = VM_PURGABLE_NONVOLATILE;
816*94d3b452SApple OSS Distributions T_QUIET;
817*94d3b452SApple OSS Distributions T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
818*94d3b452SApple OSS Distributions vm_addr,
819*94d3b452SApple OSS Distributions VM_PURGABLE_SET_STATE,
820*94d3b452SApple OSS Distributions &state),
821*94d3b452SApple OSS Distributions KERN_SUCCESS,
822*94d3b452SApple OSS Distributions "vm_purgable_control(NONVOLATILE)");
823*94d3b452SApple OSS Distributions T_QUIET;
824*94d3b452SApple OSS Distributions T_ASSERT_EQ(state, VM_PURGABLE_VOLATILE,
825*94d3b452SApple OSS Distributions "memory was volatile");
826*94d3b452SApple OSS Distributions /* ... should increase footprint */
827*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
828*94d3b452SApple OSS Distributions footprint_expected = footprint_before + dirty_size;
829*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
830*94d3b452SApple OSS Distributions T_LOG("making non-volatile increases phys_footprint");
831*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
832*94d3b452SApple OSS Distributions "made non-volatile %lld dirty bytes: "
833*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
834*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
835*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
836*94d3b452SApple OSS Distributions
837*94d3b452SApple OSS Distributions /* making a memory entry... */
838*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
839*94d3b452SApple OSS Distributions me_size = vm_size;
840*94d3b452SApple OSS Distributions me_port = MACH_PORT_NULL;
841*94d3b452SApple OSS Distributions kr = mach_make_memory_entry_64(mach_task_self(),
842*94d3b452SApple OSS Distributions &me_size,
843*94d3b452SApple OSS Distributions vm_addr,
844*94d3b452SApple OSS Distributions MAP_MEM_VM_SHARE | VM_PROT_READ | VM_PROT_WRITE,
845*94d3b452SApple OSS Distributions &me_port,
846*94d3b452SApple OSS Distributions MACH_PORT_NULL);
847*94d3b452SApple OSS Distributions T_QUIET;
848*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "make_memory_entry() error 0x%x (%s)",
849*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
850*94d3b452SApple OSS Distributions T_QUIET;
851*94d3b452SApple OSS Distributions T_EXPECT_EQ(me_size, vm_size, "memory entry size mismatch");
852*94d3b452SApple OSS Distributions /* ... should not change footprint */
853*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
854*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
855*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
856*94d3b452SApple OSS Distributions T_LOG("making a memory entry does not change phys_footprint");
857*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
858*94d3b452SApple OSS Distributions "making a memory entry of %lld bytes: "
859*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
860*94d3b452SApple OSS Distributions vm_size, footprint_before, footprint_after,
861*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
862*94d3b452SApple OSS Distributions
863*94d3b452SApple OSS Distributions /* deallocating memory while holding memory entry... */
864*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
865*94d3b452SApple OSS Distributions kr = mach_vm_deallocate(mach_task_self(), vm_addr, vm_size);
866*94d3b452SApple OSS Distributions T_QUIET;
867*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_deallocate() error 0x%x (%s)",
868*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
869*94d3b452SApple OSS Distributions /* ... should not change footprint */
870*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
871*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
872*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
873*94d3b452SApple OSS Distributions T_LOG("deallocating owned memory while holding memory entry "
874*94d3b452SApple OSS Distributions "does not change phys_footprint");
875*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
876*94d3b452SApple OSS Distributions "deallocated %lld dirty bytes: "
877*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
878*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
879*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
880*94d3b452SApple OSS Distributions
881*94d3b452SApple OSS Distributions /* changing ownership of memory entry (from self to self)... */
882*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
883*94d3b452SApple OSS Distributions kr = mach_memory_entry_ownership(me_port,
884*94d3b452SApple OSS Distributions MACH_PORT_NULL, /* owner remains unchanged */
885*94d3b452SApple OSS Distributions VM_LEDGER_TAG_UNCHANGED, /* ledger-tag remains unchanged */
886*94d3b452SApple OSS Distributions 0);
887*94d3b452SApple OSS Distributions T_QUIET;
888*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS,
889*94d3b452SApple OSS Distributions "mach_memory_entry_ownership() error 0x%x (%s)",
890*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
891*94d3b452SApple OSS Distributions /* ... should not change footprint */
892*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
893*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
894*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
895*94d3b452SApple OSS Distributions T_LOG("changing ownership from self to self "
896*94d3b452SApple OSS Distributions "does not change phys_footprint");
897*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
898*94d3b452SApple OSS Distributions "changed ownership of %lld dirty bytes: "
899*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
900*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
901*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
902*94d3b452SApple OSS Distributions
903*94d3b452SApple OSS Distributions /* releasing the memory entry... */
904*94d3b452SApple OSS Distributions kr = mach_port_deallocate(mach_task_self(), me_port);
905*94d3b452SApple OSS Distributions T_QUIET;
906*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "mach_port_deallocate() error 0x%x (%s)",
907*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
908*94d3b452SApple OSS Distributions /* ... should decrease footprint */
909*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
910*94d3b452SApple OSS Distributions footprint_expected = footprint_before - dirty_size;
911*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
912*94d3b452SApple OSS Distributions T_LOG("releasing memory entry decreases phys_footprint");
913*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
914*94d3b452SApple OSS Distributions "made volatile %lld dirty bytes: "
915*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
916*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
917*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
918*94d3b452SApple OSS Distributions }
919*94d3b452SApple OSS Distributions #endif /* VM_LEDGER_TAG_UNCHANGED */
920*94d3b452SApple OSS Distributions
921*94d3b452SApple OSS Distributions #ifdef MAP_MEM_LEDGER_TAGGED
922*94d3b452SApple OSS Distributions T_DECL(phys_footprint_ledger_purgeable_owned,
923*94d3b452SApple OSS Distributions "phys_footprint for ledger-tagged purgeable memory ownership",
924*94d3b452SApple OSS Distributions T_META_LTEPHASE(LTE_POSTINIT))
925*94d3b452SApple OSS Distributions {
926*94d3b452SApple OSS Distributions uint64_t footprint_before, pagetable_before;
927*94d3b452SApple OSS Distributions uint64_t footprint_after, pagetable_after;
928*94d3b452SApple OSS Distributions uint64_t footprint_expected;
929*94d3b452SApple OSS Distributions kern_return_t kr;
930*94d3b452SApple OSS Distributions mach_vm_address_t pre_vm_addr, vm_addr;
931*94d3b452SApple OSS Distributions mach_vm_size_t vm_size, dirty_size, me_size;
932*94d3b452SApple OSS Distributions int state;
933*94d3b452SApple OSS Distributions mach_port_t me_port;
934*94d3b452SApple OSS Distributions
935*94d3b452SApple OSS Distributions /* pre-warm to account for page table expansion */
936*94d3b452SApple OSS Distributions pre_vm_addr = pre_warm(MEM_SIZE);
937*94d3b452SApple OSS Distributions
938*94d3b452SApple OSS Distributions /* making a memory entry... */
939*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
940*94d3b452SApple OSS Distributions vm_size = MEM_SIZE;
941*94d3b452SApple OSS Distributions me_size = vm_size;
942*94d3b452SApple OSS Distributions me_port = MACH_PORT_NULL;
943*94d3b452SApple OSS Distributions kr = mach_make_memory_entry_64(mach_task_self(),
944*94d3b452SApple OSS Distributions &me_size,
945*94d3b452SApple OSS Distributions 0,
946*94d3b452SApple OSS Distributions (MAP_MEM_NAMED_CREATE |
947*94d3b452SApple OSS Distributions MAP_MEM_LEDGER_TAGGED |
948*94d3b452SApple OSS Distributions MAP_MEM_PURGABLE |
949*94d3b452SApple OSS Distributions VM_PROT_READ | VM_PROT_WRITE),
950*94d3b452SApple OSS Distributions &me_port,
951*94d3b452SApple OSS Distributions MACH_PORT_NULL);
952*94d3b452SApple OSS Distributions T_QUIET;
953*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "make_memory_entry() error 0x%x (%s)",
954*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
955*94d3b452SApple OSS Distributions T_QUIET;
956*94d3b452SApple OSS Distributions T_EXPECT_EQ(me_size, vm_size, "memory entry size mismatch");
957*94d3b452SApple OSS Distributions /* ... should not change footprint */
958*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
959*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
960*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
961*94d3b452SApple OSS Distributions T_LOG("making a memory entry does not change phys_footprint");
962*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
963*94d3b452SApple OSS Distributions "making a memory entry of %lld bytes: "
964*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
965*94d3b452SApple OSS Distributions vm_size, footprint_before, footprint_after,
966*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
967*94d3b452SApple OSS Distributions
968*94d3b452SApple OSS Distributions /* mapping ledger-tagged virtual memory... */
969*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
970*94d3b452SApple OSS Distributions vm_addr = 0;
971*94d3b452SApple OSS Distributions kr = mach_vm_map(mach_task_self(), &vm_addr, vm_size,
972*94d3b452SApple OSS Distributions 0, /* mask */
973*94d3b452SApple OSS Distributions VM_FLAGS_ANYWHERE,
974*94d3b452SApple OSS Distributions me_port,
975*94d3b452SApple OSS Distributions 0, /* offset */
976*94d3b452SApple OSS Distributions FALSE, /* copy */
977*94d3b452SApple OSS Distributions VM_PROT_READ | VM_PROT_WRITE,
978*94d3b452SApple OSS Distributions VM_PROT_READ | VM_PROT_WRITE,
979*94d3b452SApple OSS Distributions VM_INHERIT_DEFAULT);
980*94d3b452SApple OSS Distributions T_QUIET;
981*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_map() error 0x%x (%s)",
982*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
983*94d3b452SApple OSS Distributions T_QUIET;
984*94d3b452SApple OSS Distributions T_EXPECT_EQ(vm_addr, pre_vm_addr, "pre-warm mishap");
985*94d3b452SApple OSS Distributions /* ... should not change footprint */
986*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
987*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
988*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
989*94d3b452SApple OSS Distributions T_LOG("mapping ledger-tagged memory does not change phys_footprint");
990*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
991*94d3b452SApple OSS Distributions "ledger-tagged mapping of %lld bytes: "
992*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
993*94d3b452SApple OSS Distributions vm_size, footprint_before, footprint_after,
994*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
995*94d3b452SApple OSS Distributions
996*94d3b452SApple OSS Distributions /* touching memory... */
997*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
998*94d3b452SApple OSS Distributions dirty_size = vm_size / 2;
999*94d3b452SApple OSS Distributions memset((char *)(uintptr_t)vm_addr, 'x', (size_t)dirty_size);
1000*94d3b452SApple OSS Distributions /* ... should increase footprint */
1001*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1002*94d3b452SApple OSS Distributions footprint_expected = footprint_before + dirty_size;
1003*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1004*94d3b452SApple OSS Distributions T_LOG("modifying ledger-tagged memory increases phys_footprint");
1005*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1006*94d3b452SApple OSS Distributions "touched %lld bytes: "
1007*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1008*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
1009*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1010*94d3b452SApple OSS Distributions
1011*94d3b452SApple OSS Distributions /* making it volatile... */
1012*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1013*94d3b452SApple OSS Distributions state = VM_PURGABLE_VOLATILE;
1014*94d3b452SApple OSS Distributions T_QUIET;
1015*94d3b452SApple OSS Distributions T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
1016*94d3b452SApple OSS Distributions vm_addr,
1017*94d3b452SApple OSS Distributions VM_PURGABLE_SET_STATE,
1018*94d3b452SApple OSS Distributions &state),
1019*94d3b452SApple OSS Distributions KERN_SUCCESS,
1020*94d3b452SApple OSS Distributions "vm_purgable_control(VOLATILE)");
1021*94d3b452SApple OSS Distributions T_QUIET;
1022*94d3b452SApple OSS Distributions T_ASSERT_EQ(state, VM_PURGABLE_NONVOLATILE,
1023*94d3b452SApple OSS Distributions "memory was non-volatile");
1024*94d3b452SApple OSS Distributions /* ... should decrease footprint */
1025*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1026*94d3b452SApple OSS Distributions footprint_expected = footprint_before - dirty_size;
1027*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1028*94d3b452SApple OSS Distributions T_LOG("making volatile decreases phys_footprint");
1029*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1030*94d3b452SApple OSS Distributions "made volatile %lld dirty bytes: "
1031*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1032*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
1033*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1034*94d3b452SApple OSS Distributions
1035*94d3b452SApple OSS Distributions /* making it non-volatile... */
1036*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1037*94d3b452SApple OSS Distributions state = VM_PURGABLE_NONVOLATILE;
1038*94d3b452SApple OSS Distributions T_QUIET;
1039*94d3b452SApple OSS Distributions T_ASSERT_EQ(mach_vm_purgable_control(mach_task_self(),
1040*94d3b452SApple OSS Distributions vm_addr,
1041*94d3b452SApple OSS Distributions VM_PURGABLE_SET_STATE,
1042*94d3b452SApple OSS Distributions &state),
1043*94d3b452SApple OSS Distributions KERN_SUCCESS,
1044*94d3b452SApple OSS Distributions "vm_purgable_control(NONVOLATILE)");
1045*94d3b452SApple OSS Distributions T_QUIET;
1046*94d3b452SApple OSS Distributions T_ASSERT_EQ(state, VM_PURGABLE_VOLATILE,
1047*94d3b452SApple OSS Distributions "memory was volatile");
1048*94d3b452SApple OSS Distributions /* ... should increase footprint */
1049*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1050*94d3b452SApple OSS Distributions footprint_expected = footprint_before + dirty_size;
1051*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1052*94d3b452SApple OSS Distributions T_LOG("making non-volatile increases phys_footprint");
1053*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1054*94d3b452SApple OSS Distributions "made non-volatile %lld dirty bytes: "
1055*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1056*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
1057*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1058*94d3b452SApple OSS Distributions
1059*94d3b452SApple OSS Distributions /* deallocating memory while holding memory entry... */
1060*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1061*94d3b452SApple OSS Distributions kr = mach_vm_deallocate(mach_task_self(), vm_addr, vm_size);
1062*94d3b452SApple OSS Distributions T_QUIET;
1063*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_deallocate() error 0x%x (%s)",
1064*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
1065*94d3b452SApple OSS Distributions /* ... should not change footprint */
1066*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1067*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
1068*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1069*94d3b452SApple OSS Distributions T_LOG("deallocating owned memory while holding memory entry "
1070*94d3b452SApple OSS Distributions "does not change phys_footprint");
1071*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1072*94d3b452SApple OSS Distributions "deallocated %lld dirty bytes: "
1073*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1074*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
1075*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1076*94d3b452SApple OSS Distributions
1077*94d3b452SApple OSS Distributions /* releasing the memory entry... */
1078*94d3b452SApple OSS Distributions kr = mach_port_deallocate(mach_task_self(), me_port);
1079*94d3b452SApple OSS Distributions T_QUIET;
1080*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "mach_port_deallocate() error 0x%x (%s)",
1081*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
1082*94d3b452SApple OSS Distributions /* ... should decrease footprint */
1083*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1084*94d3b452SApple OSS Distributions footprint_expected = footprint_before - dirty_size;
1085*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1086*94d3b452SApple OSS Distributions T_LOG("releasing memory entry decreases phys_footprint");
1087*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1088*94d3b452SApple OSS Distributions "made volatile %lld dirty bytes: "
1089*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1090*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
1091*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1092*94d3b452SApple OSS Distributions }
1093*94d3b452SApple OSS Distributions
1094*94d3b452SApple OSS Distributions T_DECL(phys_footprint_ledger_owned,
1095*94d3b452SApple OSS Distributions "phys_footprint for ledger-tagged memory ownership",
1096*94d3b452SApple OSS Distributions T_META_LTEPHASE(LTE_POSTINIT))
1097*94d3b452SApple OSS Distributions {
1098*94d3b452SApple OSS Distributions uint64_t footprint_before, pagetable_before;
1099*94d3b452SApple OSS Distributions uint64_t footprint_after, pagetable_after;
1100*94d3b452SApple OSS Distributions uint64_t footprint_expected;
1101*94d3b452SApple OSS Distributions kern_return_t kr;
1102*94d3b452SApple OSS Distributions mach_vm_address_t pre_vm_addr, vm_addr;
1103*94d3b452SApple OSS Distributions mach_vm_size_t vm_size, dirty_size, me_size;
1104*94d3b452SApple OSS Distributions mach_port_t me_port;
1105*94d3b452SApple OSS Distributions
1106*94d3b452SApple OSS Distributions /* pre-warm to account for page table expansion */
1107*94d3b452SApple OSS Distributions pre_vm_addr = pre_warm(MEM_SIZE);
1108*94d3b452SApple OSS Distributions
1109*94d3b452SApple OSS Distributions /* making a memory entry... */
1110*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1111*94d3b452SApple OSS Distributions vm_size = MEM_SIZE;
1112*94d3b452SApple OSS Distributions me_size = vm_size;
1113*94d3b452SApple OSS Distributions me_port = MACH_PORT_NULL;
1114*94d3b452SApple OSS Distributions kr = mach_make_memory_entry_64(mach_task_self(),
1115*94d3b452SApple OSS Distributions &me_size,
1116*94d3b452SApple OSS Distributions 0,
1117*94d3b452SApple OSS Distributions (MAP_MEM_NAMED_CREATE |
1118*94d3b452SApple OSS Distributions MAP_MEM_LEDGER_TAGGED |
1119*94d3b452SApple OSS Distributions VM_PROT_READ | VM_PROT_WRITE),
1120*94d3b452SApple OSS Distributions &me_port,
1121*94d3b452SApple OSS Distributions MACH_PORT_NULL);
1122*94d3b452SApple OSS Distributions T_QUIET;
1123*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "make_memory_entry() error 0x%x (%s)",
1124*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
1125*94d3b452SApple OSS Distributions T_QUIET;
1126*94d3b452SApple OSS Distributions T_EXPECT_EQ(me_size, vm_size, "memory entry size mismatch");
1127*94d3b452SApple OSS Distributions /* ... should not change footprint */
1128*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1129*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
1130*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1131*94d3b452SApple OSS Distributions T_LOG("making a memory entry does not change phys_footprint");
1132*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1133*94d3b452SApple OSS Distributions "making a memory entry of %lld bytes: "
1134*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1135*94d3b452SApple OSS Distributions vm_size, footprint_before, footprint_after,
1136*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1137*94d3b452SApple OSS Distributions
1138*94d3b452SApple OSS Distributions /* mapping ledger-tagged virtual memory... */
1139*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1140*94d3b452SApple OSS Distributions vm_addr = 0;
1141*94d3b452SApple OSS Distributions kr = mach_vm_map(mach_task_self(), &vm_addr, vm_size,
1142*94d3b452SApple OSS Distributions 0, /* mask */
1143*94d3b452SApple OSS Distributions VM_FLAGS_ANYWHERE,
1144*94d3b452SApple OSS Distributions me_port,
1145*94d3b452SApple OSS Distributions 0, /* offset */
1146*94d3b452SApple OSS Distributions FALSE, /* copy */
1147*94d3b452SApple OSS Distributions VM_PROT_READ | VM_PROT_WRITE,
1148*94d3b452SApple OSS Distributions VM_PROT_READ | VM_PROT_WRITE,
1149*94d3b452SApple OSS Distributions VM_INHERIT_DEFAULT);
1150*94d3b452SApple OSS Distributions T_QUIET;
1151*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_map() error 0x%x (%s)",
1152*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
1153*94d3b452SApple OSS Distributions T_QUIET;
1154*94d3b452SApple OSS Distributions T_EXPECT_EQ(vm_addr, pre_vm_addr, "pre-warm mishap");
1155*94d3b452SApple OSS Distributions /* ... should not change footprint */
1156*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1157*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
1158*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1159*94d3b452SApple OSS Distributions T_LOG("mapping ledger-tagged memory does not change phys_footprint");
1160*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1161*94d3b452SApple OSS Distributions "ledger-tagged mapping of %lld bytes: "
1162*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1163*94d3b452SApple OSS Distributions vm_size, footprint_before, footprint_after,
1164*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1165*94d3b452SApple OSS Distributions
1166*94d3b452SApple OSS Distributions /* touching memory... */
1167*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1168*94d3b452SApple OSS Distributions dirty_size = vm_size / 2;
1169*94d3b452SApple OSS Distributions memset((char *)(uintptr_t)vm_addr, 'x', (size_t)dirty_size);
1170*94d3b452SApple OSS Distributions /* ... should increase footprint */
1171*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1172*94d3b452SApple OSS Distributions footprint_expected = footprint_before + dirty_size;
1173*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1174*94d3b452SApple OSS Distributions T_LOG("modifying ledger-tagged memory increases phys_footprint");
1175*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1176*94d3b452SApple OSS Distributions "touched %lld bytes: "
1177*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1178*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
1179*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1180*94d3b452SApple OSS Distributions
1181*94d3b452SApple OSS Distributions /* deallocating memory while holding memory entry... */
1182*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1183*94d3b452SApple OSS Distributions kr = mach_vm_deallocate(mach_task_self(), vm_addr, vm_size);
1184*94d3b452SApple OSS Distributions T_QUIET;
1185*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_deallocate() error 0x%x (%s)",
1186*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
1187*94d3b452SApple OSS Distributions /* ... should not change footprint */
1188*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1189*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
1190*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1191*94d3b452SApple OSS Distributions T_LOG("deallocating owned memory while holding memory entry "
1192*94d3b452SApple OSS Distributions "does not change phys_footprint");
1193*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1194*94d3b452SApple OSS Distributions "deallocated %lld dirty bytes: "
1195*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1196*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
1197*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1198*94d3b452SApple OSS Distributions
1199*94d3b452SApple OSS Distributions /* releasing the memory entry... */
1200*94d3b452SApple OSS Distributions kr = mach_port_deallocate(mach_task_self(), me_port);
1201*94d3b452SApple OSS Distributions T_QUIET;
1202*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "mach_port_deallocate() error 0x%x (%s)",
1203*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
1204*94d3b452SApple OSS Distributions /* ... should decrease footprint */
1205*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1206*94d3b452SApple OSS Distributions footprint_expected = footprint_before - dirty_size;
1207*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1208*94d3b452SApple OSS Distributions T_LOG("releasing memory entry decreases phys_footprint");
1209*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1210*94d3b452SApple OSS Distributions "made volatile %lld dirty bytes: "
1211*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1212*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
1213*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1214*94d3b452SApple OSS Distributions }
1215*94d3b452SApple OSS Distributions
1216*94d3b452SApple OSS Distributions T_DECL(phys_footprint_no_footprint_for_debug,
1217*94d3b452SApple OSS Distributions "phys_footprint for no_footprint_for_debug",
1218*94d3b452SApple OSS Distributions T_META_LTEPHASE(LTE_POSTINIT))
1219*94d3b452SApple OSS Distributions {
1220*94d3b452SApple OSS Distributions uint64_t footprint_before, pagetable_before;
1221*94d3b452SApple OSS Distributions uint64_t footprint_after, pagetable_after;
1222*94d3b452SApple OSS Distributions uint64_t footprint_expected;
1223*94d3b452SApple OSS Distributions kern_return_t kr;
1224*94d3b452SApple OSS Distributions mach_vm_address_t pre_vm_addr, vm_addr;
1225*94d3b452SApple OSS Distributions mach_vm_size_t vm_size, dirty_size, me_size;
1226*94d3b452SApple OSS Distributions mach_port_t me_port;
1227*94d3b452SApple OSS Distributions int new_value, ret;
1228*94d3b452SApple OSS Distributions
1229*94d3b452SApple OSS Distributions /* pre-warm to account for page table expansion */
1230*94d3b452SApple OSS Distributions pre_vm_addr = pre_warm(MEM_SIZE);
1231*94d3b452SApple OSS Distributions
1232*94d3b452SApple OSS Distributions /* making a memory entry... */
1233*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1234*94d3b452SApple OSS Distributions vm_size = MEM_SIZE;
1235*94d3b452SApple OSS Distributions me_size = vm_size;
1236*94d3b452SApple OSS Distributions me_port = MACH_PORT_NULL;
1237*94d3b452SApple OSS Distributions kr = mach_make_memory_entry_64(mach_task_self(),
1238*94d3b452SApple OSS Distributions &me_size,
1239*94d3b452SApple OSS Distributions 0,
1240*94d3b452SApple OSS Distributions (MAP_MEM_NAMED_CREATE |
1241*94d3b452SApple OSS Distributions MAP_MEM_LEDGER_TAGGED |
1242*94d3b452SApple OSS Distributions VM_PROT_READ | VM_PROT_WRITE),
1243*94d3b452SApple OSS Distributions &me_port,
1244*94d3b452SApple OSS Distributions MACH_PORT_NULL);
1245*94d3b452SApple OSS Distributions T_QUIET;
1246*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "make_memory_entry() error 0x%x (%s)",
1247*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
1248*94d3b452SApple OSS Distributions T_QUIET;
1249*94d3b452SApple OSS Distributions T_EXPECT_EQ(me_size, vm_size, "memory entry size mismatch");
1250*94d3b452SApple OSS Distributions /* ... should not change footprint */
1251*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1252*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
1253*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1254*94d3b452SApple OSS Distributions T_LOG("making a memory entry does not change phys_footprint");
1255*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1256*94d3b452SApple OSS Distributions "making a memory entry of %lld bytes: "
1257*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1258*94d3b452SApple OSS Distributions vm_size, footprint_before, footprint_after,
1259*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1260*94d3b452SApple OSS Distributions
1261*94d3b452SApple OSS Distributions /* trying to hide debug memory from footprint while not allowed */
1262*94d3b452SApple OSS Distributions kr = mach_memory_entry_ownership(me_port,
1263*94d3b452SApple OSS Distributions mach_task_self(),
1264*94d3b452SApple OSS Distributions VM_LEDGER_TAG_DEFAULT,
1265*94d3b452SApple OSS Distributions VM_LEDGER_FLAG_NO_FOOTPRINT_FOR_DEBUG);
1266*94d3b452SApple OSS Distributions T_QUIET;
1267*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_NO_ACCESS,
1268*94d3b452SApple OSS Distributions "mach_memory_entry_ownership(NO_FOOTPRINT_FOR_DEBUG) fails without sysctl");
1269*94d3b452SApple OSS Distributions
1270*94d3b452SApple OSS Distributions /* let's get permission to hide debug memory */
1271*94d3b452SApple OSS Distributions new_value = 1;
1272*94d3b452SApple OSS Distributions ret = sysctlbyname("vm.task_no_footprint_for_debug", NULL, NULL, &new_value, sizeof(new_value));
1273*94d3b452SApple OSS Distributions if (ret == -1 && errno == ENOENT) {
1274*94d3b452SApple OSS Distributions T_SKIP("sysctlbyname(vm.task_no_footprint_for_debug) ENOENT");
1275*94d3b452SApple OSS Distributions }
1276*94d3b452SApple OSS Distributions T_QUIET;
1277*94d3b452SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(ret, "sysctlbyname(vm.task_no_footprint_for_debug)");
1278*94d3b452SApple OSS Distributions
1279*94d3b452SApple OSS Distributions /* trying to hide debug memory from footprint while allowed */
1280*94d3b452SApple OSS Distributions task_id_token_t token;
1281*94d3b452SApple OSS Distributions kr = task_create_identity_token(mach_task_self(), &token);
1282*94d3b452SApple OSS Distributions T_QUIET;
1283*94d3b452SApple OSS Distributions T_ASSERT_EQ(kr, KERN_SUCCESS,
1284*94d3b452SApple OSS Distributions "task_create_identity_token");
1285*94d3b452SApple OSS Distributions
1286*94d3b452SApple OSS Distributions kr = mach_memory_entry_ownership(me_port,
1287*94d3b452SApple OSS Distributions token, /* this time also try calling it with id token */
1288*94d3b452SApple OSS Distributions VM_LEDGER_TAG_DEFAULT,
1289*94d3b452SApple OSS Distributions VM_LEDGER_FLAG_NO_FOOTPRINT_FOR_DEBUG);
1290*94d3b452SApple OSS Distributions T_QUIET;
1291*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS,
1292*94d3b452SApple OSS Distributions "mach_memory_entry_ownership(NO_FOOTPRINT_FOR_DEBUG) succeeds after sysctl");
1293*94d3b452SApple OSS Distributions mach_port_deallocate(mach_task_self(), token);
1294*94d3b452SApple OSS Distributions
1295*94d3b452SApple OSS Distributions /* mapping ledger-tagged virtual memory... */
1296*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1297*94d3b452SApple OSS Distributions vm_addr = 0;
1298*94d3b452SApple OSS Distributions kr = mach_vm_map(mach_task_self(), &vm_addr, vm_size,
1299*94d3b452SApple OSS Distributions 0, /* mask */
1300*94d3b452SApple OSS Distributions VM_FLAGS_ANYWHERE,
1301*94d3b452SApple OSS Distributions me_port,
1302*94d3b452SApple OSS Distributions 0, /* offset */
1303*94d3b452SApple OSS Distributions FALSE, /* copy */
1304*94d3b452SApple OSS Distributions VM_PROT_READ | VM_PROT_WRITE,
1305*94d3b452SApple OSS Distributions VM_PROT_READ | VM_PROT_WRITE,
1306*94d3b452SApple OSS Distributions VM_INHERIT_DEFAULT);
1307*94d3b452SApple OSS Distributions T_QUIET;
1308*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_map() error 0x%x (%s)",
1309*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
1310*94d3b452SApple OSS Distributions T_QUIET;
1311*94d3b452SApple OSS Distributions T_EXPECT_EQ(vm_addr, pre_vm_addr, "pre-warm mishap");
1312*94d3b452SApple OSS Distributions /* ... should not change footprint */
1313*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1314*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
1315*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1316*94d3b452SApple OSS Distributions T_LOG("mapping ledger-tagged memory does not change phys_footprint");
1317*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1318*94d3b452SApple OSS Distributions "ledger-tagged mapping of %lld bytes: "
1319*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1320*94d3b452SApple OSS Distributions vm_size, footprint_before, footprint_after,
1321*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1322*94d3b452SApple OSS Distributions
1323*94d3b452SApple OSS Distributions /* touching memory... */
1324*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1325*94d3b452SApple OSS Distributions dirty_size = vm_size / 2;
1326*94d3b452SApple OSS Distributions memset((char *)(uintptr_t)vm_addr, 'x', (size_t)dirty_size);
1327*94d3b452SApple OSS Distributions /* ... should not increase footprint */
1328*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1329*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
1330*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1331*94d3b452SApple OSS Distributions T_LOG("modifying no_footprint_for_debug memory does not increase phys_footprint");
1332*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1333*94d3b452SApple OSS Distributions "touched %lld bytes: "
1334*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1335*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
1336*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1337*94d3b452SApple OSS Distributions
1338*94d3b452SApple OSS Distributions /* deallocating memory while holding memory entry... */
1339*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1340*94d3b452SApple OSS Distributions kr = mach_vm_deallocate(mach_task_self(), vm_addr, vm_size);
1341*94d3b452SApple OSS Distributions T_QUIET;
1342*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_deallocate() error 0x%x (%s)",
1343*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
1344*94d3b452SApple OSS Distributions /* ... should not change footprint */
1345*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1346*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
1347*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1348*94d3b452SApple OSS Distributions T_LOG("deallocating owned memory while holding memory entry "
1349*94d3b452SApple OSS Distributions "does not change phys_footprint");
1350*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1351*94d3b452SApple OSS Distributions "deallocated %lld dirty bytes: "
1352*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1353*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
1354*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1355*94d3b452SApple OSS Distributions
1356*94d3b452SApple OSS Distributions /* releasing the memory entry... */
1357*94d3b452SApple OSS Distributions kr = mach_port_deallocate(mach_task_self(), me_port);
1358*94d3b452SApple OSS Distributions T_QUIET;
1359*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "mach_port_deallocate() error 0x%x (%s)",
1360*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
1361*94d3b452SApple OSS Distributions /* ... should not change footprint */
1362*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1363*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
1364*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1365*94d3b452SApple OSS Distributions T_LOG("releasing memory entry does not change phys_footprint");
1366*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1367*94d3b452SApple OSS Distributions "made volatile %lld dirty bytes: "
1368*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1369*94d3b452SApple OSS Distributions dirty_size, footprint_before, footprint_after,
1370*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1371*94d3b452SApple OSS Distributions }
1372*94d3b452SApple OSS Distributions #endif /* MAP_MEM_LEDGER_TAGGED */
1373*94d3b452SApple OSS Distributions
1374*94d3b452SApple OSS Distributions /* IOSurface code from: CoreImage/CoreImageTests/CIRender/SurfaceUtils.c */
1375*94d3b452SApple OSS Distributions #include <CoreFoundation/CoreFoundation.h>
1376*94d3b452SApple OSS Distributions #include <IOSurface/IOSurface.h>
1377*94d3b452SApple OSS Distributions #include <IOSurface/IOSurfacePrivate.h>
1378*94d3b452SApple OSS Distributions static size_t
bytes_per_element(uint32_t format)1379*94d3b452SApple OSS Distributions bytes_per_element(uint32_t format)
1380*94d3b452SApple OSS Distributions {
1381*94d3b452SApple OSS Distributions size_t bpe = 0;
1382*94d3b452SApple OSS Distributions switch (format) {
1383*94d3b452SApple OSS Distributions case 32: // kCVPixelFormatType_32ARGB (ARGB8)
1384*94d3b452SApple OSS Distributions bpe = 4;
1385*94d3b452SApple OSS Distributions break;
1386*94d3b452SApple OSS Distributions default:
1387*94d3b452SApple OSS Distributions bpe = 0;
1388*94d3b452SApple OSS Distributions break;
1389*94d3b452SApple OSS Distributions }
1390*94d3b452SApple OSS Distributions return bpe;
1391*94d3b452SApple OSS Distributions }
1392*94d3b452SApple OSS Distributions static size_t
bytes_per_pixel(uint32_t format)1393*94d3b452SApple OSS Distributions bytes_per_pixel(uint32_t format)
1394*94d3b452SApple OSS Distributions {
1395*94d3b452SApple OSS Distributions size_t bpe = 0;
1396*94d3b452SApple OSS Distributions switch (format) {
1397*94d3b452SApple OSS Distributions case 32: // kCVPixelFormatType_32ARGB (ARGB8)
1398*94d3b452SApple OSS Distributions bpe = 4;
1399*94d3b452SApple OSS Distributions break;
1400*94d3b452SApple OSS Distributions default:
1401*94d3b452SApple OSS Distributions bpe = 0;
1402*94d3b452SApple OSS Distributions break;
1403*94d3b452SApple OSS Distributions }
1404*94d3b452SApple OSS Distributions return bpe;
1405*94d3b452SApple OSS Distributions }
1406*94d3b452SApple OSS Distributions static inline size_t
roundSizeToMultiple(size_t size,size_t mult)1407*94d3b452SApple OSS Distributions roundSizeToMultiple(size_t size, size_t mult)
1408*94d3b452SApple OSS Distributions {
1409*94d3b452SApple OSS Distributions return ((size + mult - 1) / mult) * mult;
1410*94d3b452SApple OSS Distributions }
1411*94d3b452SApple OSS Distributions static inline void
setIntValue(CFMutableDictionaryRef dict,const CFStringRef key,int value)1412*94d3b452SApple OSS Distributions setIntValue(CFMutableDictionaryRef dict, const CFStringRef key, int value)
1413*94d3b452SApple OSS Distributions {
1414*94d3b452SApple OSS Distributions CFNumberRef number = CFNumberCreate(0, kCFNumberIntType, &value);
1415*94d3b452SApple OSS Distributions CFDictionarySetValue(dict, key, number);
1416*94d3b452SApple OSS Distributions CFRelease(number);
1417*94d3b452SApple OSS Distributions }
1418*94d3b452SApple OSS Distributions static inline void
setBoolValue(CFMutableDictionaryRef dict,const CFStringRef key,bool value)1419*94d3b452SApple OSS Distributions setBoolValue(CFMutableDictionaryRef dict, const CFStringRef key, bool value)
1420*94d3b452SApple OSS Distributions {
1421*94d3b452SApple OSS Distributions CFDictionarySetValue(dict, key, value ? kCFBooleanTrue : kCFBooleanFalse);
1422*94d3b452SApple OSS Distributions }
1423*94d3b452SApple OSS Distributions typedef void (^SurfacePlaneBlock)(void *data, size_t planeIndex, size_t width, size_t height, size_t rowbytes);
1424*94d3b452SApple OSS Distributions static IOReturn
SurfaceApplyPlaneBlock(IOSurfaceRef surface,SurfacePlaneBlock block)1425*94d3b452SApple OSS Distributions SurfaceApplyPlaneBlock(IOSurfaceRef surface, SurfacePlaneBlock block)
1426*94d3b452SApple OSS Distributions {
1427*94d3b452SApple OSS Distributions if (surface == nil || block == nil) {
1428*94d3b452SApple OSS Distributions return kIOReturnBadArgument;
1429*94d3b452SApple OSS Distributions }
1430*94d3b452SApple OSS Distributions
1431*94d3b452SApple OSS Distributions IOReturn result = kIOReturnSuccess;
1432*94d3b452SApple OSS Distributions size_t planeCount = IOSurfaceGetPlaneCount(surface);
1433*94d3b452SApple OSS Distributions
1434*94d3b452SApple OSS Distributions if (planeCount == 0) {
1435*94d3b452SApple OSS Distributions result = IOSurfaceLock(surface, 0, NULL);
1436*94d3b452SApple OSS Distributions if (result != kIOReturnSuccess) {
1437*94d3b452SApple OSS Distributions return result;
1438*94d3b452SApple OSS Distributions }
1439*94d3b452SApple OSS Distributions
1440*94d3b452SApple OSS Distributions void* base = IOSurfaceGetBaseAddress(surface);
1441*94d3b452SApple OSS Distributions size_t rb = IOSurfaceGetBytesPerRow(surface);
1442*94d3b452SApple OSS Distributions size_t w = IOSurfaceGetWidth(surface);
1443*94d3b452SApple OSS Distributions size_t h = IOSurfaceGetHeight(surface);
1444*94d3b452SApple OSS Distributions
1445*94d3b452SApple OSS Distributions if (base && rb && w && h) {
1446*94d3b452SApple OSS Distributions block(base, 0, w, h, rb);
1447*94d3b452SApple OSS Distributions }
1448*94d3b452SApple OSS Distributions
1449*94d3b452SApple OSS Distributions IOSurfaceUnlock(surface, 0, NULL);
1450*94d3b452SApple OSS Distributions } else if (planeCount == 2) {
1451*94d3b452SApple OSS Distributions for (size_t i = 0; i < planeCount; i++) {
1452*94d3b452SApple OSS Distributions result = IOSurfaceLock(surface, 0, NULL);
1453*94d3b452SApple OSS Distributions if (result != kIOReturnSuccess) {
1454*94d3b452SApple OSS Distributions return result;
1455*94d3b452SApple OSS Distributions }
1456*94d3b452SApple OSS Distributions
1457*94d3b452SApple OSS Distributions void* base = IOSurfaceGetBaseAddressOfPlane(surface, i);
1458*94d3b452SApple OSS Distributions size_t rb = IOSurfaceGetBytesPerRowOfPlane(surface, i);
1459*94d3b452SApple OSS Distributions size_t w = IOSurfaceGetWidthOfPlane(surface, i);
1460*94d3b452SApple OSS Distributions size_t h = IOSurfaceGetHeightOfPlane(surface, i);
1461*94d3b452SApple OSS Distributions
1462*94d3b452SApple OSS Distributions if (base && rb && w && h) {
1463*94d3b452SApple OSS Distributions block(base, i, w, h, rb);
1464*94d3b452SApple OSS Distributions }
1465*94d3b452SApple OSS Distributions
1466*94d3b452SApple OSS Distributions IOSurfaceUnlock(surface, 0, NULL);
1467*94d3b452SApple OSS Distributions }
1468*94d3b452SApple OSS Distributions }
1469*94d3b452SApple OSS Distributions return result;
1470*94d3b452SApple OSS Distributions }
1471*94d3b452SApple OSS Distributions static void
ClearSurface(IOSurfaceRef surface)1472*94d3b452SApple OSS Distributions ClearSurface(IOSurfaceRef surface)
1473*94d3b452SApple OSS Distributions {
1474*94d3b452SApple OSS Distributions const int zero = 0;
1475*94d3b452SApple OSS Distributions (void) SurfaceApplyPlaneBlock(surface, ^(void *p, size_t i, __unused size_t w, size_t h, size_t rb)
1476*94d3b452SApple OSS Distributions {
1477*94d3b452SApple OSS Distributions if (i == 0) {
1478*94d3b452SApple OSS Distributions memset(p, zero, rb * h);
1479*94d3b452SApple OSS Distributions } else {
1480*94d3b452SApple OSS Distributions memset(p, 128, rb * h);
1481*94d3b452SApple OSS Distributions }
1482*94d3b452SApple OSS Distributions });
1483*94d3b452SApple OSS Distributions }
1484*94d3b452SApple OSS Distributions static size_t
SurfaceGetMemorySize(IOSurfaceRef surface)1485*94d3b452SApple OSS Distributions SurfaceGetMemorySize(IOSurfaceRef surface)
1486*94d3b452SApple OSS Distributions {
1487*94d3b452SApple OSS Distributions size_t planeCount = IOSurfaceGetPlaneCount(surface);
1488*94d3b452SApple OSS Distributions
1489*94d3b452SApple OSS Distributions if (planeCount == 0) {
1490*94d3b452SApple OSS Distributions size_t rb = IOSurfaceGetBytesPerRow(surface);
1491*94d3b452SApple OSS Distributions size_t h = IOSurfaceGetHeight(surface);
1492*94d3b452SApple OSS Distributions return rb * h;
1493*94d3b452SApple OSS Distributions } else if (planeCount == 2) {
1494*94d3b452SApple OSS Distributions size_t rb0 = IOSurfaceGetBytesPerRowOfPlane(surface, 0);
1495*94d3b452SApple OSS Distributions size_t h0 = IOSurfaceGetHeightOfPlane(surface, 0);
1496*94d3b452SApple OSS Distributions size_t rb1 = IOSurfaceGetBytesPerRowOfPlane(surface, 1);
1497*94d3b452SApple OSS Distributions size_t h1 = IOSurfaceGetHeightOfPlane(surface, 1);
1498*94d3b452SApple OSS Distributions return rb0 * h0 + rb1 * h1;
1499*94d3b452SApple OSS Distributions }
1500*94d3b452SApple OSS Distributions return 0;
1501*94d3b452SApple OSS Distributions }
1502*94d3b452SApple OSS Distributions static IOSurfaceRef
CreateSurface(uint32_t pixelsWide,uint32_t pixelsHigh,uint32_t rowBytesAlignment,uint32_t fmt,bool purgeable,bool clear)1503*94d3b452SApple OSS Distributions CreateSurface(uint32_t pixelsWide, uint32_t pixelsHigh, uint32_t rowBytesAlignment, uint32_t fmt, bool purgeable, bool clear)
1504*94d3b452SApple OSS Distributions {
1505*94d3b452SApple OSS Distributions IOSurfaceRef surface = nil;
1506*94d3b452SApple OSS Distributions
1507*94d3b452SApple OSS Distributions if (pixelsWide < 1 || pixelsHigh < 1 || fmt == 0) {
1508*94d3b452SApple OSS Distributions return nil;
1509*94d3b452SApple OSS Distributions }
1510*94d3b452SApple OSS Distributions
1511*94d3b452SApple OSS Distributions size_t bpp = bytes_per_pixel(fmt);
1512*94d3b452SApple OSS Distributions size_t bpe = bytes_per_element(fmt);
1513*94d3b452SApple OSS Distributions if (bpp == 0 || bpe == 0) {
1514*94d3b452SApple OSS Distributions return nil;
1515*94d3b452SApple OSS Distributions }
1516*94d3b452SApple OSS Distributions
1517*94d3b452SApple OSS Distributions size_t rowbytes = pixelsWide * bpp;
1518*94d3b452SApple OSS Distributions if (rowBytesAlignment == 0) {
1519*94d3b452SApple OSS Distributions rowBytesAlignment = 16;
1520*94d3b452SApple OSS Distributions }
1521*94d3b452SApple OSS Distributions rowbytes = roundSizeToMultiple(rowbytes, rowBytesAlignment);
1522*94d3b452SApple OSS Distributions
1523*94d3b452SApple OSS Distributions CFMutableDictionaryRef props = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
1524*94d3b452SApple OSS Distributions setIntValue(props, kIOSurfaceBytesPerRow, (int)rowbytes);
1525*94d3b452SApple OSS Distributions setIntValue(props, kIOSurfaceWidth, (int)pixelsWide);
1526*94d3b452SApple OSS Distributions setIntValue(props, kIOSurfaceHeight, (int)pixelsHigh);
1527*94d3b452SApple OSS Distributions setIntValue(props, kIOSurfacePixelFormat, (int)fmt);
1528*94d3b452SApple OSS Distributions #if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
1529*94d3b452SApple OSS Distributions setBoolValue(props, kIOSurfaceNonPurgeable, !purgeable);
1530*94d3b452SApple OSS Distributions #else /* (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR) */
1531*94d3b452SApple OSS Distributions (void)purgeable;
1532*94d3b452SApple OSS Distributions #endif /* (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR) */
1533*94d3b452SApple OSS Distributions {
1534*94d3b452SApple OSS Distributions if (bpe != bpp) { // i.e. a 422 format such as 'yuvf' etc.
1535*94d3b452SApple OSS Distributions setIntValue(props, kIOSurfaceElementWidth, 2);
1536*94d3b452SApple OSS Distributions setIntValue(props, kIOSurfaceElementHeight, 1);
1537*94d3b452SApple OSS Distributions }
1538*94d3b452SApple OSS Distributions setIntValue(props, kIOSurfaceBytesPerElement, (int)bpe);
1539*94d3b452SApple OSS Distributions }
1540*94d3b452SApple OSS Distributions
1541*94d3b452SApple OSS Distributions surface = IOSurfaceCreate(props);
1542*94d3b452SApple OSS Distributions
1543*94d3b452SApple OSS Distributions if (clear) {
1544*94d3b452SApple OSS Distributions ClearSurface(surface);
1545*94d3b452SApple OSS Distributions }
1546*94d3b452SApple OSS Distributions
1547*94d3b452SApple OSS Distributions CFRelease(props);
1548*94d3b452SApple OSS Distributions return surface;
1549*94d3b452SApple OSS Distributions }
1550*94d3b452SApple OSS Distributions T_DECL(phys_footprint_purgeable_iokit,
1551*94d3b452SApple OSS Distributions "phys_footprint for purgeable IOKit memory",
1552*94d3b452SApple OSS Distributions T_META_LTEPHASE(LTE_POSTINIT))
1553*94d3b452SApple OSS Distributions {
1554*94d3b452SApple OSS Distributions uint64_t footprint_before, pagetable_before;
1555*94d3b452SApple OSS Distributions uint64_t footprint_after, pagetable_after;
1556*94d3b452SApple OSS Distributions uint64_t footprint_expected, footprint_delta_slop;
1557*94d3b452SApple OSS Distributions int64_t footprint_delta;
1558*94d3b452SApple OSS Distributions IOSurfaceRef surface;
1559*94d3b452SApple OSS Distributions uint32_t old_state;
1560*94d3b452SApple OSS Distributions uint64_t surface_size;
1561*94d3b452SApple OSS Distributions
1562*94d3b452SApple OSS Distributions T_SETUPBEGIN;
1563*94d3b452SApple OSS Distributions footprint_delta_slop = 8 * vm_kernel_page_size;
1564*94d3b452SApple OSS Distributions ledger_init();
1565*94d3b452SApple OSS Distributions surface = CreateSurface(1024, 1024, 0, 32, true, true);
1566*94d3b452SApple OSS Distributions IOSurfaceSetPurgeable(surface, kIOSurfacePurgeableVolatile, &old_state);
1567*94d3b452SApple OSS Distributions IOSurfaceSetPurgeable(surface, kIOSurfacePurgeableNonVolatile, &old_state);
1568*94d3b452SApple OSS Distributions CFRelease(surface);
1569*94d3b452SApple OSS Distributions T_SETUPEND;
1570*94d3b452SApple OSS Distributions
1571*94d3b452SApple OSS Distributions surface_size = 1024 * 1024 * 4;
1572*94d3b452SApple OSS Distributions
1573*94d3b452SApple OSS Distributions /* create IOsurface: footprint grows */
1574*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1575*94d3b452SApple OSS Distributions surface = CreateSurface(1024, 1024, 0, 32, true, true);
1576*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1577*94d3b452SApple OSS Distributions if (legacy_footprint) {
1578*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
1579*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1580*94d3b452SApple OSS Distributions footprint_delta = (int64_t)(footprint_after - footprint_expected);
1581*94d3b452SApple OSS Distributions T_LOG("LEGACY FOOTPRINT: creating purgeable IOSurface: no footprint impact");
1582*94d3b452SApple OSS Distributions T_EXPECT_LE((uint64_t)llabs(footprint_delta), footprint_delta_slop,
1583*94d3b452SApple OSS Distributions "create purgeable IOSurface %lld bytes: "
1584*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1585*94d3b452SApple OSS Distributions surface_size, footprint_before, footprint_after,
1586*94d3b452SApple OSS Distributions footprint_expected, footprint_delta);
1587*94d3b452SApple OSS Distributions } else {
1588*94d3b452SApple OSS Distributions footprint_expected = footprint_before + surface_size;
1589*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1590*94d3b452SApple OSS Distributions footprint_delta = (int64_t)(footprint_after - footprint_expected);
1591*94d3b452SApple OSS Distributions T_LOG("creating purgeable IOSurface increases phys_footprint");
1592*94d3b452SApple OSS Distributions T_EXPECT_LE((uint64_t)llabs(footprint_delta), footprint_delta_slop,
1593*94d3b452SApple OSS Distributions "create purgeable IOSurface %lld bytes: "
1594*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1595*94d3b452SApple OSS Distributions surface_size, footprint_before, footprint_after,
1596*94d3b452SApple OSS Distributions footprint_expected, footprint_delta);
1597*94d3b452SApple OSS Distributions }
1598*94d3b452SApple OSS Distributions
1599*94d3b452SApple OSS Distributions /* make IOSurface volatile: footprint shrinks */
1600*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1601*94d3b452SApple OSS Distributions IOSurfaceSetPurgeable(surface, kIOSurfacePurgeableVolatile, &old_state);
1602*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1603*94d3b452SApple OSS Distributions if (legacy_footprint) {
1604*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
1605*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1606*94d3b452SApple OSS Distributions T_LOG("LEGACY FOOTPRINT: volatile IOSurface: no footprint impact");
1607*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1608*94d3b452SApple OSS Distributions "volatile IOSurface %lld bytes: "
1609*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1610*94d3b452SApple OSS Distributions surface_size, footprint_before, footprint_after,
1611*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1612*94d3b452SApple OSS Distributions } else {
1613*94d3b452SApple OSS Distributions footprint_expected = footprint_before - surface_size;
1614*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1615*94d3b452SApple OSS Distributions T_LOG("making IOSurface volatile decreases phys_footprint");
1616*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1617*94d3b452SApple OSS Distributions "made volatile %lld bytes: "
1618*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1619*94d3b452SApple OSS Distributions surface_size, footprint_before, footprint_after,
1620*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1621*94d3b452SApple OSS Distributions }
1622*94d3b452SApple OSS Distributions
1623*94d3b452SApple OSS Distributions /* make IOSurface non-volatile: footprint grows */
1624*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1625*94d3b452SApple OSS Distributions IOSurfaceSetPurgeable(surface, kIOSurfacePurgeableNonVolatile, &old_state);
1626*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1627*94d3b452SApple OSS Distributions if (legacy_footprint) {
1628*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
1629*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1630*94d3b452SApple OSS Distributions T_LOG("LEGACY FOOTPRINT: non-volatile IOSurface: no footprint impact");
1631*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1632*94d3b452SApple OSS Distributions "non-volatile IOSurface %lld bytes: "
1633*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1634*94d3b452SApple OSS Distributions surface_size, footprint_before, footprint_after,
1635*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1636*94d3b452SApple OSS Distributions } else {
1637*94d3b452SApple OSS Distributions footprint_expected = footprint_before + surface_size;
1638*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1639*94d3b452SApple OSS Distributions T_LOG("making IOSurface non-volatile increases phys_footprint");
1640*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1641*94d3b452SApple OSS Distributions "made non-volatile %lld bytes: "
1642*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1643*94d3b452SApple OSS Distributions surface_size, footprint_before, footprint_after,
1644*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1645*94d3b452SApple OSS Distributions }
1646*94d3b452SApple OSS Distributions
1647*94d3b452SApple OSS Distributions /* accessing IOSurface re-mapping: no footprint impact */
1648*94d3b452SApple OSS Distributions
1649*94d3b452SApple OSS Distributions /* deallocating IOSurface re-mapping: no footprint impact */
1650*94d3b452SApple OSS Distributions
1651*94d3b452SApple OSS Distributions /* release IOSurface: footprint shrinks */
1652*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1653*94d3b452SApple OSS Distributions CFRelease(surface);
1654*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1655*94d3b452SApple OSS Distributions if (legacy_footprint) {
1656*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
1657*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1658*94d3b452SApple OSS Distributions T_LOG("LEGACY FOOTPRINT: release IOSurface: no footprint impact");
1659*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1660*94d3b452SApple OSS Distributions "releasing IOSurface %lld bytes: "
1661*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1662*94d3b452SApple OSS Distributions surface_size, footprint_before, footprint_after,
1663*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1664*94d3b452SApple OSS Distributions } else {
1665*94d3b452SApple OSS Distributions footprint_expected = footprint_before - surface_size;
1666*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1667*94d3b452SApple OSS Distributions T_LOG("releasing IOSurface decreases phys_footprint");
1668*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1669*94d3b452SApple OSS Distributions "released IOSurface %lld bytes: "
1670*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1671*94d3b452SApple OSS Distributions surface_size, footprint_before, footprint_after,
1672*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1673*94d3b452SApple OSS Distributions }
1674*94d3b452SApple OSS Distributions }
1675*94d3b452SApple OSS Distributions
1676*94d3b452SApple OSS Distributions #if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
1677*94d3b452SApple OSS Distributions T_DECL(phys_footprint_nonpurgeable_iokit,
1678*94d3b452SApple OSS Distributions "phys_footprint for non-purgeable IOKit memory",
1679*94d3b452SApple OSS Distributions T_META_LTEPHASE(LTE_POSTINIT))
1680*94d3b452SApple OSS Distributions {
1681*94d3b452SApple OSS Distributions uint64_t footprint_before, pagetable_before;
1682*94d3b452SApple OSS Distributions uint64_t footprint_after, pagetable_after;
1683*94d3b452SApple OSS Distributions uint64_t footprint_expected, footprint_delta_slop;
1684*94d3b452SApple OSS Distributions int64_t footprint_delta;
1685*94d3b452SApple OSS Distributions IOSurfaceRef surface;
1686*94d3b452SApple OSS Distributions uint64_t surface_size;
1687*94d3b452SApple OSS Distributions void *map_base;
1688*94d3b452SApple OSS Distributions size_t map_size;
1689*94d3b452SApple OSS Distributions mach_vm_address_t remap_addr;
1690*94d3b452SApple OSS Distributions kern_return_t kr;
1691*94d3b452SApple OSS Distributions vm_prot_t cur_prot, max_prot;
1692*94d3b452SApple OSS Distributions uint32_t old_state;
1693*94d3b452SApple OSS Distributions
1694*94d3b452SApple OSS Distributions
1695*94d3b452SApple OSS Distributions T_SETUPBEGIN;
1696*94d3b452SApple OSS Distributions ledger_init();
1697*94d3b452SApple OSS Distributions surface = CreateSurface(1024, 1024, 0, 32, false, true);
1698*94d3b452SApple OSS Distributions CFRelease(surface);
1699*94d3b452SApple OSS Distributions footprint_delta_slop = 8 * vm_kernel_page_size;
1700*94d3b452SApple OSS Distributions T_SETUPEND;
1701*94d3b452SApple OSS Distributions
1702*94d3b452SApple OSS Distributions surface_size = 1024 * 1024 * 4;
1703*94d3b452SApple OSS Distributions
1704*94d3b452SApple OSS Distributions /* create IOsurface: footprint grows */
1705*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1706*94d3b452SApple OSS Distributions surface = CreateSurface(1024, 1024, 0, 32, false, true);
1707*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1708*94d3b452SApple OSS Distributions footprint_expected = footprint_before + surface_size;
1709*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1710*94d3b452SApple OSS Distributions footprint_delta = (int64_t)(footprint_after - footprint_expected);
1711*94d3b452SApple OSS Distributions T_LOG("creating non-purgeable IOSurface increases phys_footprint");
1712*94d3b452SApple OSS Distributions T_EXPECT_LE((uint64_t)llabs(footprint_delta), footprint_delta_slop,
1713*94d3b452SApple OSS Distributions "create non-purgeable IOSurface %lld bytes: "
1714*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1715*94d3b452SApple OSS Distributions surface_size, footprint_before, footprint_after,
1716*94d3b452SApple OSS Distributions footprint_expected, footprint_delta);
1717*94d3b452SApple OSS Distributions
1718*94d3b452SApple OSS Distributions /* make IOSurface volatile: fail and no footprint impact */
1719*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1720*94d3b452SApple OSS Distributions IOSurfaceSetPurgeable(surface, kIOSurfacePurgeableVolatile, &old_state);
1721*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1722*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
1723*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1724*94d3b452SApple OSS Distributions T_LOG("making non-purgeable IOSurface volatile: no footprint impact");
1725*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1726*94d3b452SApple OSS Distributions "made volatile %lld non-purgeable bytes: "
1727*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1728*94d3b452SApple OSS Distributions surface_size, footprint_before, footprint_after,
1729*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1730*94d3b452SApple OSS Distributions
1731*94d3b452SApple OSS Distributions /* re-mapping IOSurface: no footprint impact */
1732*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1733*94d3b452SApple OSS Distributions map_base = IOSurfaceGetBaseAddress(surface);
1734*94d3b452SApple OSS Distributions map_size = SurfaceGetMemorySize(surface);
1735*94d3b452SApple OSS Distributions // T_EXPECT_EQ(map_size, surface_size, "map_size %lld surface_size %lld",
1736*94d3b452SApple OSS Distributions // map_size, surface_size);
1737*94d3b452SApple OSS Distributions remap_addr = 0;
1738*94d3b452SApple OSS Distributions kr = mach_vm_remap(mach_task_self(),
1739*94d3b452SApple OSS Distributions &remap_addr,
1740*94d3b452SApple OSS Distributions (mach_vm_size_t)surface_size,
1741*94d3b452SApple OSS Distributions 0,
1742*94d3b452SApple OSS Distributions VM_FLAGS_ANYWHERE,
1743*94d3b452SApple OSS Distributions mach_task_self(),
1744*94d3b452SApple OSS Distributions (mach_vm_address_t)map_base,
1745*94d3b452SApple OSS Distributions FALSE, /* copy */
1746*94d3b452SApple OSS Distributions &cur_prot,
1747*94d3b452SApple OSS Distributions &max_prot,
1748*94d3b452SApple OSS Distributions VM_INHERIT_DEFAULT);
1749*94d3b452SApple OSS Distributions T_QUIET;
1750*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_remap() error 0x%x (%s)",
1751*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
1752*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1753*94d3b452SApple OSS Distributions footprint_expected = footprint_before;
1754*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1755*94d3b452SApple OSS Distributions T_LOG("re-mapping IOSurface does not impact phys_footprint");
1756*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1757*94d3b452SApple OSS Distributions "remapping IOSurface %lld bytes: "
1758*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1759*94d3b452SApple OSS Distributions surface_size, footprint_before, footprint_after,
1760*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1761*94d3b452SApple OSS Distributions
1762*94d3b452SApple OSS Distributions /* accessing IOSurface re-mapping: footprint grows */
1763*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1764*94d3b452SApple OSS Distributions memset((char *)(uintptr_t)remap_addr, 'p', (size_t)surface_size);
1765*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1766*94d3b452SApple OSS Distributions footprint_expected = footprint_before + surface_size;
1767*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1768*94d3b452SApple OSS Distributions T_LOG("accessing re-mapped IOSurface grows phys_footprint");
1769*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1770*94d3b452SApple OSS Distributions "accessing remapped IOSurface %lld bytes: "
1771*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1772*94d3b452SApple OSS Distributions surface_size, footprint_before, footprint_after,
1773*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1774*94d3b452SApple OSS Distributions
1775*94d3b452SApple OSS Distributions /* deallocating IOSurface re-mapping: footprint shrinks */
1776*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1777*94d3b452SApple OSS Distributions kr = mach_vm_deallocate(mach_task_self(),
1778*94d3b452SApple OSS Distributions remap_addr,
1779*94d3b452SApple OSS Distributions (mach_vm_size_t)surface_size);
1780*94d3b452SApple OSS Distributions T_QUIET;
1781*94d3b452SApple OSS Distributions T_EXPECT_EQ(kr, KERN_SUCCESS, "vm_deallocate() error 0x%x (%s)",
1782*94d3b452SApple OSS Distributions kr, mach_error_string(kr));
1783*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1784*94d3b452SApple OSS Distributions footprint_expected = footprint_before - surface_size;
1785*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1786*94d3b452SApple OSS Distributions T_LOG("deallocating re-mapping of IOSurface shrinks phys_footprint");
1787*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1788*94d3b452SApple OSS Distributions "deallocating remapped IOSurface %lld bytes: "
1789*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1790*94d3b452SApple OSS Distributions surface_size, footprint_before, footprint_after,
1791*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1792*94d3b452SApple OSS Distributions
1793*94d3b452SApple OSS Distributions /* release IOSurface: footprint shrinks */
1794*94d3b452SApple OSS Distributions get_ledger_info(&footprint_before, &pagetable_before);
1795*94d3b452SApple OSS Distributions CFRelease(surface);
1796*94d3b452SApple OSS Distributions get_ledger_info(&footprint_after, &pagetable_after);
1797*94d3b452SApple OSS Distributions footprint_expected = footprint_before - surface_size;
1798*94d3b452SApple OSS Distributions footprint_expected += (pagetable_after - pagetable_before);
1799*94d3b452SApple OSS Distributions T_LOG("releasing IOSurface decreases phys_footprint");
1800*94d3b452SApple OSS Distributions T_EXPECT_EQ(footprint_after, footprint_expected,
1801*94d3b452SApple OSS Distributions "released IOSurface %lld bytes: "
1802*94d3b452SApple OSS Distributions "footprint %lld -> %lld expected %lld delta %lld",
1803*94d3b452SApple OSS Distributions surface_size, footprint_before, footprint_after,
1804*94d3b452SApple OSS Distributions footprint_expected, footprint_after - footprint_expected);
1805*94d3b452SApple OSS Distributions }
1806*94d3b452SApple OSS Distributions #endif /* (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR) */
1807*94d3b452SApple OSS Distributions
1808*94d3b452SApple OSS Distributions #if 0
1809*94d3b452SApple OSS Distributions #if LEGACY_FOOTPRINT_ENTITLED && defined(__arm64__)
1810*94d3b452SApple OSS Distributions T_DECL(legacy_footprint_entitled_set_and_query,
1811*94d3b452SApple OSS Distributions "legacy footprint entitled is sticky with memlimit set properties and can be queried",
1812*94d3b452SApple OSS Distributions T_META_BOOTARGS_SET("legacy_footprint_entitlement_mode=3"))
1813*94d3b452SApple OSS Distributions {
1814*94d3b452SApple OSS Distributions int ret;
1815*94d3b452SApple OSS Distributions int32_t max_task_pmem = 0, legacy_footprint_bonus_mb = 0;
1816*94d3b452SApple OSS Distributions size_t size_max_task_pmem = sizeof(max_task_pmem);
1817*94d3b452SApple OSS Distributions size_t size_legacy_footprint_bonus_mb = sizeof(legacy_footprint_bonus_mb);
1818*94d3b452SApple OSS Distributions memorystatus_memlimit_properties2_t mmprops;
1819*94d3b452SApple OSS Distributions
1820*94d3b452SApple OSS Distributions /* Get the default limit */
1821*94d3b452SApple OSS Distributions ret = sysctlbyname("kern.max_task_pmem", &max_task_pmem, &size_max_task_pmem, NULL, 0);
1822*94d3b452SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "call sysctlbyname to get max task physical memory.");
1823*94d3b452SApple OSS Distributions
1824*94d3b452SApple OSS Distributions ret = sysctlbyname("kern.legacy_footprint_bonus_mb", &legacy_footprint_bonus_mb,
1825*94d3b452SApple OSS Distributions &size_legacy_footprint_bonus_mb, NULL, 0);
1826*94d3b452SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "call sysctlbyname to get the bonus value.");
1827*94d3b452SApple OSS Distributions
1828*94d3b452SApple OSS Distributions mmprops.v1.memlimit_active = -1;
1829*94d3b452SApple OSS Distributions mmprops.v1.memlimit_inactive = -1;
1830*94d3b452SApple OSS Distributions ret = memorystatus_control(MEMORYSTATUS_CMD_SET_MEMLIMIT_PROPERTIES, getpid(), 0, &mmprops.v1, sizeof(mmprops.v1));
1831*94d3b452SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "memorystatus_control");
1832*94d3b452SApple OSS Distributions
1833*94d3b452SApple OSS Distributions /* Check our memlimt */
1834*94d3b452SApple OSS Distributions ret = memorystatus_control(MEMORYSTATUS_CMD_GET_MEMLIMIT_PROPERTIES, getpid(), 0, &mmprops, sizeof(mmprops));
1835*94d3b452SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "memorystatus_control");
1836*94d3b452SApple OSS Distributions
1837*94d3b452SApple OSS Distributions T_QUIET; T_ASSERT_EQ(mmprops.v1.memlimit_active, max_task_pmem + legacy_footprint_bonus_mb, "active limit");
1838*94d3b452SApple OSS Distributions T_QUIET; T_ASSERT_EQ(mmprops.v1.memlimit_inactive, max_task_pmem + legacy_footprint_bonus_mb, "inactive limit");
1839*94d3b452SApple OSS Distributions
1840*94d3b452SApple OSS Distributions /* Verify MEMORYSTATUS_CMD_CONVERT_MEMLIMIT_MB */
1841*94d3b452SApple OSS Distributions ret = memorystatus_control(MEMORYSTATUS_CMD_CONVERT_MEMLIMIT_MB, getpid(), (uint32_t) -1, NULL, 0);
1842*94d3b452SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "memorystatus_control");
1843*94d3b452SApple OSS Distributions T_QUIET; T_ASSERT_EQ(ret, max_task_pmem + legacy_footprint_bonus_mb, "got bonus adjustment");
1844*94d3b452SApple OSS Distributions }
1845*94d3b452SApple OSS Distributions #endif /* LEGACY_FOOTPRINT_ENTITLED && defined(__arm64__) */
1846*94d3b452SApple OSS Distributions #endif
1847