Skip to content

Commit 17a91d5

Browse files
author
Fox Snowpatch
committed
1 parent a2f7734 commit 17a91d5

20 files changed

Lines changed: 481 additions & 353 deletions

File tree

arch/powerpc/kernel/time.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,47 @@ void vtime_task_switch(struct task_struct *prev)
376376
acct->starttime = acct0->starttime;
377377
}
378378
}
379+
380+
#ifdef CONFIG_NO_HZ_COMMON
381+
/**
382+
* vtime_reset - Fast forward vtime entry clocks
383+
*
384+
* Called from dynticks idle IRQ entry to fast-forward the clocks to current time
385+
* so that the IRQ time is still accounted by vtime while nohz cputime is paused.
386+
*/
387+
void vtime_reset(void)
388+
{
389+
struct cpu_accounting_data *acct = get_accounting(current);
390+
391+
acct->starttime = mftb();
392+
#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
393+
acct->startspurr = read_spurr(acct->starttime);
394+
#endif
395+
}
396+
397+
/**
398+
* vtime_dyntick_start - Inform vtime about entry to idle-dynticks
399+
*
400+
* Called when idle enters in dyntick mode. The idle cputime that elapsed so far
401+
* is accumulated and the tick subsystem takes over the idle cputime accounting.
402+
*/
403+
void vtime_dyntick_start(void)
404+
{
405+
vtime_account_idle(current);
406+
}
407+
408+
/**
409+
* vtime_dyntick_stop - Inform vtime about exit from idle-dynticks
410+
*
411+
* Called when idle exits from dyntick mode. The vtime entry clocks are
412+
* fast-forward to current time so that idle accounting restarts elapsing from
413+
* now.
414+
*/
415+
void vtime_dyntick_stop(void)
416+
{
417+
vtime_reset();
418+
}
419+
#endif /* CONFIG_NO_HZ_COMMON */
379420
#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
380421

381422
void __no_kcsan __delay(unsigned long loops)

arch/s390/include/asm/idle.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
#ifndef _S390_IDLE_H
99
#define _S390_IDLE_H
1010

11+
#include <linux/percpu-defs.h>
1112
#include <linux/types.h>
1213
#include <linux/device.h>
1314

1415
struct s390_idle_data {
16+
bool idle_dyntick;
1517
unsigned long idle_count;
1618
unsigned long idle_time;
1719
unsigned long clock_idle_enter;

arch/s390/kernel/idle.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ void account_idle_time_irq(void)
3131
/* Account time spent with enabled wait psw loaded as idle time. */
3232
__atomic64_add(idle_time, &idle->idle_time);
3333
__atomic64_add_const(1, &idle->idle_count);
34-
account_idle_time(cputime_to_nsecs(idle_time));
34+
35+
/* Dyntick idle time accounted by nohz/scheduler */
36+
if (!idle->idle_dyntick)
37+
account_idle_time(cputime_to_nsecs(idle_time));
3538
}
3639

3740
void noinstr arch_cpu_idle(void)

arch/s390/kernel/vtime.c

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <asm/vtimer.h>
1818
#include <asm/vtime.h>
1919
#include <asm/cpu_mf.h>
20+
#include <asm/idle.h>
2021
#include <asm/smp.h>
2122

2223
#include "entry.h"
@@ -110,6 +111,16 @@ static void account_system_index_scaled(struct task_struct *p, u64 cputime,
110111
account_system_index_time(p, cputime_to_nsecs(cputime), index);
111112
}
112113

114+
static inline void vtime_reset_last_update(struct lowcore *lc)
115+
{
116+
asm volatile(
117+
" stpt %0\n" /* Store current cpu timer value */
118+
" stckf %1" /* Store current tod clock value */
119+
: "=Q" (lc->last_update_timer),
120+
"=Q" (lc->last_update_clock)
121+
: : "cc");
122+
}
123+
113124
/*
114125
* Update process times based on virtual cpu times stored by entry.S
115126
* to the lowcore fields user_timer, system_timer & steal_clock.
@@ -121,12 +132,9 @@ static int do_account_vtime(struct task_struct *tsk)
121132

122133
timer = lc->last_update_timer;
123134
clock = lc->last_update_clock;
124-
asm volatile(
125-
" stpt %0\n" /* Store current cpu timer value */
126-
" stckf %1" /* Store current tod clock value */
127-
: "=Q" (lc->last_update_timer),
128-
"=Q" (lc->last_update_clock)
129-
: : "cc");
135+
136+
vtime_reset_last_update(lc);
137+
130138
clock = lc->last_update_clock - clock;
131139
timer -= lc->last_update_timer;
132140

@@ -239,6 +247,43 @@ void vtime_account_hardirq(struct task_struct *tsk)
239247
get_lowcore()->hardirq_timer += vtime_delta();
240248
}
241249

250+
#ifdef CONFIG_NO_HZ_COMMON
251+
/**
252+
* vtime_reset - Fast forward vtime entry clocks
253+
*
254+
* Called from dynticks idle IRQ entry to fast-forward the clocks to current time
255+
* so that the IRQ time is still accounted by vtime while nohz cputime is paused.
256+
*/
257+
void vtime_reset(void)
258+
{
259+
vtime_reset_last_update(get_lowcore());
260+
}
261+
262+
/**
263+
* vtime_dyntick_start - Inform vtime about entry to idle-dynticks
264+
*
265+
* Called when idle enters in dyntick mode. The idle cputime that elapsed so far
266+
* is flushed and the tick subsystem takes over the idle cputime accounting.
267+
*/
268+
void vtime_dyntick_start(void)
269+
{
270+
__this_cpu_write(s390_idle.idle_dyntick, true);
271+
vtime_flush(current);
272+
}
273+
274+
/**
275+
* vtime_dyntick_stop - Inform vtime about exit from idle-dynticks
276+
*
277+
* Called when idle exits from dyntick mode. The vtime entry clocks are
278+
* fast-forward to current time and idle accounting resumes.
279+
*/
280+
void vtime_dyntick_stop(void)
281+
{
282+
vtime_reset_last_update(get_lowcore());
283+
__this_cpu_write(s390_idle.idle_dyntick, false);
284+
}
285+
#endif /* CONFIG_NO_HZ_COMMON */
286+
242287
/*
243288
* Sorted add to a list. List is linear searched until first bigger
244289
* element is found.

drivers/cpufreq/cpufreq.c

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -130,38 +130,11 @@ struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy)
130130
}
131131
EXPORT_SYMBOL_GPL(get_governor_parent_kobj);
132132

133-
static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)
134-
{
135-
struct kernel_cpustat kcpustat;
136-
u64 cur_wall_time;
137-
u64 idle_time;
138-
u64 busy_time;
139-
140-
cur_wall_time = jiffies64_to_nsecs(get_jiffies_64());
141-
142-
kcpustat_cpu_fetch(&kcpustat, cpu);
143-
144-
busy_time = kcpustat.cpustat[CPUTIME_USER];
145-
busy_time += kcpustat.cpustat[CPUTIME_SYSTEM];
146-
busy_time += kcpustat.cpustat[CPUTIME_IRQ];
147-
busy_time += kcpustat.cpustat[CPUTIME_SOFTIRQ];
148-
busy_time += kcpustat.cpustat[CPUTIME_STEAL];
149-
busy_time += kcpustat.cpustat[CPUTIME_NICE];
150-
151-
idle_time = cur_wall_time - busy_time;
152-
if (wall)
153-
*wall = div_u64(cur_wall_time, NSEC_PER_USEC);
154-
155-
return div_u64(idle_time, NSEC_PER_USEC);
156-
}
157-
158133
u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy)
159134
{
160135
u64 idle_time = get_cpu_idle_time_us(cpu, io_busy ? wall : NULL);
161136

162-
if (idle_time == -1ULL)
163-
return get_cpu_idle_time_jiffy(cpu, wall);
164-
else if (!io_busy)
137+
if (!io_busy)
165138
idle_time += get_cpu_iowait_time_us(cpu, wall);
166139

167140
return idle_time;

drivers/cpufreq/cpufreq_governor.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ void gov_update_cpu_data(struct dbs_data *dbs_data)
105105
j_cdbs->prev_cpu_idle = get_cpu_idle_time(j, &j_cdbs->prev_update_time,
106106
dbs_data->io_is_busy);
107107
if (dbs_data->ignore_nice_load)
108-
j_cdbs->prev_cpu_nice = kcpustat_field(&kcpustat_cpu(j), CPUTIME_NICE, j);
108+
j_cdbs->prev_cpu_nice = kcpustat_field(CPUTIME_NICE, j);
109109
}
110110
}
111111
}
@@ -165,7 +165,7 @@ unsigned int dbs_update(struct cpufreq_policy *policy)
165165
j_cdbs->prev_cpu_idle = cur_idle_time;
166166

167167
if (ignore_nice) {
168-
u64 cur_nice = kcpustat_field(&kcpustat_cpu(j), CPUTIME_NICE, j);
168+
u64 cur_nice = kcpustat_field(CPUTIME_NICE, j);
169169

170170
idle_time += div_u64(cur_nice - j_cdbs->prev_cpu_nice, NSEC_PER_USEC);
171171
j_cdbs->prev_cpu_nice = cur_nice;
@@ -539,7 +539,7 @@ int cpufreq_dbs_governor_start(struct cpufreq_policy *policy)
539539
j_cdbs->prev_load = 0;
540540

541541
if (ignore_nice)
542-
j_cdbs->prev_cpu_nice = kcpustat_field(&kcpustat_cpu(j), CPUTIME_NICE, j);
542+
j_cdbs->prev_cpu_nice = kcpustat_field(CPUTIME_NICE, j);
543543
}
544544

545545
gov->start(policy);

drivers/macintosh/rack-meter.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ static inline u64 get_cpu_idle_time(unsigned int cpu)
8787
kcpustat->cpustat[CPUTIME_IOWAIT];
8888

8989
if (rackmeter_ignore_nice)
90-
retval += kcpustat_field(kcpustat, CPUTIME_NICE, cpu);
90+
retval += kcpustat_field(CPUTIME_NICE, cpu);
9191

9292
return retval;
9393
}

fs/proc/stat.c

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,38 +22,6 @@
2222
#define arch_irq_stat() 0
2323
#endif
2424

25-
u64 get_idle_time(struct kernel_cpustat *kcs, int cpu)
26-
{
27-
u64 idle, idle_usecs = -1ULL;
28-
29-
if (cpu_online(cpu))
30-
idle_usecs = get_cpu_idle_time_us(cpu, NULL);
31-
32-
if (idle_usecs == -1ULL)
33-
/* !NO_HZ or cpu offline so we can rely on cpustat.idle */
34-
idle = kcs->cpustat[CPUTIME_IDLE];
35-
else
36-
idle = idle_usecs * NSEC_PER_USEC;
37-
38-
return idle;
39-
}
40-
41-
static u64 get_iowait_time(struct kernel_cpustat *kcs, int cpu)
42-
{
43-
u64 iowait, iowait_usecs = -1ULL;
44-
45-
if (cpu_online(cpu))
46-
iowait_usecs = get_cpu_iowait_time_us(cpu, NULL);
47-
48-
if (iowait_usecs == -1ULL)
49-
/* !NO_HZ or cpu offline so we can rely on cpustat.iowait */
50-
iowait = kcs->cpustat[CPUTIME_IOWAIT];
51-
else
52-
iowait = iowait_usecs * NSEC_PER_USEC;
53-
54-
return iowait;
55-
}
56-
5725
static void show_irq_gap(struct seq_file *p, unsigned int gap)
5826
{
5927
static const char zeros[] = " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
@@ -105,8 +73,8 @@ static int show_stat(struct seq_file *p, void *v)
10573
user += cpustat[CPUTIME_USER];
10674
nice += cpustat[CPUTIME_NICE];
10775
system += cpustat[CPUTIME_SYSTEM];
108-
idle += get_idle_time(&kcpustat, i);
109-
iowait += get_iowait_time(&kcpustat, i);
76+
idle += cpustat[CPUTIME_IDLE];
77+
iowait += cpustat[CPUTIME_IOWAIT];
11078
irq += cpustat[CPUTIME_IRQ];
11179
softirq += cpustat[CPUTIME_SOFTIRQ];
11280
steal += cpustat[CPUTIME_STEAL];
@@ -146,8 +114,8 @@ static int show_stat(struct seq_file *p, void *v)
146114
user = cpustat[CPUTIME_USER];
147115
nice = cpustat[CPUTIME_NICE];
148116
system = cpustat[CPUTIME_SYSTEM];
149-
idle = get_idle_time(&kcpustat, i);
150-
iowait = get_iowait_time(&kcpustat, i);
117+
idle = cpustat[CPUTIME_IDLE];
118+
iowait = cpustat[CPUTIME_IOWAIT];
151119
irq = cpustat[CPUTIME_IRQ];
152120
softirq = cpustat[CPUTIME_SOFTIRQ];
153121
steal = cpustat[CPUTIME_STEAL];

fs/proc/uptime.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,8 @@ static int uptime_proc_show(struct seq_file *m, void *v)
1818
int i;
1919

2020
idle_nsec = 0;
21-
for_each_possible_cpu(i) {
22-
struct kernel_cpustat kcs;
23-
24-
kcpustat_cpu_fetch(&kcs, i);
25-
idle_nsec += get_idle_time(&kcs, i);
26-
}
21+
for_each_possible_cpu(i)
22+
idle_nsec += kcpustat_field(CPUTIME_IDLE, i);
2723

2824
ktime_get_boottime_ts64(&uptime);
2925
timens_add_boottime(&uptime);

0 commit comments

Comments
 (0)