aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/hardirq.h2
-rw-r--r--include/linux/sched.h13
-rw-r--r--kernel/sched.c49
3 files changed, 63 insertions, 1 deletions
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index 41367c5c3c68..ff43e9268449 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -137,7 +137,7 @@ extern void synchronize_irq(unsigned int irq);
137 137
138struct task_struct; 138struct task_struct;
139 139
140#ifndef CONFIG_VIRT_CPU_ACCOUNTING 140#if !defined(CONFIG_VIRT_CPU_ACCOUNTING) && !defined(CONFIG_IRQ_TIME_ACCOUNTING)
141static inline void account_system_vtime(struct task_struct *tsk) 141static inline void account_system_vtime(struct task_struct *tsk)
142{ 142{
143} 143}
diff --git a/include/linux/sched.h b/include/linux/sched.h
index aca0ce675939..2cca9a92f5e5 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1826,6 +1826,19 @@ extern void sched_clock_idle_sleep_event(void);
1826extern void sched_clock_idle_wakeup_event(u64 delta_ns); 1826extern void sched_clock_idle_wakeup_event(u64 delta_ns);
1827#endif 1827#endif
1828 1828
1829#ifdef CONFIG_IRQ_TIME_ACCOUNTING
1830/*
1831 * An i/f to runtime opt-in for irq time accounting based off of sched_clock.
1832 * The reason for this explicit opt-in is not to have perf penalty with
1833 * slow sched_clocks.
1834 */
1835extern void enable_sched_clock_irqtime(void);
1836extern void disable_sched_clock_irqtime(void);
1837#else
1838static inline void enable_sched_clock_irqtime(void) {}
1839static inline void disable_sched_clock_irqtime(void) {}
1840#endif
1841
1829extern unsigned long long 1842extern unsigned long long
1830task_sched_runtime(struct task_struct *task); 1843task_sched_runtime(struct task_struct *task);
1831extern unsigned long long thread_group_sched_runtime(struct task_struct *task); 1844extern unsigned long long thread_group_sched_runtime(struct task_struct *task);
diff --git a/kernel/sched.c b/kernel/sched.c
index 089be8adb074..9b302e355791 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1908,6 +1908,55 @@ static void deactivate_task(struct rq *rq, struct task_struct *p, int flags)
1908 dec_nr_running(rq); 1908 dec_nr_running(rq);
1909} 1909}
1910 1910
1911#ifdef CONFIG_IRQ_TIME_ACCOUNTING
1912
1913static DEFINE_PER_CPU(u64, cpu_hardirq_time);
1914static DEFINE_PER_CPU(u64, cpu_softirq_time);
1915
1916static DEFINE_PER_CPU(u64, irq_start_time);
1917static int sched_clock_irqtime;
1918
1919void enable_sched_clock_irqtime(void)
1920{
1921 sched_clock_irqtime = 1;
1922}
1923
1924void disable_sched_clock_irqtime(void)
1925{
1926 sched_clock_irqtime = 0;
1927}
1928
1929void account_system_vtime(struct task_struct *curr)
1930{
1931 unsigned long flags;
1932 int cpu;
1933 u64 now, delta;
1934
1935 if (!sched_clock_irqtime)
1936 return;
1937
1938 local_irq_save(flags);
1939
1940 now = sched_clock();
1941 cpu = smp_processor_id();
1942 delta = now - per_cpu(irq_start_time, cpu);
1943 per_cpu(irq_start_time, cpu) = now;
1944 /*
1945 * We do not account for softirq time from ksoftirqd here.
1946 * We want to continue accounting softirq time to ksoftirqd thread
1947 * in that case, so as not to confuse scheduler with a special task
1948 * that do not consume any time, but still wants to run.
1949 */
1950 if (hardirq_count())
1951 per_cpu(cpu_hardirq_time, cpu) += delta;
1952 else if (in_serving_softirq() && !(curr->flags & PF_KSOFTIRQD))
1953 per_cpu(cpu_softirq_time, cpu) += delta;
1954
1955 local_irq_restore(flags);
1956}
1957
1958#endif
1959
1911#include "sched_idletask.c" 1960#include "sched_idletask.c"
1912#include "sched_fair.c" 1961#include "sched_fair.c"
1913#include "sched_rt.c" 1962#include "sched_rt.c"