2017-11-01 15:07:57 +01:00
/* SPDX-License-Identifier: GPL-2.0 */
2021-11-20 10:39:20 +01:00
#ifndef _KERNEL_STATS_H
#define _KERNEL_STATS_H
2007-07-09 18:51:58 +02:00
2022-02-13 08:19:43 +01:00
#ifdef CONFIG_SCHEDSTATS
2021-09-05 14:35:42 +00:00
extern struct static_key_false sched_schedstats ;
2007-07-09 18:51:58 +02:00
/*
* Expects runqueue lock to be held for atomicity of update
*/
static inline void
rq_sched_info_arrive ( struct rq * rq , unsigned long long delta )
{
if ( rq ) {
rq -> rq_sched_info . run_delay += delta ;
2007-10-15 17:00:12 +02:00
rq -> rq_sched_info . pcount ++ ;
2007-07-09 18:51:58 +02:00
}
}
/*
* Expects runqueue lock to be held for atomicity of update
*/
static inline void
rq_sched_info_depart ( struct rq * rq , unsigned long long delta )
{
if ( rq )
2008-12-16 23:41:22 -08:00
rq -> rq_cpu_time += delta ;
2007-07-09 18:51:58 +02:00
}
2008-07-01 14:30:06 +05:30
static inline void
2021-05-04 22:43:45 +02:00
rq_sched_info_dequeue ( struct rq * rq , unsigned long long delta )
2008-07-01 14:30:06 +05:30
{
if ( rq )
rq -> rq_sched_info . run_delay += delta ;
}
2018-03-03 14:01:12 +01:00
#define schedstat_enabled() static_branch_unlikely(&sched_schedstats)
2018-01-16 20:51:06 +01:00
#define __schedstat_inc(var) do { var++; } while (0)
2018-03-03 14:01:12 +01:00
#define schedstat_inc(var) do { if (schedstat_enabled()) { var++; } } while (0)
2018-01-23 20:34:30 +01:00
#define __schedstat_add(var, amt) do { var += (amt); } while (0)
2018-03-03 14:01:12 +01:00
#define schedstat_add(var, amt) do { if (schedstat_enabled()) { var += (amt); } } while (0)
#define __schedstat_set(var, val) do { var = (val); } while (0)
#define schedstat_set(var, val) do { if (schedstat_enabled()) { var = (val); } } while (0)
#define schedstat_val(var) (var)
#define schedstat_val_or_zero(var) ((schedstat_enabled()) ? (var) : 0)
2016-06-03 17:58:40 -05:00
2021-09-05 14:35:42 +00:00
void __update_stats_wait_start ( struct rq * rq , struct task_struct * p ,
struct sched_statistics * stats );
void __update_stats_wait_end ( struct rq * rq , struct task_struct * p ,
struct sched_statistics * stats );
void __update_stats_enqueue_sleeper ( struct rq * rq , struct task_struct * p ,
struct sched_statistics * stats );
static inline void
check_schedstat_required ( void )
{
if ( schedstat_enabled ())
return ;
/* Force schedstat enabled if a dependent tracepoint is active */
if ( trace_sched_stat_wait_enabled () ||
trace_sched_stat_sleep_enabled () ||
trace_sched_stat_iowait_enabled () ||
trace_sched_stat_blocked_enabled () ||
trace_sched_stat_runtime_enabled ())
printk_deferred_once ( "Scheduler tracepoints stat_sleep, stat_iowait, stat_blocked and stat_runtime require the kernel parameter schedstats=enable or kernel.sched_schedstats=1 \n " );
}
2018-03-03 14:01:12 +01:00
#else /* !CONFIG_SCHEDSTATS: */
2021-09-05 14:35:41 +00:00
2018-03-03 14:01:12 +01:00
static inline void rq_sched_info_arrive ( struct rq * rq , unsigned long long delta ) { }
2021-05-04 22:43:45 +02:00
static inline void rq_sched_info_dequeue ( struct rq * rq , unsigned long long delta ) { }
2018-03-03 14:01:12 +01:00
static inline void rq_sched_info_depart ( struct rq * rq , unsigned long long delta ) { }
# define schedstat_enabled() 0
# define __schedstat_inc(var) do { } while (0)
# define schedstat_inc(var) do { } while (0)
# define __schedstat_add(var, amt) do { } while (0)
# define schedstat_add(var, amt) do { } while (0)
# define __schedstat_set(var, val) do { } while (0)
# define schedstat_set(var, val) do { } while (0)
# define schedstat_val(var) 0
# define schedstat_val_or_zero(var) 0
2021-09-05 14:35:41 +00:00
2021-09-05 14:35:42 +00:00
# define __update_stats_wait_start(rq, p, stats) do { } while (0)
# define __update_stats_wait_end(rq, p, stats) do { } while (0)
# define __update_stats_enqueue_sleeper(rq, p, stats) do { } while (0)
# define check_schedstat_required() do { } while (0)
2016-06-17 12:43:24 -05:00
#endif /* CONFIG_SCHEDSTATS */
2007-07-09 18:51:58 +02:00
2021-09-05 14:35:41 +00:00
#ifdef CONFIG_FAIR_GROUP_SCHED
struct sched_entity_stats {
struct sched_entity se ;
struct sched_statistics stats ;
} __no_randomize_layout ;
#endif
static inline struct sched_statistics *
__schedstats_from_se ( struct sched_entity * se )
{
#ifdef CONFIG_FAIR_GROUP_SCHED
if ( ! entity_is_task ( se ))
return & container_of ( se , struct sched_entity_stats , se ) -> stats ;
#endif
return & task_of ( se ) -> stats ;
}
2018-10-26 15:06:27 -07:00
#ifdef CONFIG_PSI
2022-08-26 00:41:05 +08:00
void psi_task_change ( struct task_struct * task , int clear , int set );
void psi_task_switch ( struct task_struct * prev , struct task_struct * next ,
bool sleep );
2024-06-18 14:58:55 -07:00
#ifdef CONFIG_IRQ_TIME_ACCOUNTING
void psi_account_irqtime ( struct rq * rq , struct task_struct * curr , struct task_struct * prev );
2025-05-28 10:08:57 +02:00
#else /* !CONFIG_IRQ_TIME_ACCOUNTING: */
2024-06-18 14:58:55 -07:00
static inline void psi_account_irqtime ( struct rq * rq , struct task_struct * curr ,
struct task_struct * prev ) {}
2025-05-28 10:08:57 +02:00
#endif /* !CONFIG_IRQ_TIME_ACCOUNTING */
2018-10-26 15:06:27 -07:00
/*
* PSI tracks state that persists across sleeps, such as iowaits and
* memory stalls. As a result, it has to distinguish between sleeps,
2024-10-11 10:49:33 +02:00
* where a task's runnable state changes, and migrations, where a task
* and its runnable state are being moved between CPUs and runqueues.
*
* A notable case is a task whose dequeue is delayed. PSI considers
* those sleeping, but because they are still on the runqueue they can
* go through migration requeues. In this case, *sleeping* states need
* to be transferred.
2018-10-26 15:06:27 -07:00
*/
2024-10-14 10:43:58 -04:00
static inline void psi_enqueue ( struct task_struct * p , int flags )
2018-10-26 15:06:27 -07:00
{
2024-10-11 10:49:33 +02:00
int clear = 0 , set = 0 ;
2018-10-26 15:06:27 -07:00
2018-11-30 14:09:58 -08:00
if ( static_branch_likely ( & psi_disabled ))
2018-10-26 15:06:27 -07:00
return ;
2024-10-14 10:43:58 -04:00
/* Same runqueue, nothing changed for psi */
if ( flags & ENQUEUE_RESTORE )
return ;
2024-12-27 06:19:41 +00:00
/* psi_sched_switch() will handle the flags */
if ( task_on_cpu ( task_rq ( p ), p ))
return ;
2024-10-11 10:49:33 +02:00
if ( p -> se . sched_delayed ) {
/* CPU migration of "sleeping" task */
2025-03-17 11:42:52 +01:00
WARN_ON_ONCE ( ! ( flags & ENQUEUE_MIGRATED ));
2020-03-16 21:28:05 -04:00
if ( p -> in_memstall )
2018-10-26 15:06:27 -07:00
set |= TSK_MEMSTALL ;
2024-10-11 10:49:33 +02:00
if ( p -> in_iowait )
set |= TSK_IOWAIT ;
2024-10-14 10:43:58 -04:00
} else if ( flags & ENQUEUE_MIGRATED ) {
2024-10-11 10:49:33 +02:00
/* CPU migration of runnable task */
set = TSK_RUNNING ;
if ( p -> in_memstall )
set |= TSK_MEMSTALL | TSK_MEMSTALL_RUNNING ;
2018-10-26 15:06:27 -07:00
} else {
2024-10-11 10:49:33 +02:00
/* Wakeup of new or sleeping task */
2018-10-26 15:06:27 -07:00
if ( p -> in_iowait )
clear |= TSK_IOWAIT ;
2024-10-11 10:49:33 +02:00
set = TSK_RUNNING ;
if ( p -> in_memstall )
set |= TSK_MEMSTALL_RUNNING ;
2018-10-26 15:06:27 -07:00
}
psi_task_change ( p , clear , set );
}
2024-10-14 10:43:58 -04:00
static inline void psi_dequeue ( struct task_struct * p , int flags )
2018-10-26 15:06:27 -07:00
{
2018-11-30 14:09:58 -08:00
if ( static_branch_likely ( & psi_disabled ))
2018-10-26 15:06:27 -07:00
return ;
2024-10-14 10:43:58 -04:00
/* Same runqueue, nothing changed for psi */
if ( flags & DEQUEUE_SAVE )
return ;
2024-10-11 10:49:33 +02:00
2021-03-03 11:46:59 +08:00
/*
* A voluntary sleep is a dequeue followed by a task switch. To
* avoid walking all ancestors twice, psi_task_switch() handles
* TSK_RUNNING and TSK_IOWAIT for us when it moves TSK_ONCPU.
* Do nothing here.
2025-12-05 01:27:09 +00:00
*
* In the SCHED_PROXY_EXECUTION case we may do sleeping
* dequeues that are not followed by a task switch, so check
* TSK_ONCPU is set to ensure the task switch is imminent.
* Otherwise clear the flags as usual.
2021-03-03 11:46:59 +08:00
*/
2025-12-05 01:27:09 +00:00
if (( flags & DEQUEUE_SLEEP ) && ( p -> psi_flags & TSK_ONCPU ))
2024-10-14 10:43:58 -04:00
return ;
/*
* When migrating a task to another CPU, clear all psi
* state. The enqueue callback above will work it out.
*/
psi_task_change ( p , p -> psi_flags , 0 );
2018-10-26 15:06:27 -07:00
}
static inline void psi_ttwu_dequeue ( struct task_struct * p )
{
2018-11-30 14:09:58 -08:00
if ( static_branch_likely ( & psi_disabled ))
2018-10-26 15:06:27 -07:00
return ;
/*
* Is the task being migrated during a wakeup? Make sure to
* deregister its sleep-persistent psi states from the old
* queue, and let psi_enqueue() know it has to requeue.
*/
2022-09-26 16:19:31 +08:00
if ( unlikely ( p -> psi_flags )) {
2018-10-26 15:06:27 -07:00
struct rq_flags rf ;
struct rq * rq ;
rq = __task_rq_lock ( p , & rf );
2022-09-26 16:19:31 +08:00
psi_task_change ( p , p -> psi_flags , 0 );
2025-09-25 11:26:22 +02:00
__task_rq_unlock ( rq , p , & rf );
2018-10-26 15:06:27 -07:00
}
}
2020-03-16 15:13:31 -04:00
static inline void psi_sched_switch ( struct task_struct * prev ,
struct task_struct * next ,
bool sleep )
{
if ( static_branch_likely ( & psi_disabled ))
return ;
2020-03-16 15:13:32 -04:00
psi_task_switch ( prev , next , sleep );
2020-03-16 15:13:31 -04:00
}
2025-05-28 10:08:57 +02:00
#else /* !CONFIG_PSI: */
2024-10-11 10:49:33 +02:00
static inline void psi_enqueue ( struct task_struct * p , bool migrate ) {}
static inline void psi_dequeue ( struct task_struct * p , bool migrate ) {}
2018-10-26 15:06:27 -07:00
static inline void psi_ttwu_dequeue ( struct task_struct * p ) {}
2020-03-16 15:13:31 -04:00
static inline void psi_sched_switch ( struct task_struct * prev ,
struct task_struct * next ,
bool sleep ) {}
2024-06-18 14:58:55 -07:00
static inline void psi_account_irqtime ( struct rq * rq , struct task_struct * curr ,
struct task_struct * prev ) {}
2025-05-28 10:08:57 +02:00
#endif /* !CONFIG_PSI */
2018-10-26 15:06:27 -07:00
2015-06-25 23:53:37 +05:30
#ifdef CONFIG_SCHED_INFO
2007-07-09 18:51:58 +02:00
/*
2010-10-24 16:28:47 +06:00
* We are interested in knowing how long it was from the *first* time a
2018-03-03 14:01:12 +01:00
* task was queued to the time that it finally hit a CPU, we call this routine
* from dequeue_task() to account for possible rq->clock skew across CPUs. The
* delta taken on each CPU would annul the skew.
2007-07-09 18:51:58 +02:00
*/
2021-05-04 22:43:45 +02:00
static inline void sched_info_dequeue ( struct rq * rq , struct task_struct * t )
2007-07-09 18:51:58 +02:00
{
2021-05-04 22:43:42 +02:00
unsigned long long delta = 0 ;
2008-07-01 14:30:06 +05:30
2021-05-12 13:32:37 +02:00
if ( ! t -> sched_info . last_queued )
return ;
delta = rq_clock ( rq ) - t -> sched_info . last_queued ;
t -> sched_info . last_queued = 0 ;
2008-07-01 14:30:06 +05:30
t -> sched_info . run_delay += delta ;
2026-01-19 10:02:41 +08:00
if ( delta > t -> sched_info . max_run_delay ) {
2024-12-03 16:48:48 +08:00
t -> sched_info . max_run_delay = delta ;
2026-01-19 10:02:41 +08:00
ktime_get_real_ts64 ( & t -> sched_info . max_run_delay_ts );
}
2024-12-20 17:31:05 +08:00
if ( delta && ( ! t -> sched_info . min_run_delay || delta < t -> sched_info . min_run_delay ))
t -> sched_info . min_run_delay = delta ;
2021-05-04 22:43:45 +02:00
rq_sched_info_dequeue ( rq , delta );
2007-07-09 18:51:58 +02:00
}
/*
2018-03-03 14:01:12 +01:00
* Called when a task finally hits the CPU. We can now calculate how
2007-07-09 18:51:58 +02:00
* long it was waiting to run. We also note when it began so that we
2024-05-27 16:54:52 +02:00
* can keep stats on how long its time-slice is.
2007-07-09 18:51:58 +02:00
*/
2013-09-22 17:20:54 +03:00
static void sched_info_arrive ( struct rq * rq , struct task_struct * t )
2007-07-09 18:51:58 +02:00
{
2021-05-12 13:32:37 +02:00
unsigned long long now , delta = 0 ;
2007-07-09 18:51:58 +02:00
2021-05-12 13:32:37 +02:00
if ( ! t -> sched_info . last_queued )
return ;
now = rq_clock ( rq );
delta = now - t -> sched_info . last_queued ;
t -> sched_info . last_queued = 0 ;
2007-07-09 18:51:58 +02:00
t -> sched_info . run_delay += delta ;
t -> sched_info . last_arrival = now ;
2007-10-15 17:00:12 +02:00
t -> sched_info . pcount ++ ;
2026-01-19 10:02:41 +08:00
if ( delta > t -> sched_info . max_run_delay ) {
2024-12-03 16:48:48 +08:00
t -> sched_info . max_run_delay = delta ;
2026-01-19 10:02:41 +08:00
ktime_get_real_ts64 ( & t -> sched_info . max_run_delay_ts );
}
2024-12-20 17:31:05 +08:00
if ( delta && ( ! t -> sched_info . min_run_delay || delta < t -> sched_info . min_run_delay ))
t -> sched_info . min_run_delay = delta ;
2007-07-09 18:51:58 +02:00
2013-09-22 17:20:54 +03:00
rq_sched_info_arrive ( rq , delta );
2007-07-09 18:51:58 +02:00
}
/*
* This function is only called from enqueue_task(), but also only updates
* the timestamp if it is already not set. It's assumed that
2021-05-04 22:43:45 +02:00
* sched_info_dequeue() will clear that stamp when appropriate.
2007-07-09 18:51:58 +02:00
*/
2021-05-04 22:43:45 +02:00
static inline void sched_info_enqueue ( struct rq * rq , struct task_struct * t )
2007-07-09 18:51:58 +02:00
{
2021-05-04 22:43:42 +02:00
if ( ! t -> sched_info . last_queued )
t -> sched_info . last_queued = rq_clock ( rq );
2007-07-09 18:51:58 +02:00
}
/*
2013-09-16 11:30:36 +03:00
* Called when a process ceases being the active-running process involuntarily
* due, typically, to expiring its time slice (this may also be called when
* switching to the idle task). Now we can calculate how long we ran.
2008-06-16 15:11:01 +05:30
* Also, if the process is still in the TASK_RUNNING state, call
2021-05-04 22:43:45 +02:00
* sched_info_enqueue() to mark that it has now again started waiting on
2008-06-16 15:11:01 +05:30
* the runqueue.
2007-07-09 18:51:58 +02:00
*/
2013-09-22 17:20:54 +03:00
static inline void sched_info_depart ( struct rq * rq , struct task_struct * t )
2007-07-09 18:51:58 +02:00
{
2018-03-03 14:01:12 +01:00
unsigned long long delta = rq_clock ( rq ) - t -> sched_info . last_arrival ;
2007-07-09 18:51:58 +02:00
2013-09-22 17:20:54 +03:00
rq_sched_info_depart ( rq , delta );
2008-06-16 15:11:01 +05:30
2021-06-11 10:28:12 +02:00
if ( task_is_running ( t ))
2021-05-04 22:43:45 +02:00
sched_info_enqueue ( rq , t );
2007-07-09 18:51:58 +02:00
}
/*
* Called when tasks are switched involuntarily due, typically, to expiring
* their time slice. (This may also be called when switching to or from
* the idle task.) We are only called when prev != next.
*/
static inline void
2021-05-04 22:43:42 +02:00
sched_info_switch ( struct rq * rq , struct task_struct * prev , struct task_struct * next )
2007-07-09 18:51:58 +02:00
{
/*
2018-03-03 14:01:12 +01:00
* prev now departs the CPU. It's not interesting to record
2007-07-09 18:51:58 +02:00
* stats about how efficient we were at scheduling the idle
* process, however.
*/
if ( prev != rq -> idle )
2013-09-22 17:20:54 +03:00
sched_info_depart ( rq , prev );
2007-07-09 18:51:58 +02:00
if ( next != rq -> idle )
2013-09-22 17:20:54 +03:00
sched_info_arrive ( rq , next );
2007-07-09 18:51:58 +02:00
}
2018-03-03 14:01:12 +01:00
#else /* !CONFIG_SCHED_INFO: */
2021-05-04 22:43:45 +02:00
# define sched_info_enqueue(rq, t) do { } while (0)
# define sched_info_dequeue(rq, t) do { } while (0)
2018-03-03 14:01:12 +01:00
# define sched_info_switch(rq, t, next) do { } while (0)
2025-05-28 10:08:57 +02:00
#endif /* !CONFIG_SCHED_INFO */
2021-11-20 10:39:20 +01:00
#endif /* _KERNEL_STATS_H */