1*19c3b8c2SApple OSS Distributions #include <darwintest.h>
2*19c3b8c2SApple OSS Distributions #include <errno.h>
3*19c3b8c2SApple OSS Distributions #include <TargetConditionals.h>
4*19c3b8c2SApple OSS Distributions #include <mach/mach.h>
5*19c3b8c2SApple OSS Distributions #include <sys/types.h>
6*19c3b8c2SApple OSS Distributions #include <sys/sysctl.h>
7*19c3b8c2SApple OSS Distributions #include <stdio.h>
8*19c3b8c2SApple OSS Distributions #include <unistd.h>
9*19c3b8c2SApple OSS Distributions #include <string.h>
10*19c3b8c2SApple OSS Distributions #include <sys/proc.h>
11*19c3b8c2SApple OSS Distributions
12*19c3b8c2SApple OSS Distributions T_GLOBAL_META(
13*19c3b8c2SApple OSS Distributions T_META_NAMESPACE("xnu.vm"),
14*19c3b8c2SApple OSS Distributions T_META_RADAR_COMPONENT_NAME("xnu"),
15*19c3b8c2SApple OSS Distributions T_META_RADAR_COMPONENT_VERSION("VM"));
16*19c3b8c2SApple OSS Distributions
17*19c3b8c2SApple OSS Distributions static int orig_age = 0;
18*19c3b8c2SApple OSS Distributions static const char *ripe_target_age_sysctl = "vm.vm_ripe_target_age_in_secs";
19*19c3b8c2SApple OSS Distributions
20*19c3b8c2SApple OSS Distributions static void
cleanup_ripe_age(void)21*19c3b8c2SApple OSS Distributions cleanup_ripe_age(void)
22*19c3b8c2SApple OSS Distributions {
23*19c3b8c2SApple OSS Distributions int ret = sysctlbyname(ripe_target_age_sysctl, NULL, NULL, &orig_age,
24*19c3b8c2SApple OSS Distributions sizeof(orig_age));
25*19c3b8c2SApple OSS Distributions if (ret == -1) {
26*19c3b8c2SApple OSS Distributions T_LOG("non-fatal: failed to reset %s: %s", ripe_target_age_sysctl,
27*19c3b8c2SApple OSS Distributions strerror(errno));
28*19c3b8c2SApple OSS Distributions }
29*19c3b8c2SApple OSS Distributions }
30*19c3b8c2SApple OSS Distributions
31*19c3b8c2SApple OSS Distributions T_DECL(compression_sweep,
32*19c3b8c2SApple OSS Distributions "ensure some pages are compressed due to pid_hibernate",
33*19c3b8c2SApple OSS Distributions T_META_ASROOT(true),
34*19c3b8c2SApple OSS Distributions T_META_ENABLED(!TARGET_OS_OSX && !TARGET_OS_WATCH && !TARGET_OS_TV))
35*19c3b8c2SApple OSS Distributions {
36*19c3b8c2SApple OSS Distributions /*
37*19c3b8c2SApple OSS Distributions * Change the system to sweep out compressed pages that are older than
38*19c3b8c2SApple OSS Distributions * `compressed_page_target_age_secs` seconds and induce `sweep_count` sweeps
39*19c3b8c2SApple OSS Distributions * every `sleep_dur_secs` seconds.
40*19c3b8c2SApple OSS Distributions */
41*19c3b8c2SApple OSS Distributions
42*19c3b8c2SApple OSS Distributions int compressed_page_target_age_secs = 1;
43*19c3b8c2SApple OSS Distributions const int sweep_period_secs = 10;
44*19c3b8c2SApple OSS Distributions T_QUIET; T_ASSERT_GT(sweep_period_secs, compressed_page_target_age_secs,
45*19c3b8c2SApple OSS Distributions "should sleep longer than target age");
46*19c3b8c2SApple OSS Distributions const int sweep_count = 3;
47*19c3b8c2SApple OSS Distributions
48*19c3b8c2SApple OSS Distributions vm_statistics64_data_t vm_stat_before;
49*19c3b8c2SApple OSS Distributions unsigned int count = HOST_VM_INFO64_COUNT;
50*19c3b8c2SApple OSS Distributions kern_return_t kret = host_statistics64(mach_host_self(), HOST_VM_INFO64,
51*19c3b8c2SApple OSS Distributions (host_info64_t)&vm_stat_before, &count);
52*19c3b8c2SApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kret, "host_statistics64");
53*19c3b8c2SApple OSS Distributions
54*19c3b8c2SApple OSS Distributions size_t size = sizeof(orig_age);
55*19c3b8c2SApple OSS Distributions int ret = sysctlbyname(ripe_target_age_sysctl, &orig_age, &size,
56*19c3b8c2SApple OSS Distributions &compressed_page_target_age_secs,
57*19c3b8c2SApple OSS Distributions sizeof(compressed_page_target_age_secs));
58*19c3b8c2SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(ret, "temporarily set sysctl(%s) to %d",
59*19c3b8c2SApple OSS Distributions ripe_target_age_sysctl, compressed_page_target_age_secs);
60*19c3b8c2SApple OSS Distributions T_ATEND(cleanup_ripe_age);
61*19c3b8c2SApple OSS Distributions
62*19c3b8c2SApple OSS Distributions for (int i = 0; i < sweep_count; i++) {
63*19c3b8c2SApple OSS Distributions const int sweep_out_unused_compressed_command = -2;
64*19c3b8c2SApple OSS Distributions ret = pid_hibernate(sweep_out_unused_compressed_command);
65*19c3b8c2SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(ret, "pid_hibernate(sweep-unused-compressed)");
66*19c3b8c2SApple OSS Distributions sleep(sweep_period_secs);
67*19c3b8c2SApple OSS Distributions }
68*19c3b8c2SApple OSS Distributions
69*19c3b8c2SApple OSS Distributions vm_statistics64_data_t vm_stat_after;
70*19c3b8c2SApple OSS Distributions count = HOST_VM_INFO64_COUNT;
71*19c3b8c2SApple OSS Distributions kret = host_statistics64(mach_host_self(), HOST_VM_INFO64,
72*19c3b8c2SApple OSS Distributions (host_info64_t)&vm_stat_after, &count);
73*19c3b8c2SApple OSS Distributions T_QUIET; T_ASSERT_MACH_SUCCESS(kret, "host_statistics64");
74*19c3b8c2SApple OSS Distributions
75*19c3b8c2SApple OSS Distributions T_LOG("compressed %llu pages",
76*19c3b8c2SApple OSS Distributions vm_stat_after.compressions - vm_stat_before.swapouts);
77*19c3b8c2SApple OSS Distributions T_EXPECT_GT(vm_stat_after.compressions, vm_stat_before.compressions,
78*19c3b8c2SApple OSS Distributions "should have compressed some pages during sweeps");
79*19c3b8c2SApple OSS Distributions // rdar://71454311 (Compression sweep swap outs are flaky, should induce compressions)
80*19c3b8c2SApple OSS Distributions T_MAYFAIL;
81*19c3b8c2SApple OSS Distributions T_EXPECT_GT(vm_stat_after.swapouts, vm_stat_before.swapouts,
82*19c3b8c2SApple OSS Distributions "should have swapped out some pages during sweeps");
83*19c3b8c2SApple OSS Distributions }
84