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