]> Git Repo - J-linux.git/blobdiff - arch/s390/kernel/idle.c
Merge tag 's390-6.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[J-linux.git] / arch / s390 / kernel / idle.c
index b04fb418307caf178660f543b3b00389eded2126..38e267c7bff7249560c2676cfebba4585c2bee46 100644 (file)
@@ -24,116 +24,61 @@ static DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
 void account_idle_time_irq(void)
 {
        struct s390_idle_data *idle = this_cpu_ptr(&s390_idle);
+       unsigned long idle_time;
        u64 cycles_new[8];
        int i;
 
-       clear_cpu_flag(CIF_ENABLED_WAIT);
        if (smp_cpu_mtid) {
                stcctm(MT_DIAG, smp_cpu_mtid, cycles_new);
                for (i = 0; i < smp_cpu_mtid; i++)
                        this_cpu_add(mt_cycles[i], cycles_new[i] - idle->mt_cycles_enter[i]);
        }
 
-       idle->clock_idle_exit = S390_lowcore.int_clock;
-       idle->timer_idle_exit = S390_lowcore.sys_enter_timer;
+       idle_time = S390_lowcore.int_clock - idle->clock_idle_enter;
 
        S390_lowcore.steal_timer += idle->clock_idle_enter - S390_lowcore.last_update_clock;
-       S390_lowcore.last_update_clock = idle->clock_idle_exit;
+       S390_lowcore.last_update_clock = S390_lowcore.int_clock;
 
        S390_lowcore.system_timer += S390_lowcore.last_update_timer - idle->timer_idle_enter;
-       S390_lowcore.last_update_timer = idle->timer_idle_exit;
+       S390_lowcore.last_update_timer = S390_lowcore.sys_enter_timer;
+
+       /* Account time spent with enabled wait psw loaded as idle time. */
+       WRITE_ONCE(idle->idle_time, READ_ONCE(idle->idle_time) + idle_time);
+       WRITE_ONCE(idle->idle_count, READ_ONCE(idle->idle_count) + 1);
+       account_idle_time(cputime_to_nsecs(idle_time));
 }
 
-void arch_cpu_idle(void)
+void noinstr arch_cpu_idle(void)
 {
        struct s390_idle_data *idle = this_cpu_ptr(&s390_idle);
-       unsigned long idle_time;
        unsigned long psw_mask;
 
        /* Wait for external, I/O or machine check interrupt. */
-       psw_mask = PSW_KERNEL_BITS | PSW_MASK_WAIT | PSW_MASK_DAT |
-               PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
+       psw_mask = PSW_KERNEL_BITS | PSW_MASK_WAIT |
+                  PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
        clear_cpu_flag(CIF_NOHZ_DELAY);
 
        /* psw_idle() returns with interrupts disabled. */
        psw_idle(idle, psw_mask);
-
-       /* Account time spent with enabled wait psw loaded as idle time. */
-       raw_write_seqcount_begin(&idle->seqcount);
-       idle_time = idle->clock_idle_exit - idle->clock_idle_enter;
-       idle->clock_idle_enter = idle->clock_idle_exit = 0ULL;
-       idle->idle_time += idle_time;
-       idle->idle_count++;
-       account_idle_time(cputime_to_nsecs(idle_time));
-       raw_write_seqcount_end(&idle->seqcount);
 }
 
 static ssize_t show_idle_count(struct device *dev,
-                               struct device_attribute *attr, char *buf)
+                              struct device_attribute *attr, char *buf)
 {
        struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id);
-       unsigned long idle_count;
-       unsigned int seq;
-
-       do {
-               seq = read_seqcount_begin(&idle->seqcount);
-               idle_count = READ_ONCE(idle->idle_count);
-               if (READ_ONCE(idle->clock_idle_enter))
-                       idle_count++;
-       } while (read_seqcount_retry(&idle->seqcount, seq));
-       return sprintf(buf, "%lu\n", idle_count);
+
+       return sysfs_emit(buf, "%lu\n", READ_ONCE(idle->idle_count));
 }
 DEVICE_ATTR(idle_count, 0444, show_idle_count, NULL);
 
 static ssize_t show_idle_time(struct device *dev,
-                               struct device_attribute *attr, char *buf)
+                             struct device_attribute *attr, char *buf)
 {
-       unsigned long now, idle_time, idle_enter, idle_exit, in_idle;
        struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id);
-       unsigned int seq;
-
-       do {
-               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));
-       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, "%lu\n", idle_time >> 12);
-}
-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 now, idle_enter, idle_exit, in_idle;
-       unsigned int seq;
-
-       do {
-               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));
-       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);
+       return sysfs_emit(buf, "%lu\n", READ_ONCE(idle->idle_time) >> 12);
 }
+DEVICE_ATTR(idle_time_us, 0444, show_idle_time, NULL);
 
 void arch_cpu_idle_enter(void)
 {
This page took 0.044438 seconds and 4 git commands to generate.