diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-12-18 20:54:09 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-12-18 20:54:09 -0800 |
commit | 796bd6b777e1f721b59411b9842176c62d7f30f7 (patch) | |
tree | 7963ef82373fd56fcad7145f0949e98aa7536825 | |
parent | 48c3c0c752f960363cc5c60488b41c916810c8a6 (diff) | |
download | ltsi-kernel-796bd6b777e1f721b59411b9842176c62d7f30f7.tar.gz |
add power efficient workqueue patches from Linaro
13 files changed, 622 insertions, 31 deletions
diff --git a/patches.renesas/0001-serial-sh-sci-HSCIF-support.patch b/patches.renesas/0001-serial-sh-sci-HSCIF-support.patch index a965f5c7119bf..3e03bd02dea65 100644 --- a/patches.renesas/0001-serial-sh-sci-HSCIF-support.patch +++ b/patches.renesas/0001-serial-sh-sci-HSCIF-support.patch @@ -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 index 0000000000000..a9dc1751a0796 --- /dev/null +++ b/patches.workqueues/0001-workqueues-Introduce-new-flag-WQ_POWER_EFFICIENT-for.patch @@ -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 index 0000000000000..8af7d85373619 --- /dev/null +++ b/patches.workqueues/0002-workqueue-Add-system-wide-power_efficient-workqueues.patch @@ -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 index 0000000000000..0db668bce346f --- /dev/null +++ b/patches.workqueues/0003-PHYLIB-queue-work-on-system_power_efficient_wq.patch @@ -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 index 0000000000000..4fa9c4ea1fb69 --- /dev/null +++ b/patches.workqueues/0004-block-queue-work-on-power-efficient-wq.patch @@ -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 index 0000000000000..17f469e80f7de --- /dev/null +++ b/patches.workqueues/0005-fbcon-queue-work-on-power-efficient-wq.patch @@ -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 index 0000000000000..07e0a7664de53 --- /dev/null +++ b/patches.workqueues/0006-ASoC-pcm-Use-the-power-efficient-workqueue-for-delay.patch @@ -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 index 0000000000000..3774c99d2c60c --- /dev/null +++ b/patches.workqueues/0007-regulator-core-Use-the-power-efficient-workqueue-for.patch @@ -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 index 0000000000000..2b826274ab362 --- /dev/null +++ b/patches.workqueues/0008-ASoC-jack-Use-power-efficient-workqueue.patch @@ -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 index 0000000000000..49b59b6c4d4ca --- /dev/null +++ b/patches.workqueues/0009-extcon-gpio-Use-power-efficient-workqueue-for-deboun.patch @@ -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 index 0000000000000..f2d34b3977813 --- /dev/null +++ b/patches.workqueues/0010-extcon-adc-jack-Use-power-efficient-workqueue.patch @@ -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 index 0000000000000..0d678f6f20062 --- /dev/null +++ b/patches.workqueues/0011-ASoC-compress-Use-power-efficient-workqueue.patch @@ -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 */ @@ -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 |