Merge tag 'pm+acpi-3.17-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafae...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 15 Aug 2014 00:13:46 +0000 (18:13 -0600)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 15 Aug 2014 00:13:46 +0000 (18:13 -0600)
Pull more ACPI and power management updates from Rafael Wysocki:
 "These are a couple of regression fixes, cpuidle menu governor
  optimizations, fixes for ACPI proccessor and battery drivers,
  hibernation fix to avoid problems related to the e820 memory map,
  fixes for a few cpufreq drivers and a new version of the suspend
  profiling tool analyze_suspend.py.

  Specifics:

   - Fix for an ACPI-based device hotplug regression introduced in 3.14
     that causes a kernel panic to trigger when memory hot-remove is
     attempted with CONFIG_ACPI_HOTPLUG_MEMORY unset from Tang Chen

   - Fix for a cpufreq regression introduced in 3.16 that triggers a
     "sleeping function called from invalid context" bug in
     dev_pm_opp_init_cpufreq_table() from Stephen Boyd

   - ACPI battery driver fix for a warning message added in 3.16 that
     prints silly stuff sometimes from Mariusz Ceier

   - Hibernation fix for safer handling of mismatches in the 820 memory
     map between the configurations during image creation and during the
     subsequent restore from Chun-Yi Lee

   - ACPI processor driver fix to handle CPU hotplug notifications
     correctly during system suspend/resume from Lan Tianyu

   - Series of four cpuidle menu governor cleanups that also should
     speed it up a bit from Mel Gorman

   - Fixes for the speedstep-smi, integrator, cpu0 and arm_big_little
     cpufreq drivers from Hans Wennborg, Himangi Saraogi, Markus
     Pargmann and Uwe Kleine-König

   - Version 3.0 of the analyze_suspend.py suspend profiling tool from
     Todd E Brandt"

* tag 'pm+acpi-3.17-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPI / battery: Fix warning message in acpi_battery_get_state()
  PM / tools: analyze_suspend.py: update to v3.0
  cpufreq: arm_big_little: fix module license spec
  cpufreq: speedstep-smi: fix decimal printf specifiers
  ACPI / hotplug: Check scan handlers in acpi_scan_hot_remove()
  cpufreq: OPP: Avoid sleeping while atomic
  cpufreq: cpu0: Do not print error message when deferring
  cpufreq: integrator: Use set_cpus_allowed_ptr
  PM / hibernate: avoid unsafe pages in e820 reserved regions
  ACPI / processor: Make acpi_cpu_soft_notify() process CPU FROZEN events
  cpuidle: menu: Lookup CPU runqueues less
  cpuidle: menu: Call nr_iowait_cpu less times
  cpuidle: menu: Use ktime_to_us instead of reinventing the wheel
  cpuidle: menu: Use shifts when calculating averages where possible

1  2 
drivers/cpuidle/governors/menu.c
include/linux/sched.h

index ae5a42595e1c620b8a6f1c54e83cc57098219563,27702742b31922e5508ad86347b1884b30d5c281..34db2fb3ef1eb5ef17a2fb47ae5cd820e240c9e5
@@@ -31,7 -31,8 +31,8 @@@
   * The default values do not overflow.
   */
  #define BUCKETS 12
- #define INTERVALS 8
+ #define INTERVAL_SHIFT 3
+ #define INTERVALS (1UL << INTERVAL_SHIFT)
  #define RESOLUTION 1024
  #define DECAY 8
  #define MAX_INTERESTING 50000
@@@ -133,15 -134,12 +134,12 @@@ struct menu_device 
  #define LOAD_INT(x) ((x) >> FSHIFT)
  #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
  
- static int get_loadavg(void)
+ static inline int get_loadavg(unsigned long load)
  {
-       unsigned long this = this_cpu_load();
-       return LOAD_INT(this) * 10 + LOAD_FRAC(this) / 10;
+       return LOAD_INT(load) * 10 + LOAD_FRAC(load) / 10;
  }
  
- static inline int which_bucket(unsigned int duration)
+ static inline int which_bucket(unsigned int duration, unsigned long nr_iowaiters)
  {
        int bucket = 0;
  
         * This allows us to calculate
         * E(duration)|iowait
         */
-       if (nr_iowait_cpu(smp_processor_id()))
+       if (nr_iowaiters)
                bucket = BUCKETS/2;
  
        if (duration < 10)
   * to be, the higher this multiplier, and thus the higher
   * the barrier to go to an expensive C state.
   */
- static inline int performance_multiplier(void)
+ static inline int performance_multiplier(unsigned long nr_iowaiters, unsigned long load)
  {
        int mult = 1;
  
        /* for higher loadavg, we are more reluctant */
  
-       mult += 2 * get_loadavg();
+       mult += 2 * get_loadavg(load);
  
        /* for IO wait tasks (per cpu!) we add 5x each */
-       mult += 10 * nr_iowait_cpu(smp_processor_id());
+       mult += 10 * nr_iowaiters;
  
        return mult;
  }
@@@ -227,7 -225,10 +225,10 @@@ again
                                max = value;
                }
        }
-       do_div(avg, divisor);
+       if (divisor == INTERVALS)
+               avg >>= INTERVAL_SHIFT;
+       else
+               do_div(avg, divisor);
  
        /* Then try to determine standard deviation */
        stddev = 0;
                        stddev += diff * diff;
                }
        }
-       do_div(stddev, divisor);
+       if (divisor == INTERVALS)
+               stddev >>= INTERVAL_SHIFT;
+       else
+               do_div(stddev, divisor);
        /*
         * The typical interval is obtained when standard deviation is small
         * or standard deviation is small compared to the average interval.
@@@ -288,7 -293,7 +293,7 @@@ static int menu_select(struct cpuidle_d
        int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
        int i;
        unsigned int interactivity_req;
-       struct timespec t;
+       unsigned long nr_iowaiters, cpu_load;
  
        if (data->needs_update) {
                menu_update(drv, dev);
                return 0;
  
        /* determine the expected residency time, round up */
-       t = ktime_to_timespec(tick_nohz_get_sleep_length());
-       data->next_timer_us =
-               t.tv_sec * USEC_PER_SEC + t.tv_nsec / NSEC_PER_USEC;
+       data->next_timer_us = ktime_to_us(tick_nohz_get_sleep_length());
  
-       data->bucket = which_bucket(data->next_timer_us);
+       get_iowait_load(&nr_iowaiters, &cpu_load);
+       data->bucket = which_bucket(data->next_timer_us, nr_iowaiters);
  
        /*
         * Force the result of multiplication to be 64 bits even if both
         * duration / latency ratio. Adjust the latency limit if
         * necessary.
         */
-       interactivity_req = data->predicted_us / performance_multiplier();
+       interactivity_req = data->predicted_us / performance_multiplier(nr_iowaiters, cpu_load);
        if (latency_req > interactivity_req)
                latency_req = interactivity_req;
  
@@@ -398,7 -401,7 +401,7 @@@ static void menu_update(struct cpuidle_
         *
         * Any measured amount of time will include the exit latency.
         * Since we are interested in when the wakeup begun, not when it
 -       * was completed, we must substract the exit latency. However, if
 +       * was completed, we must subtract the exit latency. However, if
         * the measured amount of time is less than the exit latency,
         * assume the state was never reached and the exit latency is 0.
         */
diff --combined include/linux/sched.h
index 857ba40426babdba40b2d81717722fea73c1acad,84729f7c472cd15136fa5f34a013104c34820a27..5c2c885ee52b3996a2665dc3d8c0e21ff9245aaf
@@@ -33,7 -33,6 +33,7 @@@ struct sched_param 
  
  #include <linux/smp.h>
  #include <linux/sem.h>
 +#include <linux/shm.h>
  #include <linux/signal.h>
  #include <linux/compiler.h>
  #include <linux/completion.h>
@@@ -169,8 -168,7 +169,7 @@@ extern int nr_processes(void)
  extern unsigned long nr_running(void);
  extern unsigned long nr_iowait(void);
  extern unsigned long nr_iowait_cpu(int cpu);
- extern unsigned long this_cpu_load(void);
+ extern void get_iowait_load(unsigned long *nr_waiters, unsigned long *load);
  
  extern void calc_global_load(unsigned long ticks);
  extern void update_cpu_load_nohz(void);
@@@ -1386,7 -1384,6 +1385,7 @@@ struct task_struct 
  #ifdef CONFIG_SYSVIPC
  /* ipc stuff */
        struct sysv_sem sysvsem;
 +      struct sysv_shm sysvshm;
  #endif
  #ifdef CONFIG_DETECT_HUNG_TASK
  /* hung task detection */
        unsigned long trace_recursion;
  #endif /* CONFIG_TRACING */
  #ifdef CONFIG_MEMCG /* memcg uses this to do batch job */
 -      struct memcg_batch_info {
 -              int do_batch;   /* incremented when batch uncharge started */
 -              struct mem_cgroup *memcg; /* target memcg of uncharge */
 -              unsigned long nr_pages; /* uncharged usage */
 -              unsigned long memsw_nr_pages; /* uncharged mem+swap usage */
 -      } memcg_batch;
        unsigned int memcg_kmem_skip_account;
        struct memcg_oom_info {
                struct mem_cgroup *memcg;
@@@ -2360,10 -2363,8 +2359,10 @@@ static inline int on_sig_stack(unsigne
  
  static inline int sas_ss_flags(unsigned long sp)
  {
 -      return (current->sas_ss_size == 0 ? SS_DISABLE
 -              : on_sig_stack(sp) ? SS_ONSTACK : 0);
 +      if (!current->sas_ss_size)
 +              return SS_DISABLE;
 +
 +      return on_sig_stack(sp) ? SS_ONSTACK : 0;
  }
  
  static inline unsigned long sigsp(unsigned long sp, struct ksignal *ksig)
@@@ -2965,10 -2966,15 +2964,10 @@@ static inline void inc_syscw(struct tas
  
  #ifdef CONFIG_MEMCG
  extern void mm_update_next_owner(struct mm_struct *mm);
 -extern void mm_init_owner(struct mm_struct *mm, struct task_struct *p);
  #else
  static inline void mm_update_next_owner(struct mm_struct *mm)
  {
  }
 -
 -static inline void mm_init_owner(struct mm_struct *mm, struct task_struct *p)
 -{
 -}
  #endif /* CONFIG_MEMCG */
  
  static inline unsigned long task_rlimit(const struct task_struct *tsk,