tests: mem_protect/demand_paging: add paging stats tests
This uses the new functions to get paging statistics and test if they are valid. Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
parent
8eea5119d7
commit
dd239be6ec
2 changed files with 142 additions and 3 deletions
|
@ -1,2 +1,5 @@
|
|||
CONFIG_ZTEST=y
|
||||
CONFIG_DEMAND_PAGING_STATS=y
|
||||
CONFIG_DEMAND_PAGING_THREAD_STATS=y
|
||||
CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM=y
|
||||
CONFIG_TEST_USERSPACE=y
|
||||
|
|
|
@ -50,9 +50,30 @@ void test_map_anon_pages(void)
|
|||
z_page_frames_dump();
|
||||
}
|
||||
|
||||
void print_paging_stats(struct k_mem_paging_stats_t *stats, const char *scope)
|
||||
{
|
||||
printk("* Page Faults (%s):\n", scope);
|
||||
printk(" - Total: %lu\n", stats->pagefaults.cnt);
|
||||
printk(" - IRQ locked: %lu\n", stats->pagefaults.irq_locked);
|
||||
printk(" - IRQ unlocked: %lu\n", stats->pagefaults.irq_unlocked);
|
||||
#ifndef CONFIG_DEMAND_PAGING_ALLOW_IRQ
|
||||
printk(" - in ISR: %lu\n", stats->pagefaults.in_isr);
|
||||
#endif
|
||||
|
||||
printk("* Eviction (%s):\n", scope);
|
||||
printk(" - Total pages evicted: %lu\n",
|
||||
stats->eviction.clean + stats->eviction.dirty);
|
||||
printk(" - Clean pages evicted: %lu\n",
|
||||
stats->eviction.clean);
|
||||
printk(" - Dirty pages evicted: %lu\n",
|
||||
stats->eviction.dirty);
|
||||
}
|
||||
|
||||
void test_touch_anon_pages(void)
|
||||
{
|
||||
unsigned long faults;
|
||||
struct k_mem_paging_stats_t stats;
|
||||
k_tid_t tid = k_current_get();
|
||||
|
||||
faults = z_num_pagefaults_get();
|
||||
|
||||
|
@ -70,13 +91,12 @@ void test_touch_anon_pages(void)
|
|||
arena[i] = nums[i % 10];
|
||||
}
|
||||
|
||||
printk("reading data\n");
|
||||
/* And ensure it can be read back */
|
||||
printk("verify written data\n");
|
||||
for (size_t i = 0; i < arena_size; i++) {
|
||||
zassert_equal(arena[i], nums[i % 10],
|
||||
"arena corrupted at index %d (%p): got 0x%hhx expected 0x%hhx",
|
||||
i, &arena[i], arena[i], nums[i % 10]);
|
||||
arena[i] = 0;
|
||||
}
|
||||
|
||||
faults = z_num_pagefaults_get() - faults;
|
||||
|
@ -84,6 +104,42 @@ void test_touch_anon_pages(void)
|
|||
/* Specific number depends on how much RAM we have but shouldn't be 0 */
|
||||
zassert_not_equal(faults, 0UL, "no page faults handled?");
|
||||
printk("Kernel handled %lu page faults\n", faults);
|
||||
|
||||
k_mem_paging_stats_get(&stats);
|
||||
print_paging_stats(&stats, "kernel");
|
||||
zassert_not_equal(stats.eviction.dirty, 0UL,
|
||||
"there should be dirty pages being evicted.");
|
||||
|
||||
/* There should be some clean pages to be evicted now,
|
||||
* since the arena is not modified.
|
||||
*/
|
||||
printk("reading unmodified data\n");
|
||||
for (size_t i = 0; i < arena_size; i++) {
|
||||
zassert_equal(arena[i], nums[i % 10],
|
||||
"arena corrupted at index %d (%p): got 0x%hhx expected 0x%hhx",
|
||||
i, &arena[i], arena[i], nums[i % 10]);
|
||||
}
|
||||
|
||||
k_mem_paging_stats_get(&stats);
|
||||
print_paging_stats(&stats, "kernel");
|
||||
zassert_not_equal(stats.eviction.clean, 0UL,
|
||||
"there should be clean pages being evicted.");
|
||||
|
||||
/* per-thread statistics */
|
||||
printk("\nPaging stats for current thread (%p):\n", tid);
|
||||
k_mem_paging_thread_stats_get(tid, &stats);
|
||||
print_paging_stats(&stats, "thread");
|
||||
zassert_not_equal(stats.pagefaults.cnt, 0UL,
|
||||
"no page faults handled in thread?");
|
||||
zassert_not_equal(stats.eviction.dirty, 0UL,
|
||||
"test thread should have dirty pages evicted.");
|
||||
zassert_not_equal(stats.eviction.clean, 0UL,
|
||||
"test thread should have clean pages evicted.");
|
||||
|
||||
/* Reset arena to zero */
|
||||
for (size_t i = 0; i < arena_size; i++) {
|
||||
arena[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void test_k_mem_page_out(void)
|
||||
|
@ -217,6 +273,84 @@ void test_backing_store_capacity(void)
|
|||
zassert_not_equal(faults, 0, "should have had some pagefaults");
|
||||
}
|
||||
|
||||
/* Test if we can get paging statistics under usermode */
|
||||
void test_user_get_stats(void)
|
||||
{
|
||||
struct k_mem_paging_stats_t stats;
|
||||
k_tid_t tid = k_current_get();
|
||||
|
||||
/* overall kernel statistics */
|
||||
printk("\nPaging stats for kernel:\n");
|
||||
k_mem_paging_stats_get(&stats);
|
||||
print_paging_stats(&stats, "kernel - usermode");
|
||||
zassert_not_equal(stats.pagefaults.cnt, 0UL,
|
||||
"no page faults handled in thread?");
|
||||
zassert_not_equal(stats.eviction.dirty, 0UL,
|
||||
"test thread should have dirty pages evicted.");
|
||||
zassert_not_equal(stats.eviction.clean, 0UL,
|
||||
"test thread should have clean pages evicted.");
|
||||
|
||||
/* per-thread statistics */
|
||||
printk("\nPaging stats for current thread (%p):\n", tid);
|
||||
k_mem_paging_thread_stats_get(tid, &stats);
|
||||
print_paging_stats(&stats, "thread - usermode");
|
||||
zassert_not_equal(stats.pagefaults.cnt, 0UL,
|
||||
"no page faults handled in thread?");
|
||||
zassert_not_equal(stats.eviction.dirty, 0UL,
|
||||
"test thread should have dirty pages evicted.");
|
||||
zassert_not_equal(stats.eviction.clean, 0UL,
|
||||
"test thread should have clean pages evicted.");
|
||||
|
||||
}
|
||||
|
||||
/* Print the histogram and return true if histogram has non-zero values
|
||||
* in one of its bins.
|
||||
*/
|
||||
bool print_histogram(struct k_mem_paging_histogram_t *hist)
|
||||
{
|
||||
bool has_non_zero;
|
||||
uint64_t time_ns;
|
||||
int idx;
|
||||
|
||||
has_non_zero = false;
|
||||
for (idx = 0;
|
||||
idx < CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM_NUM_BINS;
|
||||
idx++) {
|
||||
time_ns = k_cyc_to_ns_ceil64(hist->bounds[idx]);
|
||||
printk(" <= %llu ns (%lu cycles): %lu\n", time_ns,
|
||||
hist->bounds[idx], hist->counts[idx]);
|
||||
if (hist->counts[idx] > 0U) {
|
||||
has_non_zero = true;
|
||||
}
|
||||
}
|
||||
|
||||
return has_non_zero;
|
||||
}
|
||||
|
||||
/* Test if we can get paging timing histograms */
|
||||
void test_user_get_hist(void)
|
||||
{
|
||||
struct k_mem_paging_histogram_t hist;
|
||||
|
||||
printk("Eviction Timing Histogram:\n");
|
||||
k_mem_paging_histogram_eviction_get(&hist);
|
||||
zassert_true(print_histogram(&hist),
|
||||
"should have non-zero counts in histogram.");
|
||||
printk("\n");
|
||||
|
||||
printk("Backing Store Page-IN Histogram:\n");
|
||||
k_mem_paging_histogram_backing_store_page_in_get(&hist);
|
||||
zassert_true(print_histogram(&hist),
|
||||
"should have non-zero counts in histogram.");
|
||||
printk("\n");
|
||||
|
||||
printk("Backing Store Page-OUT Histogram:\n");
|
||||
k_mem_paging_histogram_backing_store_page_out_get(&hist);
|
||||
zassert_true(print_histogram(&hist),
|
||||
"should have non-zero counts in histogram.");
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
/* ztest main entry*/
|
||||
void test_main(void)
|
||||
{
|
||||
|
@ -227,7 +361,9 @@ void test_main(void)
|
|||
ztest_unit_test(test_k_mem_page_in),
|
||||
ztest_unit_test(test_k_mem_pin),
|
||||
ztest_unit_test(test_k_mem_unpin),
|
||||
ztest_unit_test(test_backing_store_capacity));
|
||||
ztest_unit_test(test_backing_store_capacity),
|
||||
ztest_user_unit_test(test_user_get_stats),
|
||||
ztest_user_unit_test(test_user_get_hist));
|
||||
|
||||
ztest_run_test_suite(test_demand_paging);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue