xref: /xnu-12377.61.12/tests/host_statistics_rate_limiting.c (revision 4d495c6e23c53686cf65f45067f79024cf5dcee8)
1*4d495c6eSApple OSS Distributions #include <unistd.h>
2*4d495c6eSApple OSS Distributions #include <stdint.h>
3*4d495c6eSApple OSS Distributions #include <sys/time.h>
4*4d495c6eSApple OSS Distributions #include <System/sys/codesign.h>
5*4d495c6eSApple OSS Distributions #include <mach/mach_time.h>
6*4d495c6eSApple OSS Distributions #include <mach/mach.h>
7*4d495c6eSApple OSS Distributions #include <darwintest.h>
8*4d495c6eSApple OSS Distributions #include <stdlib.h>
9*4d495c6eSApple OSS Distributions #include <sys/sysctl.h>
10*4d495c6eSApple OSS Distributions #include "cs_helpers.h"
11*4d495c6eSApple OSS Distributions 
12*4d495c6eSApple OSS Distributions T_GLOBAL_META(T_META_RUN_CONCURRENTLY(true));
13*4d495c6eSApple OSS Distributions 
14*4d495c6eSApple OSS Distributions #if !defined(CS_OPS_CLEARPLATFORM)
15*4d495c6eSApple OSS Distributions #define CS_OPS_CLEARPLATFORM 13
16*4d495c6eSApple OSS Distributions #endif
17*4d495c6eSApple OSS Distributions 
18*4d495c6eSApple OSS Distributions #define WINDOW 1 /* seconds */
19*4d495c6eSApple OSS Distributions #define MAX_ATTEMP_PER_SEC 10
20*4d495c6eSApple OSS Distributions #define ITER 30
21*4d495c6eSApple OSS Distributions #define RETRY 5
22*4d495c6eSApple OSS Distributions 
23*4d495c6eSApple OSS Distributions struct all_host_info {
24*4d495c6eSApple OSS Distributions 	vm_statistics64_data_t host_vm_info64_rev0;
25*4d495c6eSApple OSS Distributions 	vm_statistics64_data_t host_vm_info64_rev1;
26*4d495c6eSApple OSS Distributions 	vm_statistics64_data_t host_vm_info64_rev2;
27*4d495c6eSApple OSS Distributions 	vm_extmod_statistics_data_t host_extmod_info64;
28*4d495c6eSApple OSS Distributions 	host_load_info_data_t host_load_info;
29*4d495c6eSApple OSS Distributions 	vm_statistics_data_t host_vm_info_rev0;
30*4d495c6eSApple OSS Distributions 	vm_statistics_data_t host_vm_info_rev1;
31*4d495c6eSApple OSS Distributions 	vm_statistics_data_t host_vm_info_rev2;
32*4d495c6eSApple OSS Distributions 	host_cpu_load_info_data_t host_cpu_load_info;
33*4d495c6eSApple OSS Distributions 	task_power_info_v2_data_t host_expired_task_info;
34*4d495c6eSApple OSS Distributions 	task_power_info_v2_data_t host_expired_task_info2;
35*4d495c6eSApple OSS Distributions };
36*4d495c6eSApple OSS Distributions 
37*4d495c6eSApple OSS Distributions static bool
on_rosetta(void)38*4d495c6eSApple OSS Distributions on_rosetta(void)
39*4d495c6eSApple OSS Distributions {
40*4d495c6eSApple OSS Distributions #if defined(__x86_64__)
41*4d495c6eSApple OSS Distributions 	int out_value = 0;
42*4d495c6eSApple OSS Distributions 	size_t io_size = sizeof(out_value);
43*4d495c6eSApple OSS Distributions 	if (sysctlbyname("sysctl.proc_translated", &out_value, &io_size, NULL, 0) == 0) {
44*4d495c6eSApple OSS Distributions 		assert(io_size >= sizeof(out_value));
45*4d495c6eSApple OSS Distributions 		return out_value;
46*4d495c6eSApple OSS Distributions 	}
47*4d495c6eSApple OSS Distributions 	return false;
48*4d495c6eSApple OSS Distributions #else /* defined(__x86_64__) */
49*4d495c6eSApple OSS Distributions 	return false;
50*4d495c6eSApple OSS Distributions #endif /* !defined(__x86_64__) */
51*4d495c6eSApple OSS Distributions }
52*4d495c6eSApple OSS Distributions 
53*4d495c6eSApple OSS Distributions static void
check_host_info(struct all_host_info * data,unsigned long iter,char lett)54*4d495c6eSApple OSS Distributions check_host_info(struct all_host_info* data, unsigned long iter, char lett)
55*4d495c6eSApple OSS Distributions {
56*4d495c6eSApple OSS Distributions 	char* datap;
57*4d495c6eSApple OSS Distributions 	unsigned long i, j;
58*4d495c6eSApple OSS Distributions 
59*4d495c6eSApple OSS Distributions 	/* check that for the shorter revisions no data is copied on the bytes of diff with the longer */
60*4d495c6eSApple OSS Distributions 	for (j = 0; j < iter; j++) {
61*4d495c6eSApple OSS Distributions 		datap = (char*) &data[j].host_vm_info64_rev0;
62*4d495c6eSApple OSS Distributions 		for (i = (HOST_VM_INFO64_REV0_COUNT * sizeof(int)); i < (HOST_VM_INFO64_REV1_COUNT * sizeof(int)); i++) {
63*4d495c6eSApple OSS Distributions 			T_QUIET; T_ASSERT_EQ(datap[i], lett, "HOST_VM_INFO64_REV0 byte %lu iter %lu", i, j);
64*4d495c6eSApple OSS Distributions 		}
65*4d495c6eSApple OSS Distributions 
66*4d495c6eSApple OSS Distributions 		datap = (char*) &data[j].host_vm_info_rev0;
67*4d495c6eSApple OSS Distributions 		for (i = (HOST_VM_INFO_REV0_COUNT * sizeof(int)); i < (HOST_VM_INFO_REV2_COUNT * sizeof(int)); i++) {
68*4d495c6eSApple OSS Distributions 			T_QUIET; T_ASSERT_EQ(datap[i], lett, "HOST_VM_INFO_REV0 byte %lu iter %lu", i, j);
69*4d495c6eSApple OSS Distributions 		}
70*4d495c6eSApple OSS Distributions 
71*4d495c6eSApple OSS Distributions 		datap = (char*) &data[j].host_vm_info_rev1;
72*4d495c6eSApple OSS Distributions 		for (i = (HOST_VM_INFO_REV1_COUNT * sizeof(int)); i < (HOST_VM_INFO_REV2_COUNT * sizeof(int)); i++) {
73*4d495c6eSApple OSS Distributions 			T_QUIET; T_ASSERT_EQ(datap[i], lett, "HOST_VM_INFO_REV1 byte %lu iter %lu", i, j);
74*4d495c6eSApple OSS Distributions 		}
75*4d495c6eSApple OSS Distributions 
76*4d495c6eSApple OSS Distributions 		datap = (char*) &data[j].host_expired_task_info;
77*4d495c6eSApple OSS Distributions 		for (i = (TASK_POWER_INFO_COUNT * sizeof(int)); i < (TASK_POWER_INFO_V2_COUNT * sizeof(int)); i++) {
78*4d495c6eSApple OSS Distributions 			T_QUIET; T_ASSERT_EQ(datap[i], lett, "TASK_POWER_INFO_COUNT byte %lu iter %lu", i, j);
79*4d495c6eSApple OSS Distributions 		}
80*4d495c6eSApple OSS Distributions 	}
81*4d495c6eSApple OSS Distributions 	T_LOG("No data overflow");
82*4d495c6eSApple OSS Distributions 
83*4d495c6eSApple OSS Distributions 	datap = (char*) data;
84*4d495c6eSApple OSS Distributions 
85*4d495c6eSApple OSS Distributions 	/* check that after MAX_ATTEMP_PER_SEC data are all the same */
86*4d495c6eSApple OSS Distributions 	for (i = 0; i < sizeof(struct all_host_info); i++) {
87*4d495c6eSApple OSS Distributions 		for (j = MAX_ATTEMP_PER_SEC - 1; j < iter - 1; j++) {
88*4d495c6eSApple OSS Distributions 			T_QUIET; T_ASSERT_EQ(datap[i + (j * sizeof(struct all_host_info))], datap[i + ((j + 1) * sizeof(struct all_host_info))], "all_host_info iter %lu does not match iter %lu", j, j + 1);
89*4d495c6eSApple OSS Distributions 		}
90*4d495c6eSApple OSS Distributions 	}
91*4d495c6eSApple OSS Distributions 
92*4d495c6eSApple OSS Distributions 	T_LOG("Data was cached");
93*4d495c6eSApple OSS Distributions }
94*4d495c6eSApple OSS Distributions 
95*4d495c6eSApple OSS Distributions static void
get_host_info(struct all_host_info * data,host_t self,int iter)96*4d495c6eSApple OSS Distributions get_host_info(struct all_host_info* data, host_t self, int iter)
97*4d495c6eSApple OSS Distributions {
98*4d495c6eSApple OSS Distributions 	int i;
99*4d495c6eSApple OSS Distributions 	unsigned int count;
100*4d495c6eSApple OSS Distributions 	for (i = 0; i < iter; i++) {
101*4d495c6eSApple OSS Distributions 		count = HOST_VM_INFO64_REV0_COUNT;
102*4d495c6eSApple OSS Distributions 		T_QUIET; T_ASSERT_POSIX_ZERO(host_statistics64(self, HOST_VM_INFO64, (host_info64_t)&data[i].host_vm_info64_rev0, &count), NULL);
103*4d495c6eSApple OSS Distributions 		T_QUIET; T_ASSERT_EQ(count, HOST_VM_INFO64_REV0_COUNT, NULL);
104*4d495c6eSApple OSS Distributions 
105*4d495c6eSApple OSS Distributions 		count = HOST_VM_INFO64_REV1_COUNT;
106*4d495c6eSApple OSS Distributions 		T_QUIET; T_ASSERT_POSIX_ZERO(host_statistics64(self, HOST_VM_INFO64, (host_info64_t)&data[i].host_vm_info64_rev1, &count), NULL);
107*4d495c6eSApple OSS Distributions 		T_QUIET; T_ASSERT_EQ(count, HOST_VM_INFO64_REV1_COUNT, NULL);
108*4d495c6eSApple OSS Distributions 
109*4d495c6eSApple OSS Distributions 		count = HOST_VM_INFO64_REV2_COUNT;
110*4d495c6eSApple OSS Distributions 		T_QUIET; T_ASSERT_POSIX_ZERO(host_statistics64(self, HOST_VM_INFO64, (host_info64_t)&data[i].host_vm_info64_rev2, &count), NULL);
111*4d495c6eSApple OSS Distributions 		T_QUIET; T_ASSERT_EQ(count, HOST_VM_INFO64_REV2_COUNT, NULL);
112*4d495c6eSApple OSS Distributions 
113*4d495c6eSApple OSS Distributions 		count = HOST_EXTMOD_INFO64_COUNT;
114*4d495c6eSApple OSS Distributions 		T_QUIET; T_ASSERT_POSIX_ZERO(host_statistics64(self, HOST_EXTMOD_INFO64, (host_info64_t)&data[i].host_extmod_info64, &count), NULL);
115*4d495c6eSApple OSS Distributions 		T_QUIET; T_ASSERT_EQ(count, HOST_EXTMOD_INFO64_COUNT, NULL);
116*4d495c6eSApple OSS Distributions 
117*4d495c6eSApple OSS Distributions 		count = HOST_LOAD_INFO_COUNT;
118*4d495c6eSApple OSS Distributions 		T_QUIET; T_ASSERT_POSIX_ZERO(host_statistics(self, HOST_LOAD_INFO, (host_info_t)&data[i].host_load_info, &count), NULL);
119*4d495c6eSApple OSS Distributions 		T_QUIET; T_ASSERT_EQ(count, HOST_LOAD_INFO_COUNT, NULL);
120*4d495c6eSApple OSS Distributions 
121*4d495c6eSApple OSS Distributions 		count = HOST_VM_INFO_REV0_COUNT;
122*4d495c6eSApple OSS Distributions 		T_QUIET; T_ASSERT_POSIX_ZERO(host_statistics(self, HOST_VM_INFO, (host_info_t)&data[i].host_vm_info_rev0, &count), NULL);
123*4d495c6eSApple OSS Distributions 		T_QUIET; T_ASSERT_EQ(count, HOST_VM_INFO_REV0_COUNT, NULL);
124*4d495c6eSApple OSS Distributions 
125*4d495c6eSApple OSS Distributions 		count = HOST_VM_INFO_REV1_COUNT;
126*4d495c6eSApple OSS Distributions 		T_QUIET; T_ASSERT_POSIX_ZERO(host_statistics(self, HOST_VM_INFO, (host_info_t)&data[i].host_vm_info_rev1, &count), NULL);
127*4d495c6eSApple OSS Distributions 		T_QUIET; T_ASSERT_EQ(count, HOST_VM_INFO_REV1_COUNT, NULL);
128*4d495c6eSApple OSS Distributions 
129*4d495c6eSApple OSS Distributions 		count = HOST_VM_INFO_REV2_COUNT;
130*4d495c6eSApple OSS Distributions 		T_QUIET; T_ASSERT_POSIX_ZERO(host_statistics(self, HOST_VM_INFO, (host_info_t)&data[i].host_vm_info_rev2, &count), NULL);
131*4d495c6eSApple OSS Distributions 		T_QUIET; T_ASSERT_EQ(count, HOST_VM_INFO_REV2_COUNT, NULL);
132*4d495c6eSApple OSS Distributions 
133*4d495c6eSApple OSS Distributions 		count = HOST_CPU_LOAD_INFO_COUNT;
134*4d495c6eSApple OSS Distributions 		T_QUIET; T_ASSERT_POSIX_ZERO(host_statistics(self, HOST_CPU_LOAD_INFO, (host_info_t)&data[i].host_cpu_load_info, &count), NULL);
135*4d495c6eSApple OSS Distributions 		T_QUIET; T_ASSERT_EQ(count, HOST_CPU_LOAD_INFO_COUNT, NULL);
136*4d495c6eSApple OSS Distributions 
137*4d495c6eSApple OSS Distributions 		count = TASK_POWER_INFO_COUNT;
138*4d495c6eSApple OSS Distributions 		T_QUIET; T_ASSERT_POSIX_ZERO(host_statistics(self, HOST_EXPIRED_TASK_INFO, (host_info_t)&data[i].host_expired_task_info, &count), NULL);
139*4d495c6eSApple OSS Distributions 		if (!on_rosetta()) {
140*4d495c6eSApple OSS Distributions 			/* rdar://61083333 */
141*4d495c6eSApple OSS Distributions 			T_QUIET; T_ASSERT_EQ(count, TASK_POWER_INFO_COUNT, NULL);
142*4d495c6eSApple OSS Distributions 		}
143*4d495c6eSApple OSS Distributions 
144*4d495c6eSApple OSS Distributions 		count = TASK_POWER_INFO_V2_COUNT;
145*4d495c6eSApple OSS Distributions 		T_QUIET; T_ASSERT_POSIX_ZERO(host_statistics(self, HOST_EXPIRED_TASK_INFO, (host_info_t)&data[i].host_expired_task_info2, &count), NULL);
146*4d495c6eSApple OSS Distributions 		if (!on_rosetta()) {
147*4d495c6eSApple OSS Distributions 			/* rdar://61083333 */
148*4d495c6eSApple OSS Distributions 			T_QUIET; T_ASSERT_EQ(count, TASK_POWER_INFO_V2_COUNT, NULL);
149*4d495c6eSApple OSS Distributions 		}
150*4d495c6eSApple OSS Distributions 	}
151*4d495c6eSApple OSS Distributions }
152*4d495c6eSApple OSS Distributions 
153*4d495c6eSApple OSS Distributions T_DECL(test_host_statistics, "testing rate limit for host_statistics",
154*4d495c6eSApple OSS Distributions     T_META_CHECK_LEAKS(false),
155*4d495c6eSApple OSS Distributions     T_META_ALL_VALID_ARCHS(true),
156*4d495c6eSApple OSS Distributions     T_META_TAG_VM_NOT_PREFERRED,
157*4d495c6eSApple OSS Distributions     T_META_ENABLED(false) /* rdar://134505671 */)
158*4d495c6eSApple OSS Distributions {
159*4d495c6eSApple OSS Distributions 	unsigned long long start, end, window;
160*4d495c6eSApple OSS Distributions 	int retry = 0;
161*4d495c6eSApple OSS Distributions 	host_t self;
162*4d495c6eSApple OSS Distributions 	char lett = 'a';
163*4d495c6eSApple OSS Distributions 	struct all_host_info* data;
164*4d495c6eSApple OSS Distributions 	mach_timebase_info_data_t timebaseInfo = { 0, 0 };
165*4d495c6eSApple OSS Distributions 
166*4d495c6eSApple OSS Distributions 	if (remove_platform_binary()) {
167*4d495c6eSApple OSS Distributions 		T_SKIP("Failed to remove platform binary");
168*4d495c6eSApple OSS Distributions 	}
169*4d495c6eSApple OSS Distributions 
170*4d495c6eSApple OSS Distributions 	data = malloc(ITER * sizeof(struct all_host_info));
171*4d495c6eSApple OSS Distributions 	T_QUIET; T_ASSERT_NE(data, NULL, "malloc");
172*4d495c6eSApple OSS Distributions 
173*4d495c6eSApple OSS Distributions 	/* check the size of the data structure against the bytes in COUNT*/
174*4d495c6eSApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(sizeof(data[0].host_vm_info64_rev0), HOST_VM_INFO64_COUNT * sizeof(int), "HOST_VM_INFO64_COUNT");
175*4d495c6eSApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(sizeof(data[0].host_extmod_info64), HOST_EXTMOD_INFO64_COUNT * sizeof(int), "HOST_EXTMOD_INFO64_COUNT");
176*4d495c6eSApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(sizeof(data[0].host_load_info), HOST_LOAD_INFO_COUNT * sizeof(int), "HOST_LOAD_INFO_COUNT");
177*4d495c6eSApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(sizeof(data[0].host_vm_info_rev0), HOST_VM_INFO_COUNT * sizeof(int), "HOST_VM_INFO_COUNT");
178*4d495c6eSApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(sizeof(data[0].host_cpu_load_info), HOST_CPU_LOAD_INFO_COUNT * sizeof(int), "HOST_CPU_LOAD_INFO_COUNT");
179*4d495c6eSApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(sizeof(data[0].host_expired_task_info2), TASK_POWER_INFO_V2_COUNT * sizeof(int), "TASK_POWER_INFO_V2_COUNT");
180*4d495c6eSApple OSS Distributions 
181*4d495c6eSApple OSS Distributions 	/* check that the latest revision is the COUNT */
182*4d495c6eSApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(HOST_VM_INFO64_REV2_COUNT, HOST_VM_INFO64_COUNT, "HOST_VM_INFO64_REV2_COUNT");
183*4d495c6eSApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(HOST_VM_INFO_REV2_COUNT, HOST_VM_INFO_COUNT, "HOST_VM_INFO_REV2_COUNT");
184*4d495c6eSApple OSS Distributions 
185*4d495c6eSApple OSS Distributions 	/* check that the previous revision are smaller than the latest */
186*4d495c6eSApple OSS Distributions 	T_QUIET; T_ASSERT_LE(HOST_VM_INFO64_REV0_COUNT, HOST_VM_INFO64_REV1_COUNT, "HOST_VM_INFO64_REV0");
187*4d495c6eSApple OSS Distributions 	T_QUIET; T_ASSERT_LE(HOST_VM_INFO64_REV1_COUNT, HOST_VM_INFO64_REV2_COUNT, "HOST_VM_INFO64_REV1");
188*4d495c6eSApple OSS Distributions 	T_QUIET; T_ASSERT_LE(HOST_VM_INFO_REV0_COUNT, HOST_VM_INFO_REV2_COUNT, "HOST_VM_INFO_REV0_COUNT");
189*4d495c6eSApple OSS Distributions 	T_QUIET; T_ASSERT_LE(HOST_VM_INFO_REV1_COUNT, HOST_VM_INFO_REV2_COUNT, "HOST_VM_INFO_REV1_COUNT");
190*4d495c6eSApple OSS Distributions 	T_QUIET; T_ASSERT_LE(TASK_POWER_INFO_COUNT, TASK_POWER_INFO_V2_COUNT, "TASK_POWER_INFO_COUNT");
191*4d495c6eSApple OSS Distributions 
192*4d495c6eSApple OSS Distributions 	memset(data, lett, ITER * sizeof(struct all_host_info));
193*4d495c6eSApple OSS Distributions 	self = mach_host_self();
194*4d495c6eSApple OSS Distributions 
195*4d495c6eSApple OSS Distributions 	T_QUIET; T_ASSERT_EQ(mach_timebase_info(&timebaseInfo), KERN_SUCCESS, NULL);
196*4d495c6eSApple OSS Distributions 	window = (WINDOW * NSEC_PER_SEC * timebaseInfo.denom) / timebaseInfo.numer;
197*4d495c6eSApple OSS Distributions 	retry = 0;
198*4d495c6eSApple OSS Distributions 
199*4d495c6eSApple OSS Distributions 	/* try to get ITER copies of host_info within window time, in such a way we should hit for sure a cached copy */
200*4d495c6eSApple OSS Distributions 	do {
201*4d495c6eSApple OSS Distributions 		start = mach_continuous_time();
202*4d495c6eSApple OSS Distributions 		get_host_info(data, self, ITER);
203*4d495c6eSApple OSS Distributions 		end = mach_continuous_time();
204*4d495c6eSApple OSS Distributions 		retry++;
205*4d495c6eSApple OSS Distributions 	} while ((end - start > window) && retry <= RETRY);
206*4d495c6eSApple OSS Distributions 
207*4d495c6eSApple OSS Distributions 	if (retry <= RETRY) {
208*4d495c6eSApple OSS Distributions 		check_host_info(data, ITER, lett);
209*4d495c6eSApple OSS Distributions 	} else {
210*4d495c6eSApple OSS Distributions 		T_SKIP("Failed to find window for test");
211*4d495c6eSApple OSS Distributions 	}
212*4d495c6eSApple OSS Distributions }
213