diff options
Diffstat (limited to 'arch/s390/kernel/idle.c')
| -rw-r--r-- | arch/s390/kernel/idle.c | 29 | 
1 files changed, 22 insertions, 7 deletions
diff --git a/arch/s390/kernel/idle.c b/arch/s390/kernel/idle.c index b9d8fe45737a..8f8456816d83 100644 --- a/arch/s390/kernel/idle.c +++ b/arch/s390/kernel/idle.c @@ -69,18 +69,26 @@ DEVICE_ATTR(idle_count, 0444, show_idle_count, NULL);  static ssize_t show_idle_time(struct device *dev,  				struct device_attribute *attr, char *buf)  { +	unsigned long long now, idle_time, idle_enter, idle_exit, in_idle;  	struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id); -	unsigned long long now, idle_time, idle_enter, idle_exit;  	unsigned int seq;  	do { -		now = get_tod_clock();  		seq = read_seqcount_begin(&idle->seqcount);  		idle_time = READ_ONCE(idle->idle_time);  		idle_enter = READ_ONCE(idle->clock_idle_enter);  		idle_exit = READ_ONCE(idle->clock_idle_exit);  	} while (read_seqcount_retry(&idle->seqcount, seq)); -	idle_time += idle_enter ? ((idle_exit ? : now) - idle_enter) : 0; +	in_idle = 0; +	now = get_tod_clock(); +	if (idle_enter) { +		if (idle_exit) { +			in_idle = idle_exit - idle_enter; +		} else if (now > idle_enter) { +			in_idle = now - idle_enter; +		} +	} +	idle_time += in_idle;  	return sprintf(buf, "%llu\n", idle_time >> 12);  }  DEVICE_ATTR(idle_time_us, 0444, show_idle_time, NULL); @@ -88,17 +96,24 @@ DEVICE_ATTR(idle_time_us, 0444, show_idle_time, NULL);  u64 arch_cpu_idle_time(int cpu)  {  	struct s390_idle_data *idle = &per_cpu(s390_idle, cpu); -	unsigned long long now, idle_enter, idle_exit; +	unsigned long long now, idle_enter, idle_exit, in_idle;  	unsigned int seq;  	do { -		now = get_tod_clock();  		seq = read_seqcount_begin(&idle->seqcount);  		idle_enter = READ_ONCE(idle->clock_idle_enter);  		idle_exit = READ_ONCE(idle->clock_idle_exit);  	} while (read_seqcount_retry(&idle->seqcount, seq)); - -	return cputime_to_nsecs(idle_enter ? ((idle_exit ?: now) - idle_enter) : 0); +	in_idle = 0; +	now = get_tod_clock(); +	if (idle_enter) { +		if (idle_exit) { +			in_idle = idle_exit - idle_enter; +		} else if (now > idle_enter) { +			in_idle = now - idle_enter; +		} +	} +	return cputime_to_nsecs(in_idle);  }  void arch_cpu_idle_enter(void)  |