add power efficient workqueue patches from Linaro
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 19 Dec 2013 04:54:09 +0000 (20:54 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 19 Dec 2013 04:54:09 +0000 (20:54 -0800)
13 files changed:
patches.renesas/0001-serial-sh-sci-HSCIF-support.patch
patches.workqueues/0001-workqueues-Introduce-new-flag-WQ_POWER_EFFICIENT-for.patch [new file with mode: 0644]
patches.workqueues/0002-workqueue-Add-system-wide-power_efficient-workqueues.patch [new file with mode: 0644]
patches.workqueues/0003-PHYLIB-queue-work-on-system_power_efficient_wq.patch [new file with mode: 0644]
patches.workqueues/0004-block-queue-work-on-power-efficient-wq.patch [new file with mode: 0644]
patches.workqueues/0005-fbcon-queue-work-on-power-efficient-wq.patch [new file with mode: 0644]
patches.workqueues/0006-ASoC-pcm-Use-the-power-efficient-workqueue-for-delay.patch [new file with mode: 0644]
patches.workqueues/0007-regulator-core-Use-the-power-efficient-workqueue-for.patch [new file with mode: 0644]
patches.workqueues/0008-ASoC-jack-Use-power-efficient-workqueue.patch [new file with mode: 0644]
patches.workqueues/0009-extcon-gpio-Use-power-efficient-workqueue-for-deboun.patch [new file with mode: 0644]
patches.workqueues/0010-extcon-adc-jack-Use-power-efficient-workqueue.patch [new file with mode: 0644]
patches.workqueues/0011-ASoC-compress-Use-power-efficient-workqueue.patch [new file with mode: 0644]
series

index a965f5c7119bfeb82f1514120cf099d00da85d16..3e03bd02dea656bb5d322b883d999aa99c47f86e 100644 (file)
@@ -14,16 +14,14 @@ Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
 (cherry picked from commit f303b364b41d3fc5bf879799128958400b7859aa)
 Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
 ---
- drivers/tty/serial/sh-sci.c      | 102 ++++++++++++++++++++++++++++++++++++---
- include/linux/serial_sci.h       |  12 +++--
- include/uapi/linux/serial_core.h |   3 ++
+ drivers/tty/serial/sh-sci.c      |  102 +++++++++++++++++++++++++++++++++++----
+ include/linux/serial_sci.h       |   12 +++-
+ include/uapi/linux/serial_core.h |    3 +
  3 files changed, 106 insertions(+), 11 deletions(-)
 
-diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
-index 15641861..931d6c3a 100644
 --- a/drivers/tty/serial/sh-sci.c
 +++ b/drivers/tty/serial/sh-sci.c
-@@ -146,6 +146,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+@@ -146,6 +146,7 @@ static struct plat_sci_reg sci_regmap[SC
                [SCRFDR]        = sci_reg_invalid,
                [SCSPTR]        = sci_reg_invalid,
                [SCLSR]         = sci_reg_invalid,
@@ -31,7 +29,7 @@ index 15641861..931d6c3a 100644
        },
  
        /*
-@@ -165,6 +166,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+@@ -165,6 +166,7 @@ static struct plat_sci_reg sci_regmap[SC
                [SCRFDR]        = sci_reg_invalid,
                [SCSPTR]        = sci_reg_invalid,
                [SCLSR]         = sci_reg_invalid,
@@ -39,7 +37,7 @@ index 15641861..931d6c3a 100644
        },
  
        /*
-@@ -183,6 +185,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+@@ -183,6 +185,7 @@ static struct plat_sci_reg sci_regmap[SC
                [SCRFDR]        = sci_reg_invalid,
                [SCSPTR]        = sci_reg_invalid,
                [SCLSR]         = sci_reg_invalid,
@@ -47,7 +45,7 @@ index 15641861..931d6c3a 100644
        },
  
        /*
-@@ -201,6 +204,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+@@ -201,6 +204,7 @@ static struct plat_sci_reg sci_regmap[SC
                [SCRFDR]        = { 0x3c, 16 },
                [SCSPTR]        = sci_reg_invalid,
                [SCLSR]         = sci_reg_invalid,
@@ -55,7 +53,7 @@ index 15641861..931d6c3a 100644
        },
  
        /*
-@@ -220,6 +224,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+@@ -220,6 +224,7 @@ static struct plat_sci_reg sci_regmap[SC
                [SCRFDR]        = sci_reg_invalid,
                [SCSPTR]        = { 0x20, 16 },
                [SCLSR]         = { 0x24, 16 },
@@ -63,7 +61,7 @@ index 15641861..931d6c3a 100644
        },
  
        /*
-@@ -238,6 +243,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+@@ -238,6 +243,7 @@ static struct plat_sci_reg sci_regmap[SC
                [SCRFDR]        = sci_reg_invalid,
                [SCSPTR]        = sci_reg_invalid,
                [SCLSR]         = sci_reg_invalid,
@@ -71,7 +69,7 @@ index 15641861..931d6c3a 100644
        },
  
        /*
-@@ -256,6 +262,26 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+@@ -256,6 +262,26 @@ static struct plat_sci_reg sci_regmap[SC
                [SCRFDR]        = sci_reg_invalid,
                [SCSPTR]        = { 0x20, 16 },
                [SCLSR]         = { 0x24, 16 },
@@ -98,7 +96,7 @@ index 15641861..931d6c3a 100644
        },
  
        /*
-@@ -275,6 +301,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+@@ -275,6 +301,7 @@ static struct plat_sci_reg sci_regmap[SC
                [SCRFDR]        = sci_reg_invalid,
                [SCSPTR]        = sci_reg_invalid,
                [SCLSR]         = { 0x24, 16 },
@@ -106,7 +104,7 @@ index 15641861..931d6c3a 100644
        },
  
        /*
-@@ -294,6 +321,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+@@ -294,6 +321,7 @@ static struct plat_sci_reg sci_regmap[SC
                [SCRFDR]        = { 0x20, 16 },
                [SCSPTR]        = { 0x24, 16 },
                [SCLSR]         = { 0x28, 16 },
@@ -114,7 +112,7 @@ index 15641861..931d6c3a 100644
        },
  
        /*
-@@ -313,6 +341,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+@@ -313,6 +341,7 @@ static struct plat_sci_reg sci_regmap[SC
                [SCRFDR]        = sci_reg_invalid,
                [SCSPTR]        = sci_reg_invalid,
                [SCLSR]         = sci_reg_invalid,
@@ -122,7 +120,7 @@ index 15641861..931d6c3a 100644
        },
  };
  
-@@ -374,6 +403,9 @@ static int sci_probe_regmap(struct plat_sci_port *cfg)
+@@ -374,6 +403,9 @@ static int sci_probe_regmap(struct plat_
                 */
                cfg->regtype = SCIx_SH4_SCIF_REGTYPE;
                break;
@@ -132,7 +130,7 @@ index 15641861..931d6c3a 100644
        default:
                printk(KERN_ERR "Can't probe register map for given port\n");
                return -EINVAL;
-@@ -1798,6 +1830,42 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps,
+@@ -1798,6 +1830,42 @@ static unsigned int sci_scbrr_calc(unsig
        return ((freq + 16 * bps) / (32 * bps) - 1);
  }
  
@@ -175,7 +173,7 @@ index 15641861..931d6c3a 100644
  static void sci_reset(struct uart_port *port)
  {
        struct plat_sci_reg *reg;
-@@ -1821,6 +1889,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
+@@ -1821,6 +1889,7 @@ static void sci_set_termios(struct uart_
        struct plat_sci_reg *reg;
        unsigned int baud, smr_val, max_baud, cks;
        int t = -1;
@@ -183,7 +181,7 @@ index 15641861..931d6c3a 100644
  
        /*
         * earlyprintk comes here early on with port->uartclk set to zero.
-@@ -1833,8 +1902,17 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
+@@ -1833,8 +1902,17 @@ static void sci_set_termios(struct uart_
        max_baud = port->uartclk ? port->uartclk / 16 : 115200;
  
        baud = uart_get_baud_rate(port, termios, old, 0, max_baud);
@@ -203,7 +201,7 @@ index 15641861..931d6c3a 100644
  
        sci_port_enable(s);
  
-@@ -1853,15 +1931,15 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
+@@ -1853,15 +1931,15 @@ static void sci_set_termios(struct uart_
  
        uart_update_timeout(port, termios->c_cflag, baud);
  
@@ -222,7 +220,7 @@ index 15641861..931d6c3a 100644
                udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */
        } else
                serial_port_out(port, SCSMR, smr_val);
-@@ -1947,6 +2025,8 @@ static const char *sci_type(struct uart_port *port)
+@@ -1947,6 +2025,8 @@ static const char *sci_type(struct uart_
                return "scifa";
        case PORT_SCIFB:
                return "scifb";
@@ -231,7 +229,7 @@ index 15641861..931d6c3a 100644
        }
  
        return NULL;
-@@ -1960,7 +2040,10 @@ static inline unsigned long sci_port_size(struct uart_port *port)
+@@ -1960,7 +2040,10 @@ static inline unsigned long sci_port_siz
         * from platform resource data at such a time that ports begin to
         * behave more erratically.
         */
@@ -243,7 +241,7 @@ index 15641861..931d6c3a 100644
  }
  
  static int sci_remap_port(struct uart_port *port)
-@@ -2085,6 +2168,9 @@ static int sci_init_single(struct platform_device *dev,
+@@ -2085,6 +2168,9 @@ static int sci_init_single(struct platfo
        case PORT_SCIFB:
                port->fifosize = 256;
                break;
@@ -253,7 +251,7 @@ index 15641861..931d6c3a 100644
        case PORT_SCIFA:
                port->fifosize = 64;
                break;
-@@ -2325,7 +2411,7 @@ static inline int sci_probe_earlyprintk(struct platform_device *pdev)
+@@ -2325,7 +2411,7 @@ static inline int sci_probe_earlyprintk(
  #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */
  
  static char banner[] __initdata =
@@ -268,8 +266,6 @@ index 15641861..931d6c3a 100644
  MODULE_AUTHOR("Paul Mundt");
 -MODULE_DESCRIPTION("SuperH SCI(F) serial driver");
 +MODULE_DESCRIPTION("SuperH (H)SCI(F) serial driver");
-diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h
-index eb763adf..d3404971 100644
 --- a/include/linux/serial_sci.h
 +++ b/include/linux/serial_sci.h
 @@ -5,7 +5,7 @@
@@ -333,8 +329,6 @@ index eb763adf..d3404971 100644
        upf_t           flags;                  /* UPF_* flags */
        unsigned long   capabilities;           /* Port features/capabilities */
  
-diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
-index 74c2bf72..26eee07e 100644
 --- a/include/uapi/linux/serial_core.h
 +++ b/include/uapi/linux/serial_core.h
 @@ -226,4 +226,7 @@
@@ -345,6 +339,3 @@ index 74c2bf72..26eee07e 100644
 +#define PORT_HSCIF    103
 +
  #endif /* _UAPILINUX_SERIAL_CORE_H */
--- 
-1.8.4.3.gca3854a
-
diff --git a/patches.workqueues/0001-workqueues-Introduce-new-flag-WQ_POWER_EFFICIENT-for.patch b/patches.workqueues/0001-workqueues-Introduce-new-flag-WQ_POWER_EFFICIENT-for.patch
new file mode 100644 (file)
index 0000000..a9dc175
--- /dev/null
@@ -0,0 +1,152 @@
+From 61a10f9763d989e6716fe35030951f2ccfca822a Mon Sep 17 00:00:00 2001
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Mon, 8 Apr 2013 16:45:40 +0530
+Subject: workqueues: Introduce new flag WQ_POWER_EFFICIENT for power oriented
+ workqueues
+
+Workqueues can be performance or power-oriented. Currently, most workqueues are
+bound to the CPU they were created on. This gives good performance (due to cache
+effects) at the cost of potentially waking up otherwise idle cores (Idle from
+scheduler's perspective. Which may or may not be physically idle) just to
+process some work. To save power, we can allow the work to be rescheduled on a
+core that is already awake.
+
+Workqueues created with the WQ_UNBOUND flag will allow some power savings.
+However, we don't change the default behaviour of the system.  To enable
+power-saving behaviour, a new config option CONFIG_WQ_POWER_EFFICIENT needs to
+be turned on. This option can also be overridden by the
+workqueue.power_efficient boot parameter.
+
+tj: Updated config description and comments.  Renamed
+    CONFIG_WQ_POWER_EFFICIENT to CONFIG_WQ_POWER_EFFICIENT_DEFAULT.
+
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Reviewed-by: Amit Kucheria <amit.kucheria@linaro.org>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+(cherry picked from commit cee22a15052faa817e3ec8985a28154d3fabc7aa)
+Signed-off-by: Mark Brown <broonie@linaro.org>
+---
+ Documentation/kernel-parameters.txt |   15 +++++++++++++++
+ include/linux/workqueue.h           |   27 +++++++++++++++++++++++++++
+ kernel/power/Kconfig                |   20 ++++++++++++++++++++
+ kernel/workqueue.c                  |   13 +++++++++++++
+ 4 files changed, 75 insertions(+)
+
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -3341,6 +3341,21 @@ bytes respectively. Such letter suffixes
+                       that this also can be controlled per-workqueue for
+                       workqueues visible under /sys/bus/workqueue/.
++      workqueue.power_efficient
++                      Per-cpu workqueues are generally preferred because
++                      they show better performance thanks to cache
++                      locality; unfortunately, per-cpu workqueues tend to
++                      be more power hungry than unbound workqueues.
++
++                      Enabling this makes the per-cpu workqueues which
++                      were observed to contribute significantly to power
++                      consumption unbound, leading to measurably lower
++                      power usage at the cost of small performance
++                      overhead.
++
++                      The default value of this parameter is determined by
++                      the config option CONFIG_WQ_POWER_EFFICIENT_DEFAULT.
++
+       x2apic_phys     [X86-64,APIC] Use x2apic physical mode instead of
+                       default x2apic cluster mode on platforms
+                       supporting x2apic.
+--- a/include/linux/workqueue.h
++++ b/include/linux/workqueue.h
+@@ -303,6 +303,33 @@ enum {
+       WQ_CPU_INTENSIVE        = 1 << 5, /* cpu instensive workqueue */
+       WQ_SYSFS                = 1 << 6, /* visible in sysfs, see wq_sysfs_register() */
++      /*
++       * Per-cpu workqueues are generally preferred because they tend to
++       * show better performance thanks to cache locality.  Per-cpu
++       * workqueues exclude the scheduler from choosing the CPU to
++       * execute the worker threads, which has an unfortunate side effect
++       * of increasing power consumption.
++       *
++       * The scheduler considers a CPU idle if it doesn't have any task
++       * to execute and tries to keep idle cores idle to conserve power;
++       * however, for example, a per-cpu work item scheduled from an
++       * interrupt handler on an idle CPU will force the scheduler to
++       * excute the work item on that CPU breaking the idleness, which in
++       * turn may lead to more scheduling choices which are sub-optimal
++       * in terms of power consumption.
++       *
++       * Workqueues marked with WQ_POWER_EFFICIENT are per-cpu by default
++       * but become unbound if workqueue.power_efficient kernel param is
++       * specified.  Per-cpu workqueues which are identified to
++       * contribute significantly to power-consumption are identified and
++       * marked with this flag and enabling the power_efficient mode
++       * leads to noticeable power saving at the cost of small
++       * performance disadvantage.
++       *
++       * http://thread.gmane.org/gmane.linux.kernel/1480396
++       */
++      WQ_POWER_EFFICIENT      = 1 << 7,
++
+       __WQ_DRAINING           = 1 << 16, /* internal: workqueue is draining */
+       __WQ_ORDERED            = 1 << 17, /* internal: workqueue is ordered */
+--- a/kernel/power/Kconfig
++++ b/kernel/power/Kconfig
+@@ -263,6 +263,26 @@ config PM_GENERIC_DOMAINS
+       bool
+       depends on PM
++config WQ_POWER_EFFICIENT_DEFAULT
++      bool "Enable workqueue power-efficient mode by default"
++      depends on PM
++      default n
++      help
++        Per-cpu workqueues are generally preferred because they show
++        better performance thanks to cache locality; unfortunately,
++        per-cpu workqueues tend to be more power hungry than unbound
++        workqueues.
++
++        Enabling workqueue.power_efficient kernel parameter makes the
++        per-cpu workqueues which were observed to contribute
++        significantly to power consumption unbound, leading to measurably
++        lower power usage at the cost of small performance overhead.
++
++        This config option determines whether workqueue.power_efficient
++        is enabled by default.
++
++        If in doubt, say N.
++
+ config PM_GENERIC_DOMAINS_SLEEP
+       def_bool y
+       depends on PM_SLEEP && PM_GENERIC_DOMAINS
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -272,6 +272,15 @@ static cpumask_var_t *wq_numa_possible_c
+ static bool wq_disable_numa;
+ module_param_named(disable_numa, wq_disable_numa, bool, 0444);
++/* see the comment above the definition of WQ_POWER_EFFICIENT */
++#ifdef CONFIG_WQ_POWER_EFFICIENT_DEFAULT
++static bool wq_power_efficient = true;
++#else
++static bool wq_power_efficient;
++#endif
++
++module_param_named(power_efficient, wq_power_efficient, bool, 0444);
++
+ static bool wq_numa_enabled;          /* unbound NUMA affinity enabled */
+ /* buf for wq_update_unbound_numa_attrs(), protected by CPU hotplug exclusion */
+@@ -4117,6 +4126,10 @@ struct workqueue_struct *__alloc_workque
+       struct workqueue_struct *wq;
+       struct pool_workqueue *pwq;
++      /* see the comment above the definition of WQ_POWER_EFFICIENT */
++      if ((flags & WQ_POWER_EFFICIENT) && wq_power_efficient)
++              flags |= WQ_UNBOUND;
++
+       /* allocate wq and format name */
+       if (flags & WQ_UNBOUND)
+               tbl_size = wq_numa_tbl_len * sizeof(wq->numa_pwq_tbl[0]);
diff --git a/patches.workqueues/0002-workqueue-Add-system-wide-power_efficient-workqueues.patch b/patches.workqueues/0002-workqueue-Add-system-wide-power_efficient-workqueues.patch
new file mode 100644 (file)
index 0000000..8af7d85
--- /dev/null
@@ -0,0 +1,72 @@
+From 7399c448c57c930a065e0ab77870ab84dc0dbf61 Mon Sep 17 00:00:00 2001
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Wed, 24 Apr 2013 17:12:54 +0530
+Subject: workqueue: Add system wide power_efficient workqueues
+
+This patch adds system wide workqueues aligned towards power saving. This is
+done by allocating them with WQ_UNBOUND flag if 'wq_power_efficient' is set to
+'true'.
+
+tj: updated comments a bit.
+
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+(cherry picked from commit 0668106ca3865ba945e155097fb042bf66d364d3)
+Signed-off-by: Mark Brown <broonie@linaro.org>
+---
+ include/linux/workqueue.h |    8 ++++++++
+ kernel/workqueue.c        |   13 ++++++++++++-
+ 2 files changed, 20 insertions(+), 1 deletion(-)
+
+--- a/include/linux/workqueue.h
++++ b/include/linux/workqueue.h
+@@ -360,11 +360,19 @@ enum {
+  *
+  * system_freezable_wq is equivalent to system_wq except that it's
+  * freezable.
++ *
++ * *_power_efficient_wq are inclined towards saving power and converted
++ * into WQ_UNBOUND variants if 'wq_power_efficient' is enabled; otherwise,
++ * they are same as their non-power-efficient counterparts - e.g.
++ * system_power_efficient_wq is identical to system_wq if
++ * 'wq_power_efficient' is disabled.  See WQ_POWER_EFFICIENT for more info.
+  */
+ extern struct workqueue_struct *system_wq;
+ extern struct workqueue_struct *system_long_wq;
+ extern struct workqueue_struct *system_unbound_wq;
+ extern struct workqueue_struct *system_freezable_wq;
++extern struct workqueue_struct *system_power_efficient_wq;
++extern struct workqueue_struct *system_freezable_power_efficient_wq;
+ static inline struct workqueue_struct * __deprecated __system_nrt_wq(void)
+ {
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -317,6 +317,10 @@ struct workqueue_struct *system_unbound_
+ EXPORT_SYMBOL_GPL(system_unbound_wq);
+ struct workqueue_struct *system_freezable_wq __read_mostly;
+ EXPORT_SYMBOL_GPL(system_freezable_wq);
++struct workqueue_struct *system_power_efficient_wq __read_mostly;
++EXPORT_SYMBOL_GPL(system_power_efficient_wq);
++struct workqueue_struct *system_freezable_power_efficient_wq __read_mostly;
++EXPORT_SYMBOL_GPL(system_freezable_power_efficient_wq);
+ static int worker_thread(void *__worker);
+ static void copy_workqueue_attrs(struct workqueue_attrs *to,
+@@ -5039,8 +5043,15 @@ static int __init init_workqueues(void)
+                                           WQ_UNBOUND_MAX_ACTIVE);
+       system_freezable_wq = alloc_workqueue("events_freezable",
+                                             WQ_FREEZABLE, 0);
++      system_power_efficient_wq = alloc_workqueue("events_power_efficient",
++                                            WQ_POWER_EFFICIENT, 0);
++      system_freezable_power_efficient_wq = alloc_workqueue("events_freezable_power_efficient",
++                                            WQ_FREEZABLE | WQ_POWER_EFFICIENT,
++                                            0);
+       BUG_ON(!system_wq || !system_highpri_wq || !system_long_wq ||
+-             !system_unbound_wq || !system_freezable_wq);
++             !system_unbound_wq || !system_freezable_wq ||
++             !system_power_efficient_wq ||
++             !system_freezable_power_efficient_wq);
+       return 0;
+ }
+ early_initcall(init_workqueues);
diff --git a/patches.workqueues/0003-PHYLIB-queue-work-on-system_power_efficient_wq.patch b/patches.workqueues/0003-PHYLIB-queue-work-on-system_power_efficient_wq.patch
new file mode 100644 (file)
index 0000000..0db668b
--- /dev/null
@@ -0,0 +1,64 @@
+From bbe9f36ad93d3404e4c99509f6d13aed67fce02e Mon Sep 17 00:00:00 2001
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Wed, 24 Apr 2013 17:12:55 +0530
+Subject: PHYLIB: queue work on system_power_efficient_wq
+
+Phylib uses workqueues for multiple purposes. There is no real dependency of
+scheduling these on the cpu which scheduled them.
+
+On a idle system, it is observed that and idle cpu wakes up many times just to
+service this work. It would be better if we can schedule it on a cpu which the
+scheduler believes to be the most appropriate one.
+
+This patch replaces system_wq with system_power_efficient_wq for PHYLIB.
+
+Cc: David S. Miller <davem@davemloft.net>
+Cc: netdev@vger.kernel.org
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Acked-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+(cherry picked from commit bbb47bdeae756f04b896b55b51f230f3eb21f207)
+Signed-off-by: Mark Brown <broonie@linaro.org>
+---
+ drivers/net/phy/phy.c |    9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/phy/phy.c
++++ b/drivers/net/phy/phy.c
+@@ -439,7 +439,7 @@ void phy_start_machine(struct phy_device
+ {
+       phydev->adjust_state = handler;
+-      schedule_delayed_work(&phydev->state_queue, HZ);
++      queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, HZ);
+ }
+ /**
+@@ -500,7 +500,7 @@ static irqreturn_t phy_interrupt(int irq
+       disable_irq_nosync(irq);
+       atomic_inc(&phydev->irq_disable);
+-      schedule_work(&phydev->phy_queue);
++      queue_work(system_power_efficient_wq, &phydev->phy_queue);
+       return IRQ_HANDLED;
+ }
+@@ -655,7 +655,7 @@ static void phy_change(struct work_struc
+       /* reschedule state queue work to run as soon as possible */
+       cancel_delayed_work_sync(&phydev->state_queue);
+-      schedule_delayed_work(&phydev->state_queue, 0);
++      queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, 0);
+       return;
+@@ -918,7 +918,8 @@ void phy_state_machine(struct work_struc
+       if (err < 0)
+               phy_error(phydev);
+-      schedule_delayed_work(&phydev->state_queue, PHY_STATE_TIME * HZ);
++      queue_delayed_work(system_power_efficient_wq, &phydev->state_queue,
++                      PHY_STATE_TIME * HZ);
+ }
+ static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
diff --git a/patches.workqueues/0004-block-queue-work-on-power-efficient-wq.patch b/patches.workqueues/0004-block-queue-work-on-power-efficient-wq.patch
new file mode 100644 (file)
index 0000000..4fa9c4e
--- /dev/null
@@ -0,0 +1,85 @@
+From 4d5c9ea3313e410686855496f556d90e589ed2e2 Mon Sep 17 00:00:00 2001
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Wed, 24 Apr 2013 17:12:56 +0530
+Subject: block: queue work on power efficient wq
+
+Block layer uses workqueues for multiple purposes. There is no real dependency
+of scheduling these on the cpu which scheduled them.
+
+On a idle system, it is observed that and idle cpu wakes up many times just to
+service this work. It would be better if we can schedule it on a cpu which the
+scheduler believes to be the most appropriate one.
+
+This patch replaces normal workqueues with power efficient versions.
+
+Cc: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+(cherry picked from commit 695588f9454bdbc7c1a2fbb8a6bfdcfba6183348)
+Signed-off-by: Mark Brown <broonie@linaro.org>
+---
+ block/blk-core.c |    3 ++-
+ block/blk-ioc.c  |    3 ++-
+ block/genhd.c    |   12 ++++++++----
+ 3 files changed, 12 insertions(+), 6 deletions(-)
+
+--- a/block/blk-core.c
++++ b/block/blk-core.c
+@@ -3191,7 +3191,8 @@ int __init blk_dev_init(void)
+       /* used for unplugging and affects IO latency/throughput - HIGHPRI */
+       kblockd_workqueue = alloc_workqueue("kblockd",
+-                                          WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
++                                          WQ_MEM_RECLAIM | WQ_HIGHPRI |
++                                          WQ_POWER_EFFICIENT, 0);
+       if (!kblockd_workqueue)
+               panic("Failed to create kblockd\n");
+--- a/block/blk-ioc.c
++++ b/block/blk-ioc.c
+@@ -144,7 +144,8 @@ void put_io_context(struct io_context *i
+       if (atomic_long_dec_and_test(&ioc->refcount)) {
+               spin_lock_irqsave(&ioc->lock, flags);
+               if (!hlist_empty(&ioc->icq_list))
+-                      schedule_work(&ioc->release_work);
++                      queue_work(system_power_efficient_wq,
++                                      &ioc->release_work);
+               else
+                       free_ioc = true;
+               spin_unlock_irqrestore(&ioc->lock, flags);
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -1489,9 +1489,11 @@ static void __disk_unblock_events(struct
+       intv = disk_events_poll_jiffies(disk);
+       set_timer_slack(&ev->dwork.timer, intv / 4);
+       if (check_now)
+-              queue_delayed_work(system_freezable_wq, &ev->dwork, 0);
++              queue_delayed_work(system_freezable_power_efficient_wq,
++                              &ev->dwork, 0);
+       else if (intv)
+-              queue_delayed_work(system_freezable_wq, &ev->dwork, intv);
++              queue_delayed_work(system_freezable_power_efficient_wq,
++                              &ev->dwork, intv);
+ out_unlock:
+       spin_unlock_irqrestore(&ev->lock, flags);
+ }
+@@ -1534,7 +1536,8 @@ void disk_flush_events(struct gendisk *d
+       spin_lock_irq(&ev->lock);
+       ev->clearing |= mask;
+       if (!ev->block)
+-              mod_delayed_work(system_freezable_wq, &ev->dwork, 0);
++              mod_delayed_work(system_freezable_power_efficient_wq,
++                              &ev->dwork, 0);
+       spin_unlock_irq(&ev->lock);
+ }
+@@ -1627,7 +1630,8 @@ static void disk_check_events(struct dis
+       intv = disk_events_poll_jiffies(disk);
+       if (!ev->block && intv)
+-              queue_delayed_work(system_freezable_wq, &ev->dwork, intv);
++              queue_delayed_work(system_freezable_power_efficient_wq,
++                              &ev->dwork, intv);
+       spin_unlock_irq(&ev->lock);
diff --git a/patches.workqueues/0005-fbcon-queue-work-on-power-efficient-wq.patch b/patches.workqueues/0005-fbcon-queue-work-on-power-efficient-wq.patch
new file mode 100644 (file)
index 0000000..17f469e
--- /dev/null
@@ -0,0 +1,35 @@
+From 3e9dc2afddfc1d76719f84ab5ea6b37e0fff5c46 Mon Sep 17 00:00:00 2001
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Wed, 24 Apr 2013 17:12:57 +0530
+Subject: fbcon: queue work on power efficient wq
+
+fbcon uses workqueues and it has no real dependency of scheduling these on the
+cpu which scheduled them.
+
+On a idle system, it is observed that and idle cpu wakes up many times just to
+service this work. It would be better if we can schedule it on a cpu which the
+scheduler believes to be the most appropriate one.
+
+This patch replaces system_wq with system_power_efficient_wq.
+
+Cc: Dave Airlie <airlied@redhat.com>
+Cc: linux-fbdev@vger.kernel.org
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+(cherry picked from commit a85f1a41f020bc2c97611060bcfae6f48a1db28d)
+Signed-off-by: Mark Brown <broonie@linaro.org>
+---
+ drivers/video/console/fbcon.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/video/console/fbcon.c
++++ b/drivers/video/console/fbcon.c
+@@ -404,7 +404,7 @@ static void cursor_timer_handler(unsigne
+       struct fb_info *info = (struct fb_info *) dev_addr;
+       struct fbcon_ops *ops = info->fbcon_par;
+-      schedule_work(&info->queue);
++      queue_work(system_power_efficient_wq, &info->queue);
+       mod_timer(&ops->cursor_timer, jiffies + HZ/5);
+ }
diff --git a/patches.workqueues/0006-ASoC-pcm-Use-the-power-efficient-workqueue-for-delay.patch b/patches.workqueues/0006-ASoC-pcm-Use-the-power-efficient-workqueue-for-delay.patch
new file mode 100644 (file)
index 0000000..07e0a76
--- /dev/null
@@ -0,0 +1,30 @@
+From 605791a1741b2a9055e60b9fb59e3d3e679e40d2 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Thu, 18 Jul 2013 11:52:17 +0100
+Subject: ASoC: pcm: Use the power efficient workqueue for delayed powerdown
+
+There is no need to use a normal per-CPU workqueue for delayed power downs
+as they're not timing or performance critical and waking up a core for them
+would defeat some of the point.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
+(cherry picked from commit d4e1a73acd4e894f8332f2093bceaef585cfab67)
+---
+ sound/soc/soc-pcm.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/sound/soc/soc-pcm.c
++++ b/sound/soc/soc-pcm.c
+@@ -408,8 +408,9 @@ static int soc_pcm_close(struct snd_pcm_
+               } else {
+                       /* start delayed pop wq here for playback streams */
+                       rtd->pop_wait = 1;
+-                      schedule_delayed_work(&rtd->delayed_work,
+-                              msecs_to_jiffies(rtd->pmdown_time));
++                      queue_delayed_work(system_power_efficient_wq,
++                                         &rtd->delayed_work,
++                                         msecs_to_jiffies(rtd->pmdown_time));
+               }
+       } else {
+               /* capture streams can be powered down now */
diff --git a/patches.workqueues/0007-regulator-core-Use-the-power-efficient-workqueue-for.patch b/patches.workqueues/0007-regulator-core-Use-the-power-efficient-workqueue-for.patch
new file mode 100644 (file)
index 0000000..3774c99
--- /dev/null
@@ -0,0 +1,32 @@
+From fbcfea7d98897a48ac8cc6b6cf7eb597a6946669 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Thu, 18 Jul 2013 11:52:04 +0100
+Subject: regulator: core: Use the power efficient workqueue for delayed
+ powerdown
+
+There is no need to use a normal per-CPU workqueue for delayed power downs
+as they're not timing or performance critical and waking up a core for them
+would defeat some of the point.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
+Acked-by: Liam Girdwood <liam.r.girdwood@intel.com>
+(cherry picked from commit 070260f07c7daec311f2466eb9d1df475d5a46f8)
+---
+ drivers/regulator/core.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -1890,8 +1890,9 @@ int regulator_disable_deferred(struct re
+       rdev->deferred_disables++;
+       mutex_unlock(&rdev->mutex);
+-      ret = schedule_delayed_work(&rdev->disable_work,
+-                                  msecs_to_jiffies(ms));
++      ret = queue_delayed_work(system_power_efficient_wq,
++                               &rdev->disable_work,
++                               msecs_to_jiffies(ms));
+       if (ret < 0)
+               return ret;
+       else
diff --git a/patches.workqueues/0008-ASoC-jack-Use-power-efficient-workqueue.patch b/patches.workqueues/0008-ASoC-jack-Use-power-efficient-workqueue.patch
new file mode 100644 (file)
index 0000000..2b82627
--- /dev/null
@@ -0,0 +1,27 @@
+From 98fe237d868087d7108fde3da27fcbb531d25ca9 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Thu, 18 Jul 2013 22:47:10 +0100
+Subject: ASoC: jack: Use power efficient workqueue
+
+The accessory detect debounce work is not performance sensitive so let
+the scheduler run it wherever is most efficient rather than in a per CPU
+workqueue by using the system power efficient workqueue.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+(cherry picked from commit e6058aaadcd473e5827720dc143af56aabbeecc7)
+---
+ sound/soc/soc-jack.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/soc/soc-jack.c
++++ b/sound/soc/soc-jack.c
+@@ -263,7 +263,7 @@ static irqreturn_t gpio_handler(int irq,
+       if (device_may_wakeup(dev))
+               pm_wakeup_event(dev, gpio->debounce_time + 50);
+-      schedule_delayed_work(&gpio->work,
++      queue_delayed_work(system_power_efficient_wq, &gpio->work,
+                             msecs_to_jiffies(gpio->debounce_time));
+       return IRQ_HANDLED;
diff --git a/patches.workqueues/0009-extcon-gpio-Use-power-efficient-workqueue-for-deboun.patch b/patches.workqueues/0009-extcon-gpio-Use-power-efficient-workqueue-for-deboun.patch
new file mode 100644 (file)
index 0000000..49b59b6
--- /dev/null
@@ -0,0 +1,29 @@
+From d3a177c71852d2eac42c74a6b2cb7af242061d21 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Fri, 19 Jul 2013 18:47:34 +0100
+Subject: extcon: gpio: Use power efficient workqueue for debounce
+
+The debounce timeout is generally quite long and the work not performance
+critical so allow the scheduler to run the work anywhere rather than in
+the normal per-CPU workqueue.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: Myungjoo Ham <myungjoo.ham@samsung.com>
+(cherry picked from commit d0db2e7ae788d84ff6d0a1cd4dc935282db29073)
+---
+ drivers/extcon/extcon-gpio.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/extcon/extcon-gpio.c
++++ b/drivers/extcon/extcon-gpio.c
+@@ -56,7 +56,7 @@ static irqreturn_t gpio_irq_handler(int
+ {
+       struct gpio_extcon_data *extcon_data = dev_id;
+-      schedule_delayed_work(&extcon_data->work,
++      queue_delayed_work(system_power_efficient_wq, &extcon_data->work,
+                             extcon_data->debounce_jiffies);
+       return IRQ_HANDLED;
+ }
diff --git a/patches.workqueues/0010-extcon-adc-jack-Use-power-efficient-workqueue.patch b/patches.workqueues/0010-extcon-adc-jack-Use-power-efficient-workqueue.patch
new file mode 100644 (file)
index 0000000..f2d34b3
--- /dev/null
@@ -0,0 +1,30 @@
+From df08b04c9a3f2925e34f778bf20d37623635c306 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Fri, 19 Jul 2013 18:47:35 +0100
+Subject: extcon: adc-jack: Use power efficient workqueue
+
+The debounce timeout is generally quite long and the work not performance
+critical so allow the scheduler to run the work anywhere rather than in
+the normal per-CPU workqueue.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
+Signed-off-by: Myungjoo Ham <myungjoo.ham@samsung.com>
+(cherry picked from commit 1a82e81e0ede6955684397ffbc0964191ef13cba)
+---
+ drivers/extcon/extcon-adc-jack.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/extcon/extcon-adc-jack.c
++++ b/drivers/extcon/extcon-adc-jack.c
+@@ -87,7 +87,8 @@ static irqreturn_t adc_jack_irq_thread(i
+ {
+       struct adc_jack_data *data = _data;
+-      schedule_delayed_work(&data->handler, data->handling_delay);
++      queue_delayed_work(system_power_efficient_wq,
++                         &data->handler, data->handling_delay);
+       return IRQ_HANDLED;
+ }
diff --git a/patches.workqueues/0011-ASoC-compress-Use-power-efficient-workqueue.patch b/patches.workqueues/0011-ASoC-compress-Use-power-efficient-workqueue.patch
new file mode 100644 (file)
index 0000000..0d678f6
--- /dev/null
@@ -0,0 +1,29 @@
+From 03bc67f592760de5b16a48cb07ca02ecedf5fa11 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Fri, 9 Aug 2013 18:12:29 +0100
+Subject: ASoC: compress: Use power efficient workqueue
+
+There is no need for the power down work to be done on a per CPU workqueue
+especially considering the fairly long delay before powerdown.
+
+Signed-off-by: Mark Brown <broonie@linaro.org>
+Acked-by: Vinod Koul <vinod.koul@intel.com>
+(cherry picked from commit 3d24cfe485e2750cc209a77dd62fa1fe004fc6c7)
+---
+ sound/soc/soc-compress.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/sound/soc/soc-compress.c
++++ b/sound/soc/soc-compress.c
+@@ -149,8 +149,9 @@ static int soc_compr_free(struct snd_com
+                                       SND_SOC_DAPM_STREAM_STOP);
+               } else {
+                       rtd->pop_wait = 1;
+-                      schedule_delayed_work(&rtd->delayed_work,
+-                              msecs_to_jiffies(rtd->pmdown_time));
++                      queue_delayed_work(system_power_efficient_wq,
++                                         &rtd->delayed_work,
++                                         msecs_to_jiffies(rtd->pmdown_time));
+               }
+       } else {
+               /* capture streams can be powered down now */
diff --git a/series b/series
index af418c9e61f91d56724e369d7deade33906ee9d6..eab24b7e3f54c0f1cc243b9667a2f2e8625a9c95 100644 (file)
--- a/series
+++ b/series
@@ -29,6 +29,21 @@ patches.ltsi/ltsi-makefile-addition.patch
 patches.lttng/lttng-2.3.4.patch
 
 
+#############################################################################
+# Power efficient workqueues
+#
+patches.workqueues/0001-workqueues-Introduce-new-flag-WQ_POWER_EFFICIENT-for.patch
+patches.workqueues/0002-workqueue-Add-system-wide-power_efficient-workqueues.patch
+patches.workqueues/0003-PHYLIB-queue-work-on-system_power_efficient_wq.patch
+patches.workqueues/0004-block-queue-work-on-power-efficient-wq.patch
+patches.workqueues/0005-fbcon-queue-work-on-power-efficient-wq.patch
+patches.workqueues/0006-ASoC-pcm-Use-the-power-efficient-workqueue-for-delay.patch
+patches.workqueues/0007-regulator-core-Use-the-power-efficient-workqueue-for.patch
+patches.workqueues/0008-ASoC-jack-Use-power-efficient-workqueue.patch
+patches.workqueues/0009-extcon-gpio-Use-power-efficient-workqueue-for-deboun.patch
+patches.workqueues/0010-extcon-adc-jack-Use-power-efficient-workqueue.patch
+patches.workqueues/0011-ASoC-compress-Use-power-efficient-workqueue.patch
+
 
 #############################################################################
 # Renesas SOC patches