kernel: enable using timing subsys to collect paging histograms

This adds bits to the paging timing histogram collection routines
so they can use timing functions to collect execution time data.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
Daniel Leung 2021-03-31 13:56:05 -07:00 committed by Anas Nashif
commit 09e8db3d68
3 changed files with 65 additions and 1 deletions

View file

@ -684,6 +684,12 @@ config DEMAND_PAGING_STATS
Should say N in production system as this is not without cost.
config DEMAND_PAGING_STATS_USING_TIMING_FUNCTIONS
bool "Use Timing Functions to Gather Demand Paging Statistics"
select TIMING_FUNCTIONS_NEED_AT_BOOT
help
Use timing functions to gather various demand paging statistics.
config DEMAND_PAGING_THREAD_STATS
bool "Gather per Thread Demand Paging Statistics"
depends on DEMAND_PAGING_STATS

View file

@ -14,6 +14,7 @@
#include <kernel_internal.h>
#include <syscall_handler.h>
#include <linker/linker-defs.h>
#include <timing/timing.h>
#include <logging/log.h>
LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL);
@ -582,15 +583,27 @@ static inline void do_backing_store_page_in(uintptr_t location)
{
#ifdef CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM
uint32_t time_diff;
#ifdef CONFIG_DEMAND_PAGING_STATS_USING_TIMING_FUNCTIONS
timing_t time_start, time_end;
time_start = timing_counter_get();
#else
uint32_t time_start;
time_start = k_cycle_get_32();
#endif /* CONFIG_DEMAND_PAGING_STATS_USING_TIMING_FUNCTIONS */
#endif /* CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM */
z_backing_store_page_in(location);
#ifdef CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM
#ifdef CONFIG_DEMAND_PAGING_STATS_USING_TIMING_FUNCTIONS
time_end = timing_counter_get();
time_diff = (uint32_t)timing_cycles_get(&time_start, &time_end);
#else
time_diff = k_cycle_get_32() - time_start;
#endif /* CONFIG_DEMAND_PAGING_STATS_USING_TIMING_FUNCTIONS */
z_paging_histogram_inc(&z_paging_histogram_backing_store_page_in,
time_diff);
@ -601,15 +614,27 @@ static inline void do_backing_store_page_out(uintptr_t location)
{
#ifdef CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM
uint32_t time_diff;
#ifdef CONFIG_DEMAND_PAGING_STATS_USING_TIMING_FUNCTIONS
timing_t time_start, time_end;
time_start = timing_counter_get();
#else
uint32_t time_start;
time_start = k_cycle_get_32();
#endif /* CONFIG_DEMAND_PAGING_STATS_USING_TIMING_FUNCTIONS */
#endif /* CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM */
z_backing_store_page_out(location);
#ifdef CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM
#ifdef CONFIG_DEMAND_PAGING_STATS_USING_TIMING_FUNCTIONS
time_end = timing_counter_get();
time_diff = (uint32_t)timing_cycles_get(&time_start, &time_end);
#else
time_diff = k_cycle_get_32() - time_start;
#endif /* CONFIG_DEMAND_PAGING_STATS_USING_TIMING_FUNCTIONS */
z_paging_histogram_inc(&z_paging_histogram_backing_store_page_out,
time_diff);
@ -901,14 +926,29 @@ static inline struct z_page_frame *do_eviction_select(bool *dirty)
struct z_page_frame *pf;
#ifdef CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM
uint32_t time_start = k_cycle_get_32();
uint32_t time_diff;
#ifdef CONFIG_DEMAND_PAGING_STATS_USING_TIMING_FUNCTIONS
timing_t time_start, time_end;
time_start = timing_counter_get();
#else
uint32_t time_start;
time_start = k_cycle_get_32();
#endif /* CONFIG_DEMAND_PAGING_STATS_USING_TIMING_FUNCTIONS */
#endif /* CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM */
pf = z_eviction_select(dirty);
#ifdef CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM
#ifdef CONFIG_DEMAND_PAGING_STATS_USING_TIMING_FUNCTIONS
time_end = timing_counter_get();
time_diff = (uint32_t)timing_cycles_get(&time_start, &time_end);
#else
time_diff = k_cycle_get_32() - time_start;
#endif /* CONFIG_DEMAND_PAGING_STATS_USING_TIMING_FUNCTIONS */
z_paging_histogram_inc(&z_paging_histogram_eviction, time_diff);
#endif /* CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM */

View file

@ -17,6 +17,23 @@ struct k_mem_paging_histogram_t z_paging_histogram_eviction;
struct k_mem_paging_histogram_t z_paging_histogram_backing_store_page_in;
struct k_mem_paging_histogram_t z_paging_histogram_backing_store_page_out;
#ifdef CONFIG_DEMAND_PAGING_STATS_USING_TIMING_FUNCTIONS
/*
* The frequency of timing functions is highly dependent on
* architecture, SoC or board. It is also not available at build time.
* Therefore, the bounds for the timing histograms needs to be defined
* externally to this file, and must be tailored to the platform
* being used.
*/
extern unsigned long
z_eviction_histogram_bounds[CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM_NUM_BINS];
extern unsigned long
z_backing_store_histogram_bounds[CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM_NUM_BINS];
#else
#define NS_TO_CYC(ns) (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 1000000U * ns)
/*
@ -53,6 +70,7 @@ z_backing_store_histogram_bounds[CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM_NUM_BINS]
NS_TO_CYC(10000),
ULONG_MAX
};
#endif /* CONFIG_DEMAND_PAGING_STATS_USING_TIMING_FUNCTIONS */
#endif /* CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM */
unsigned long z_num_pagefaults_get(void)