
From: Xu Kuohai <xukuohai@huawei.com> hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/ICAOAT -------------------------------- Add softirq and hardirq interference track support. Signed-off-by: Xu Kuohai <xukuohai@huawei.com> Signed-off-by: Pu Lehui <pulehui@huawei.com> --- include/linux/cgroup.h | 45 ++++++++++++++++++++++++++++++++++++++++++ kernel/cgroup/ifs.c | 23 +++++++++++++++++++++ kernel/sched/cputime.c | 8 ++++++-- 3 files changed, 74 insertions(+), 2 deletions(-) diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 5ac1b53c25e4..d6f43bca5ecb 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -867,6 +867,10 @@ enum ifs_types { IFS_RUNDELAY, IFS_WAKELAT, IFS_THROTTLE, +#ifdef CONFIG_IRQ_TIME_ACCOUNTING + IFS_SOFTIRQ, + IFS_HARDIRQ, +#endif #ifdef CONFIG_SCHEDSTATS IFS_SLEEP, #endif @@ -971,6 +975,42 @@ static inline void cgroup_ifs_account_throttle(struct cgroup *cgrp, int cpu, cgroup_ifs_account_delta(ifsc, IFS_THROTTLE, delta); } +#ifdef CONFIG_IRQ_TIME_ACCOUNTING +static inline void cgroup_ifs_account_softirq(u64 delta) +{ + struct cgroup_ifs *ifs; + struct cgroup_ifs_cpu *ifsc; + + if (!cgroup_ifs_enabled()) + return; + + ifs = current_ifs(); + if (!ifs) + return; + + ifsc = this_cpu_ptr(ifs->pcpu); + cgroup_ifs_account_delta(ifsc, IFS_SOFTIRQ, delta); +} + +static inline void cgroup_ifs_account_hardirq(u64 delta) +{ + struct cgroup_ifs *ifs; + struct cgroup_ifs_cpu *ifsc; + + if (!cgroup_ifs_enabled()) + return; + + ifs = current_ifs(); + if (!ifs) + return; + + ifsc = this_cpu_ptr(ifs->pcpu); + cgroup_ifs_account_delta(ifsc, IFS_HARDIRQ, delta); +} + +void cgroup_ifs_enable_irq_account(void); +#endif + #ifdef CONFIG_SCHEDSTATS static inline void cgroup_ifs_account_sleep(struct task_struct *task, u64 delta) @@ -998,6 +1038,11 @@ static inline void cgroup_ifs_set_smt(cpumask_t *sibling) {} static inline void cgroup_ifs_account_rundelay(struct task_struct *task, u64 delta) {} static inline void cgroup_ifs_account_wakelat(struct task_struct *task, u64 delta) {} static inline void cgroup_ifs_account_throttle(struct cgroup *cgrp, int cpu, u64 delta) {} +#ifdef CONFIG_IRQ_TIME_ACCOUNTING +static inline void cgroup_ifs_account_softirq(u64 delta) {} +static inline void cgroup_ifs_account_hardirq(u64 delta) {} +static inline void cgroup_ifs_enable_irq_account(void) {} +#endif #ifdef CONFIG_SCHEDSTATS static inline void cgroup_ifs_account_sleep(struct task_struct *task, u64 delta) {} static inline void cgroup_ifs_enable_sleep_account(void) {} diff --git a/kernel/cgroup/ifs.c b/kernel/cgroup/ifs.c index edebb5f00602..7ac051913920 100644 --- a/kernel/cgroup/ifs.c +++ b/kernel/cgroup/ifs.c @@ -36,6 +36,10 @@ static bool ifs_enable; static bool ifs_sleep_enable; #endif +#ifdef CONFIG_IRQ_TIME_ACCOUNTING +static bool ifs_irq_enable; +#endif + static int __init setup_ifs(char *str) { return kstrtobool(str, &ifs_enable) == 0; @@ -168,6 +172,14 @@ static const char *ifs_type_name(int type) case IFS_THROTTLE: name = "throttle"; break; +#ifdef CONFIG_IRQ_TIME_ACCOUNTING + case IFS_SOFTIRQ: + name = "softirq"; + break; + case IFS_HARDIRQ: + name = "hardirq"; + break; +#endif #ifdef CONFIG_SCHEDSTATS case IFS_SLEEP: name = "sleep"; @@ -185,6 +197,10 @@ static bool should_print(int type) #ifdef CONFIG_SCHEDSTATS if (type == IFS_SLEEP) return ifs_sleep_enable; +#endif +#ifdef CONFIG_IRQ_TIME_ACCOUNTING + if (type == IFS_SOFTIRQ || type == IFS_HARDIRQ) + return ifs_irq_enable; #endif return true; } @@ -304,3 +320,10 @@ void cgroup_ifs_enable_sleep_account(void) ifs_sleep_enable = true; } #endif + +#ifdef CONFIG_IRQ_TIME_ACCOUNTING +void cgroup_ifs_enable_irq_account(void) +{ + ifs_irq_enable = true; +} +#endif diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index b453f8a6a7c7..499812509f7d 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c @@ -27,6 +27,7 @@ static int sched_clock_irqtime; void enable_sched_clock_irqtime(void) { sched_clock_irqtime = 1; + cgroup_ifs_enable_irq_account(); } void disable_sched_clock_irqtime(void) @@ -71,10 +72,13 @@ void irqtime_account_irq(struct task_struct *curr, unsigned int offset) * in that case, so as not to confuse scheduler with a special task * that do not consume any time, but still wants to run. */ - if (pc & HARDIRQ_MASK) + if (pc & HARDIRQ_MASK) { irqtime_account_delta(irqtime, delta, CPUTIME_IRQ); - else if ((pc & SOFTIRQ_OFFSET) && curr != this_cpu_ksoftirqd()) + cgroup_ifs_account_hardirq(delta); + } else if ((pc & SOFTIRQ_OFFSET) && curr != this_cpu_ksoftirqd()) { irqtime_account_delta(irqtime, delta, CPUTIME_SOFTIRQ); + cgroup_ifs_account_softirq(delta); + } } static u64 irqtime_tick_accounted(u64 maxtime) -- 2.34.1