Peter/Ingo,
These are minor fixes that I could find for code responsible for creating sched
domains. They are rebased of my earlier fixes:
https://lkml.org/lkml/2013/6/4/253
I couldn't find them in linux-next or tip/master and so giving this link.
Viresh Kumar (3):
sched: don't initialize alloc_state in build_sched_domains
sched: don't sd->child to NULL when it is already NULL
sched: Create for_each_sd_topology()
kernel/sched/core.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
--
1.7.12.rc2.18.g61b472e
Hi Rafael,
Recently Arnd sent few fixes where drivers were using APIs from freq_table.c but
haven't selected CPU_FREQ_TABLE. Based on that, I just crossed checked all the
places where it should be selected and where it shouldn't be. These are fixes
around that.
I have applied these in my cpufreq-kconfig-fixes branch. Will send you a pull
request separately once I get some Acks (will wait for few days).
Viresh Kumar (11):
cpufreq: blackfin: enable driver for CONFIG_BFIN_CPU_FREQ
cpufreq: cris: select CPU_FREQ_TABLE
cpufreq: davinci: select CPU_FREQ_TABLE
cpufreq: exynos: select CPU_FREQ_TABLE
cpufreq: highbank: remove select CPU_FREQ_TABLE
cpufreq: imx: select CPU_FREQ_TABLE
cpufreq: powerpc: CBE_RAS: select CPU_FREQ_TABLE
cpufreq: pxa: select CPU_FREQ_TABLE
cpufreq: S3C2416/S3C64XX: select CPU_FREQ_TABLE
cpufreq: tegra: select CPU_FREQ_TABLE for ARCH_TEGRA
cpufreq: X86_AMD_FREQ_SENSITIVITY: select CPU_FREQ_TABLE
arch/arm/mach-davinci/Kconfig | 1 +
arch/arm/mach-pxa/Kconfig | 3 +++
arch/arm/mach-tegra/Kconfig | 4 +---
arch/cris/Kconfig | 2 ++
drivers/cpufreq/Kconfig.arm | 6 +++++-
drivers/cpufreq/Kconfig.powerpc | 1 +
drivers/cpufreq/Kconfig.x86 | 1 +
drivers/cpufreq/Makefile | 2 +-
8 files changed, 15 insertions(+), 5 deletions(-)
--
1.7.12.rc2.18.g61b472e
== Linus Walleij linusw ==
=== Highlights ===
* Merged the runtime PM pinctrl states device core
container patch into the pinctrl tree. Now discussing
the OMAP "active" state with affected maintainers.
* Olof J pulled all 5 ux500 branches for v3.11
* Iterated the Integrator/AP pull request after it was
discovered that it broke on ATAG build. Mea culpa.
Hopefully the fixed version get pulled.
* Sent a pull request for the Integrator PCI DT patch
series to ARM SoC.
* Sent fixes on top of the U300 Device Tree and
multiplatform branch to address the last review
comments by utilizing regmap/syscon and attempt
to move board power into the regulator driver. If we
can sort this out I can line up a
pull request.
* Merged pinctrl patches for sparser GPIO ranges
i.e. where pinctrl GPIO ranges are not entirely
linear. Christian Ruppert needed this and it enables
us to proceed with the Intel Bay Trail as a pinctrl
driver.
* Reviewed lots of pinctrl code. Qeueued some
pinctrl patches.
* Adviced on how pinctrl works to LKML newbies.
* Involved in some Allwinner reviews.
=== Plans ===
* I have a ux500-defconfig branch, that will be
submitted later, turning on this and some more new
stuff that will hit the v3.11 merge window. Maybe this
need to come after v3.11-rc1.
* Finalize U300 DT+multiplatform patch set and send
a pull request for it.
* Start to delete Integrator board files and convert to
multiplatform once the PCI DT patches land in ARM
SoC.
* Convert Nomadik pinctrl driver to register GPIO ranges
from the gpiochip side.
* Test the PL08x patches on the Ericsson Research
PB11MPCore and submit platform data for using
pl08x DMA on that platform.
=== Issues ===
* Subsystem maintainers in the kernel community are
acting like Judge Dredd on DT review and commit issues,
as noted last week.
* Some impediments from internal turmoil @ST-Ericsson.
Thanks,
Linus Walleij
=== Highlights ===
* Cleaned/fixed up and sent out volatile ranges (v8) patchset to lkml
* Sent re-factored ION patchset to Rebecca, Arnd, Jesse and Serban
* Updated linaro.android kernel to the AOSP 3.10-rc5 base branch
* Discussed Android's adoption of memcg pressure notifications w/ AntonV
and Android devs.
* Thomas merged my current 3.11 queue into -tip
* Worked with Zoran on his mmc wakeup_source patch
* Tried to sort out vfat ioctl issues w/ Android devs, so we can get
something upstream.
* Discussed & reviewed a number of community time/rtc patches on lkml
* Implemented a new alarmtimer test for my timekeeping testsuite
* Worked out some details on LCE Android Graphics Upstreaming session
* More work on Plumbers Android MiniConf (& got another yes from an
Android dev!)
* Reviewed blueprints and sent out weekly status mail
* Attended LSK android patch discussion
* Attended Linaro internal patch review discussion
=== Plans ===
* Try to get Anton's ulmkd updated to use upstreamed memcg mempressure
notifier
* Re-integrate noswap purging into vrange patchset
* Update refactored ion patches to include changes from the AOSP
3.10-rc5 branch
* Sort out the rest of my 3.11 queue and send to Thomas
* Still have to do some blueprint breaking up for Jakub
=== Issues ===
* N/A
Hi,
Linaro kernels include a patch by Tony Lindgren that adds a
printascii() to every printk() call. Currently in
linux-linaro-tracking, that's 892a9def (ARM: Make low-level printk
work). With this patch, every line is printed twice once you've
registered a console driver which is a bit of a pain. Speaking to
him, he acknowledges that this hack is no longer needed since we now
have earlyprintk, so can this patch be removed from linaro kernels?
Cheers,
Javi
PS: Please CC me, I'm not subscribed to the list
The governors are defined as module in the code, but the Kconfig options do not
allow to compile them as module. This is not really a problem but the init
order is: the cpuidle init functions (framework and driver) and then the
governors. That leads to some weirdness in the cpuidle framework because the
function cpuidle_register_device calls cpuidle_enable_device which in turns
fails at the first attempt because no governor is registered. When the
governor is registered, the framework calls cpuidle_enable_device again which
will invoke the __cpuidle_register_device function. Of course, in order to make
this to work, the return code of cpuidle_enable_device is not checked by the
caller in cpuidle_register_device.
Instead of having this cyclic call graph and relying on a positive side effect
of the hackish back and forth call to cpuidle_enable_device, let's fix the
init order for the governor in order to clean up the cpuidle_enable_device
function.
Remove the module init code and replaced it with postcore_initcall, so we have:
* cpuidle framework : core_initcall
* cpuidle governors : postcore_initcall
* cpuidle drivers : device_initcall
Remove exit module code as it is dead code (governors aren't compiled as
module).
Signed-off-by: Daniel Lezcano <daniel.lezcano(a)linaro.org>
---
drivers/cpuidle/governors/ladder.c | 12 +-----------
drivers/cpuidle/governors/menu.c | 12 +-----------
2 files changed, 2 insertions(+), 22 deletions(-)
diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c
index 9b78405..9f08e8c 100644
--- a/drivers/cpuidle/governors/ladder.c
+++ b/drivers/cpuidle/governors/ladder.c
@@ -192,14 +192,4 @@ static int __init init_ladder(void)
return cpuidle_register_governor(&ladder_governor);
}
-/**
- * exit_ladder - exits the governor
- */
-static void __exit exit_ladder(void)
-{
- cpuidle_unregister_governor(&ladder_governor);
-}
-
-MODULE_LICENSE("GPL");
-module_init(init_ladder);
-module_exit(exit_ladder);
+postcore_initcall(init_ladder);
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index fe343a0..743138c 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -540,14 +540,4 @@ static int __init init_menu(void)
return cpuidle_register_governor(&menu_governor);
}
-/**
- * exit_menu - exits the governor
- */
-static void __exit exit_menu(void)
-{
- cpuidle_unregister_governor(&menu_governor);
-}
-
-MODULE_LICENSE("GPL");
-module_init(init_menu);
-module_exit(exit_menu);
+postcore_initcall(init_menu);
--
1.7.9.5
From: "Mathieu J. Poirier" <mathieu.poirier(a)linaro.org>
Will Deacon has a better solution and his patch should
be coming in soon. In the mean time please consider for inclusion.
This is an in-between solution that prevents the EVENTEN bit in
the CNTKCTL register from being mask, resulting in events between
clusters being lost.
Bug: LP1188778
Signed-off-by: Mathieu Poirier <mathieu.poirier(a)linaro.org>
Signed-off-by: Sudeep KarkadaNagesha <Sudeep.KarkadaNagesha(a)arm.com>
---
arch/arm/include/asm/arch_timer.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
index 7c1bfc0..4928cda 100644
--- a/arch/arm/include/asm/arch_timer.h
+++ b/arch/arm/include/asm/arch_timer.h
@@ -105,7 +105,7 @@ static inline void __cpuinit arch_counter_set_user_access(void)
asm volatile("mrc p15, 0, %0, c14, c1, 0" : "=r" (cntkctl));
/* disable user access to everything */
- cntkctl &= ~((3 << 8) | (7 << 0));
+ cntkctl &= ~((3 << 8) | (3 << 0));
asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl));
}
--
1.7.9.5
Dear Members,
I am trying to use systemtap on Pandaboard with Linaro Ubuntu 13.04
version. http://releases.linaro.org/13.04/ubuntu/panda
I have installed systemtap & other dependencies by apt-get. And followed
the instructions below.
https://wiki.linaro.org/Platform/DevPlatform/Tools/Systemtap
Simple script to test systemtap:
stap -k -v -e 'probe vfs.read {printf("read performed\n"); exit()}'
It failed at the step 4(pass) to compile the code.
By default -Werror flag is also enabled by stap. I guess that would be the
cause. Also there are few other errors.
Please find the compilation error message below & let me know how to solve
this.
Thanks in advance.
localhost:~# stap -k -v -e 'probe vfs.read {printf("read performed\n"); exi
Pass 1: parsed user script and 79 library script(s) using
17588virt/12740res/1716shr kb, in 900usr/20sys/912real ms.
Pass 2: analyzed script: 1 probe(s), 1 function(s), 3 embed(s), 0 global(s)
using 188456virt/72220res/2284shr kb, in 9440usr/590sys/10031real ms.
Pass 3: translated to C into "/tmp/staprrXuW5/stap_1871_src.c" using
188456virt/75576res/5640shr kb, in 120usr/20sys/145real ms.
In file included from /usr/share/systemtap/runtime/runtime.h:130:0,
from /tmp/staprrXuW5/stap_1871_src.c:20:
/usr/share/systemtap/runtime/copy.c: In function '_stp_strncpy_from_user':
/usr/share/systemtap/runtime/copy.c:137:3: error: implicit declaration of
function '__strncpy_from_user' [-Werror=implicit-function-declaration]
In file included from /usr/share/systemtap/runtime/stp_utrace.c:32:0,
from /usr/share/systemtap/runtime/task_finder2.c:4,
from /usr/share/systemtap/runtime/task_finder.c:21,
from /usr/share/systemtap/runtime/runtime.h:138,
from /tmp/staprrXuW5/stap_1871_src.c:20:
/usr/share/systemtap/runtime/stp_utrace.h: At top level:
/usr/share/systemtap/runtime/stp_utrace.h:258:14: error: 'struct
linux_binprm' declared inside parameter list [-Werror]
/usr/share/systemtap/runtime/stp_utrace.h:258:14: error: its scope is only
this definition or declaration, which is probably not what you want
[-Werror]
In file included from /usr/share/systemtap/runtime/task_finder2.c:4:0,
from /usr/share/systemtap/runtime/task_finder.c:21,
from /usr/share/systemtap/runtime/runtime.h:138,
from /tmp/staprrXuW5/stap_1871_src.c:20:
/usr/share/systemtap/runtime/stp_utrace.c: In function 'utrace_shutdown':
/usr/share/systemtap/runtime/stp_utrace.c:289:61: error: macro
"hlist_for_each_entry_safe" passed 5 arguments, but takes just 4
/usr/share/systemtap/runtime/stp_utrace.c:289:3: error:
'hlist_for_each_entry_safe' undeclared (first use in this function)
/usr/share/systemtap/runtime/stp_utrace.c:289:3: note: each undeclared
identifier is reported only once for each function it appears in
/usr/share/systemtap/runtime/stp_utrace.c:289:63: error: expected ';'
before '{' token
/usr/share/systemtap/runtime/stp_utrace.c: In function
'__task_utrace_struct':
/usr/share/systemtap/runtime/stp_utrace.c:308:48: error: macro
"hlist_for_each_entry" passed 4 arguments, but takes just 3
/usr/share/systemtap/runtime/stp_utrace.c:308:2: error:
'hlist_for_each_entry' undeclared (first use in this function)
/usr/share/systemtap/runtime/stp_utrace.c:308:50: error: expected ';'
before '{' token
/usr/share/systemtap/runtime/stp_utrace.c:313:1: error: no return statement
in function returning non-void [-Werror=return-type]
In file included from /usr/share/systemtap/runtime/task_finder2.c:13:0,
from /usr/share/systemtap/runtime/task_finder.c:21,
from /usr/share/systemtap/runtime/runtime.h:138,
from /tmp/staprrXuW5/stap_1871_src.c:20:
/usr/share/systemtap/runtime/task_finder_map.c: In function
'__stp_tf_map_get_free_entry':
/usr/share/systemtap/runtime/task_finder_map.c:74:47: error: macro
"hlist_for_each_entry" passed 4 arguments, but takes just 3
/usr/share/systemtap/runtime/task_finder_map.c:74:2: error:
'hlist_for_each_entry' undeclared (first use in this function)
/usr/share/systemtap/runtime/task_finder_map.c:74:49: error: expected ';'
before '{' token
/usr/share/systemtap/runtime/task_finder_map.c: In function
'__stp_tf_get_map_entry':
/usr/share/systemtap/runtime/task_finder_map.c:114:47: error: macro
"hlist_for_each_entry" passed 4 arguments, but takes just 3
/usr/share/systemtap/runtime/task_finder_map.c:114:2: error:
'hlist_for_each_entry' undeclared (first use in this function)
/usr/share/systemtap/runtime/task_finder_map.c:114:49: error: expected ';'
before '{' token
/usr/share/systemtap/runtime/task_finder_map.c: In function
'__stp_tf_add_map':
/usr/share/systemtap/runtime/task_finder_map.c:138:47: error: macro
"hlist_for_each_entry" passed 4 arguments, but takes just 3
/usr/share/systemtap/runtime/task_finder_map.c:138:2: error:
'hlist_for_each_entry' undeclared (first use in this function)
/usr/share/systemtap/runtime/task_finder_map.c:138:49: error: expected ';'
before '{' token
In file included from /usr/share/systemtap/runtime/task_finder.c:21:0,
from /usr/share/systemtap/runtime/runtime.h:138,
from /tmp/staprrXuW5/stap_1871_src.c:20:
/usr/share/systemtap/runtime/task_finder2.c: In function
'stap_register_task_finder_target':
/usr/share/systemtap/runtime/task_finder2.c:152:27: error: assignment from
incompatible pointer type [-Werror]
/usr/share/systemtap/runtime/task_finder2.c: In function
'__stp_get_mm_path':
/usr/share/systemtap/runtime/task_finder2.c:353:24: error: 'VM_EXECUTABLE'
undeclared (first use in this function)
/usr/share/systemtap/runtime/task_finder2.c: At top level:
/usr/share/systemtap/runtime/task_finder2.c:1324:2: error: initialization
from incompatible pointer type [-Werror]
/usr/share/systemtap/runtime/task_finder2.c:1324:2: error: (near
initialization for '__stp_utrace_task_finder_ops.report_exec') [-Werror]
In file included from /usr/share/systemtap/runtime/vma.c:18:0,
from /usr/share/systemtap/runtime/sym.c:16,
from /usr/share/systemtap/runtime/runtime.h:140,
from /tmp/staprrXuW5/stap_1871_src.c:20:
/usr/share/systemtap/runtime/task_finder_vma.c: In function
'stap_destroy_vma_map':
/usr/share/systemtap/runtime/task_finder_vma.c:102:64: error: macro
"hlist_for_each_entry_safe" passed 5 arguments, but takes just 4
/usr/share/systemtap/runtime/task_finder_vma.c:102:11: error:
'hlist_for_each_entry_safe' undeclared (first use in this function)
/usr/share/systemtap/runtime/task_finder_vma.c:102:66: error: expected ';'
before '{' token
/usr/share/systemtap/runtime/task_finder_vma.c: In function
'__stp_tf_get_vma_map_entry_internal':
/usr/share/systemtap/runtime/task_finder_vma.c:131:47: error: macro
"hlist_for_each_entry" passed 4 arguments, but takes just 3
/usr/share/systemtap/runtime/task_finder_vma.c:131:2: error:
'hlist_for_each_entry' undeclared (first use in this function)
/usr/share/systemtap/runtime/task_finder_vma.c:131:49: error: expected ';'
before '{' token
/usr/share/systemtap/runtime/task_finder_vma.c:138:1: error: no return
statement in function returning non-void [-Werror=return-type]
/usr/share/systemtap/runtime/task_finder_vma.c: In function
'__stp_tf_get_vma_map_entry_end_internal':
/usr/share/systemtap/runtime/task_finder_vma.c:152:47: error: macro
"hlist_for_each_entry" passed 4 arguments, but takes just 3
/usr/share/systemtap/runtime/task_finder_vma.c:152:2: error:
'hlist_for_each_entry' undeclared (first use in this function)
/usr/share/systemtap/runtime/task_finder_vma.c:152:49: error: expected ';'
before '{' token
/usr/share/systemtap/runtime/task_finder_vma.c:159:1: error: no return
statement in function returning non-void [-Werror=return-type]
/usr/share/systemtap/runtime/task_finder_vma.c: In function
'stap_find_vma_map_info':
/usr/share/systemtap/runtime/task_finder_vma.c:290:47: error: macro
"hlist_for_each_entry" passed 4 arguments, but takes just 3
/usr/share/systemtap/runtime/task_finder_vma.c:290:2: error:
'hlist_for_each_entry' undeclared (first use in this function)
/usr/share/systemtap/runtime/task_finder_vma.c:290:49: error: expected ';'
before '{' token
/usr/share/systemtap/runtime/task_finder_vma.c: In function
'stap_find_vma_map_info_user':
/usr/share/systemtap/runtime/task_finder_vma.c:334:47: error: macro
"hlist_for_each_entry" passed 4 arguments, but takes just 3
/usr/share/systemtap/runtime/task_finder_vma.c:334:2: error:
'hlist_for_each_entry' undeclared (first use in this function)
/usr/share/systemtap/runtime/task_finder_vma.c:334:49: error: expected ';'
before '{' token
/usr/share/systemtap/runtime/task_finder_vma.c: In function
'stap_drop_vma_maps':
/usr/share/systemtap/runtime/task_finder_vma.c:365:62: error: macro
"hlist_for_each_entry_safe" passed 5 arguments, but takes just 4
/usr/share/systemtap/runtime/task_finder_vma.c:365:9: error:
'hlist_for_each_entry_safe' undeclared (first use in this function)
/usr/share/systemtap/runtime/task_finder_vma.c:365:64: error: expected ';'
before '{' token
cc1: all warnings being treated as errors
make[1]: *** [/tmp/staprrXuW5/stap_1871_src.o] Error 1
make: *** [_module_/tmp/staprrXuW5] Error 2
WARNING: make exited with status: 2
Pass 4: compiled C into "stap_1871.ko" in 22840usr/1690sys/31630real ms.
Pass 4: compilation failed. Try again with another '--vp 0001' option.
Keeping temporary directory "/tmp/staprrXuW5"
root@localhost:~#
Hi all,
I am sure lot of us have this information but just in case someone
missed it, there is a micro conference proposal for Linux Plumbers New
Orleans:
http://wiki.linuxplumbersconf.org/2013:power-efficient_scheduling
If you are interested in it and you could have the opportunity to be
there, please update the wiki page with your name, it is still proposed
not yet accepted.
-- Daniel
This patch series does the following:
1) Factors out possible common code, unifies the clk strutures used
for PLL35xx & PLL36xx and usues clk->base instead of clk->con0
2) Defines a common rate_table which will contain recommended p, m, s and k
values for supported rates that needs to be changed for changing
corresponding PLL's rate
3) Adds set_rate() and round_rate() clk_ops for PLL35xx and PLL36xx
changes since v2:
- Added new patch to reorder the MUX registration for mout_vpllsrc MUX
before the PLL registrations. And to add the alias for the mout_vpllsrc MUX.
- Added a check to confirm parent rate while registrating the PLL
rate tables.
changes since v1:
- removed sorting and bsearch
- modified the definition of struct "samsung_pll_rate_table"
- added generic round_rate()
- rectified the ops assignment for "rate table passed as NULL"
during PLL registration
Is rebased on branch kgene's "for-next"
https://git.kernel.org/cgit/linux/kernel/git/kgene/linux-samsung.git/log/?h…
And tested these patch on chromebook for EPLL settings for Audio on our chrome tree.
Vikas Sajjan (3):
clk: samsung: Add set_rate() clk_ops for PLL36xx
clk: samsung: Add alias for mout_vpllsrc and reorder MUX registration
for it
clk: samsung: Add EPLL and VPLL freq table for exynos5250 SoC
Yadwinder Singh Brar (3):
clk: samsung: Use clk->base instead of directly using clk->con0 for
PLL3xxx
clk: samsung: Add support to register rate_table for PLL3xxx
clk: samsung: Add set_rate() clk_ops for PLL35xx
drivers/clk/samsung/clk-exynos4.c | 10 +-
drivers/clk/samsung/clk-exynos5250.c | 69 +++++++++--
drivers/clk/samsung/clk-pll.c | 226 ++++++++++++++++++++++++++++++----
drivers/clk/samsung/clk-pll.h | 35 +++++-
drivers/clk/samsung/clk.h | 2 +
5 files changed, 300 insertions(+), 42 deletions(-)
--
1.7.9.5
Current cpufreq stats has got three parts: time_in_state, total_trans and
trans_table.
trans_table was present under a separate macro's from others:
CONFIG_CPU_FREQ_STAT_DETAILS
The reason quoted for that was:
- trans_table goes against the traditional /sysfs rule of one value per
interface. It provides a whole bunch of value in a 2 dimensional matrix form.
I don't understand how necessary it is to keep trans_table inside a separate
macro. These are all cpufreq sysfs stats, probably it doesn't matter if its one
dimensional or two.
Lets remove CONFIG_CPU_FREQ_STAT_DETAILS and use CONFIG_CPU_FREQ_STAT only to
make code more cleaner (i.e. remove unnecessary macros).
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
---
Documentation/cpu-freq/cpufreq-stats.txt | 18 ++++--------------
arch/mips/configs/lemote2f_defconfig | 1 -
arch/powerpc/configs/ppc6xx_defconfig | 1 -
arch/sh/configs/sh7785lcr_32bit_defconfig | 1 -
drivers/cpufreq/Kconfig | 9 ---------
drivers/cpufreq/cpufreq_stats.c | 12 ------------
6 files changed, 4 insertions(+), 38 deletions(-)
diff --git a/Documentation/cpu-freq/cpufreq-stats.txt b/Documentation/cpu-freq/cpufreq-stats.txt
index fc64749..838f990 100644
--- a/Documentation/cpu-freq/cpufreq-stats.txt
+++ b/Documentation/cpu-freq/cpufreq-stats.txt
@@ -111,18 +111,8 @@ Config Main Menu
cpufreq-stats.
"CPU frequency translation statistics" (CONFIG_CPU_FREQ_STAT) provides the
-basic statistics which includes time_in_state and total_trans.
-
-"CPU frequency translation statistics details" (CONFIG_CPU_FREQ_STAT_DETAILS)
-provides fine grained cpufreq stats by trans_table. The reason for having a
-separate config option for trans_table is:
-- trans_table goes against the traditional /sysfs rule of one value per
- interface. It provides a whole bunch of value in a 2 dimensional matrix
- form.
-
-Once these two options are enabled and your CPU supports cpufrequency, you
-will be able to see the CPU frequency statistics in /sysfs.
-
-
-
+statistics which includes time_in_state, total_trans and fine grained cpufreq
+stats by trans_table.
+Once this option is enabled and your CPU supports cpufrequency, you will be able
+to see the CPU frequency statistics in /sysfs.
diff --git a/arch/mips/configs/lemote2f_defconfig b/arch/mips/configs/lemote2f_defconfig
index 343bebc..f9229e9 100644
--- a/arch/mips/configs/lemote2f_defconfig
+++ b/arch/mips/configs/lemote2f_defconfig
@@ -41,7 +41,6 @@ CONFIG_PM_RUNTIME=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_DEBUG=y
CONFIG_CPU_FREQ_STAT=m
-CONFIG_CPU_FREQ_STAT_DETAILS=y
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=m
diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig
index be1cb6e..bb7664c 100644
--- a/arch/powerpc/configs/ppc6xx_defconfig
+++ b/arch/powerpc/configs/ppc6xx_defconfig
@@ -58,7 +58,6 @@ CONFIG_GEF_SBC610=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_DEBUG=y
CONFIG_CPU_FREQ_STAT=m
-CONFIG_CPU_FREQ_STAT_DETAILS=y
CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
diff --git a/arch/sh/configs/sh7785lcr_32bit_defconfig b/arch/sh/configs/sh7785lcr_32bit_defconfig
index 9bdcf72..7ce136d 100644
--- a/arch/sh/configs/sh7785lcr_32bit_defconfig
+++ b/arch/sh/configs/sh7785lcr_32bit_defconfig
@@ -25,7 +25,6 @@ CONFIG_SH_SH7785LCR=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_STAT_DETAILS=y
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
CONFIG_SH_CPU_FREQ=y
CONFIG_HEARTBEAT=y
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index 534fcb8..f64ed8a 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -36,15 +36,6 @@ config CPU_FREQ_STAT
If in doubt, say N.
-config CPU_FREQ_STAT_DETAILS
- bool "CPU frequency translation statistics details"
- depends on CPU_FREQ_STAT
- help
- This will show detail CPU frequency translation table in sysfs file
- system.
-
- If in doubt, say N.
-
choice
prompt "Default CPUFreq governor"
default CPU_FREQ_DEFAULT_GOV_USERSPACE if ARM_SA1100_CPUFREQ || ARM_SA1110_CPUFREQ
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index fb65dec..c774005 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -33,9 +33,7 @@ struct cpufreq_stats {
unsigned int last_index;
u64 *time_in_state;
unsigned int *freq_table;
-#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
unsigned int *trans_table;
-#endif
};
static DEFINE_PER_CPU(struct cpufreq_stats *, cpufreq_stats_table);
@@ -86,7 +84,6 @@ static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf)
return len;
}
-#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)
{
ssize_t len = 0;
@@ -131,7 +128,6 @@ static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)
return len;
}
cpufreq_freq_attr_ro(trans_table);
-#endif
cpufreq_freq_attr_ro(total_trans);
cpufreq_freq_attr_ro(time_in_state);
@@ -139,9 +135,7 @@ cpufreq_freq_attr_ro(time_in_state);
static struct attribute *default_attrs[] = {
&total_trans.attr,
&time_in_state.attr,
-#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
&trans_table.attr,
-#endif
NULL
};
static struct attribute_group stats_attr_group = {
@@ -231,9 +225,7 @@ static int cpufreq_stats_create_table(struct cpufreq_policy *policy,
alloc_size = count * sizeof(int) + count * sizeof(u64);
-#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
alloc_size += count * count * sizeof(int);
-#endif
stat->max_state = count;
stat->time_in_state = kzalloc(alloc_size, GFP_KERNEL);
if (!stat->time_in_state) {
@@ -242,9 +234,7 @@ static int cpufreq_stats_create_table(struct cpufreq_policy *policy,
}
stat->freq_table = (unsigned int *)(stat->time_in_state + count);
-#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
stat->trans_table = stat->freq_table + count;
-#endif
j = 0;
for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
unsigned int freq = table[i].frequency;
@@ -333,9 +323,7 @@ static int cpufreq_stat_notifier_trans(struct notifier_block *nb,
spin_lock(&cpufreq_stats_lock);
stat->last_index = new_index;
-#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
stat->trans_table[old_index * stat->max_state + new_index]++;
-#endif
stat->total_trans++;
spin_unlock(&cpufreq_stats_lock);
return 0;
--
1.7.12.rc2.18.g61b472e
This patch set implements out of the box support of perf tools for
persistent events. For this the kernel must provide necessary
information about existing persistent events via sysfs to userland.
Persistent events are provided by the kernel with readonly event
buffers. To allow the independent usage of the event buffers by any
process without limiting other processes, multiple users of a single
event must be handled too.
The basic concept is to use a pmu as an event container for persistent
events. The pmu registers events in sysfs and provides format and
event information for the userland. The persistent event framework
requires to add events to the pmu dynamically.
With the information in sysfs userland knows about how to setup the
perf_event attribute of a persistent event. Since a persistent event
always has the persistent flag set, a way is needed to express this in
sysfs. A new syntax is used for this. With 'attr<num>:<mask>' any bit
in the attribute structure may be set in a similar way as using
'config<num>', but <num> is an index that points to the u64 value to
change within the attribute.
For persistent events the persistent flag (bit 23 of flag field in
struct perf_event_attr) needs to be set which is expressed in sysfs
with "attr5:23". E.g. the mce_record event is described in sysfs as
follows:
/sys/bus/event_source/devices/persistent/events/mce_record:persistent,config=106
/sys/bus/event_source/devices/persistent/format/persistent:attr5:23
Note that perf tools need to support the 'attr<num>' syntax that is
added in a separate patch set. With it we are able to run perf tool
commands to read persistent events, e.g.:
# perf record -e persistent/mce_record/ sleep 10
# perf top -e persistent/mce_record/
In general the new syntax is flexible to describe with sysfs any event
to be setup by perf tools.
First patches contain also fixes and reworks made after reviewing
code. Could be applied separately.
Patches base on Boris' patches which I have rebased to latest
tip/perf/core. All patches can be found here:
git://git.kernel.org/pub/scm/linux/kernel/git/rric/oprofile.git persistent-v2
I wonder if this patch set could be applied to a tip/perf topic
branch? This would avoid reposting already reviewed patches.
Note: The perf tools patch set do not need to be reposted.
-Robert
Changes for V2:
* Merged minor changes into Boris' patches
* Included Boris' patches for review
* Document attr<index> syntax in sysfs ABI
* Adding cpu check to perf_get_persistent_event_fd()
* Rebased to latest tip/perf/core
Borislav Petkov (4):
perf, ring_buffer: Use same prefix
perf: Add persistent events
perf: Add persistent event facilities
MCE: Enable persistent event
Robert Richter (10):
perf, persistent: Rework struct pers_event_desc
perf, persistent: Remove rb_put()
perf, persistent: Introduce get_persistent_event()
perf, persistent: Reworking perf_get_persistent_event_fd()
perf, persistent: Protect event lists with mutex
perf, persistent: Avoid adding identical events
perf, persistent: Implementing a persistent pmu
perf, persistent: Name each persistent event
perf, persistent: Exposing persistent events using sysfs
perf, persistent: Allow multiple users for an event
.../testing/sysfs-bus-event_source-devices-format | 43 ++-
arch/x86/kernel/cpu/mcheck/mce.c | 19 ++
include/linux/perf_event.h | 9 +-
include/uapi/linux/perf_event.h | 3 +-
kernel/events/Makefile | 2 +-
kernel/events/core.c | 56 ++--
kernel/events/internal.h | 3 +
kernel/events/persistent.c | 320 +++++++++++++++++++++
kernel/events/ring_buffer.c | 7 +-
9 files changed, 419 insertions(+), 43 deletions(-)
create mode 100644 kernel/events/persistent.c
--
1.8.1.1
also cc linaro kernel
Hi,
This patch will forward target residency information from the arm_big_little
driver to mcpm.
If multiple powerdown states are used, the vendor specific code will need a way to distinguish the intended c-state information.
I do not have TC2 hardware to verify this. Would someone be able to help
verify this change on TC2?
Thanks!
Sebastian
Sebastian Capella (1):
cpuidle: arm_big_little: route target residency to mcpm
drivers/cpuidle/arm_big_little.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--
1.7.9.5
If CPUs are marked as disabled in the devicetree, make sure they do
not exist in the system CPU information and CPU topology information.
In this case these CPUs will not be able to be added to the system later
using hot-plug. This allows a single chip with many CPUs to be easily
used in a variety of hardware devices where they may have different
actual processing requirements (eg for thermal/cost reasons).
- Change devicetree.c to ignore any cpu nodes marked as disabled,
this effectively limits the number of active cpu cores so no need
for the max_cpus=x in the chosen node.
- Change topology.c to ignore any cpu nodes marked as disabled, this
is where the scheduler would learn about big/LITTLE cores so this
effectively keeps the scheduler in sync.
Signed-off-by: James King <james.king(a)linaro.org>
---
Documentation/devicetree/bindings/arm/cpus.txt | 5 +++++
arch/arm/kernel/devtree.c | 6 ++++++
arch/arm/kernel/topology.c | 4 ++++
3 files changed, 15 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index f32494d..9fbcbc5 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -45,6 +45,10 @@ For the ARM architecture every CPU node must contain the following properties:
"marvell,xsc3"
"marvell,xscale"
+And optionally set the following properties:
+
+- status: can be set to "disabled" to remove that CPU from the system CPU topology
+
Example:
cpus {
@@ -73,5 +77,6 @@ Example:
device_type = "cpu";
compatible = "arm,cortex-a7";
reg = <0x101>;
+ status = "disabled";
};
};
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
index 5af04f6..f4ba8ee 100644
--- a/arch/arm/kernel/devtree.c
+++ b/arch/arm/kernel/devtree.c
@@ -112,6 +112,12 @@ void __init arm_dt_init_cpu_maps(void)
return;
/*
+ * Check if the cpu is marked as "disabled", if so ignore.
+ */
+ if (!of_device_is_available(cpu))
+ continue;
+
+ /*
* Duplicate MPIDRs are a recipe for disaster.
* Scan all initialized entries and check for
* duplicates. If any is found just bail out.
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
index f10316b..90f8fb3 100644
--- a/arch/arm/kernel/topology.c
+++ b/arch/arm/kernel/topology.c
@@ -116,6 +116,10 @@ static void __init parse_dt_topology(void)
if (cpu_eff->compatible == NULL)
continue;
+ /* Check if the cpu is marked as "disabled", if so ignore. */
+ if (!of_device_is_available(cn))
+ continue;
+
rate = of_get_property(cn, "clock-frequency", &len);
if (!rate || len != 4) {
pr_err("%s missing clock-frequency property\n",
--
1.8.1.2
Before the commit d6f346f2d2bf511c2c59176121a6e42ce60173a0, the
ARCH_NEEDS_CPU_IDLE_COUPLED option was wrongly not depending on the CPU_IDLE
and the Kconfig for OMAP / TEGRA was not checking this dependency when setting
the option.
With this patch, the ARCH_NEEDS_CPU_IDLE_COUPLED has been moved under the
CPU_IDLE option. The dependency has been fixed in the relevant arch's Kconfig.
Signed-off-by: Daniel Lezcano <daniel.lezcano(a)linaro.org>
---
arch/arm/mach-omap2/Kconfig | 2 +-
arch/arm/mach-tegra/Kconfig | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index f49cd51..831e89e 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -83,7 +83,7 @@ config ARCH_OMAP4
depends on ARCH_OMAP2PLUS
depends on ARCH_MULTI_V7
select ARCH_HAS_OPP
- select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
+ select ARCH_NEEDS_CPU_IDLE_COUPLED if (SMP && CPU_IDLE)
select ARM_CPU_SUSPEND if PM
select ARM_ERRATA_720789
select ARM_GIC
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 84d72fc..04c6221 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -23,7 +23,7 @@ menu "NVIDIA Tegra options"
config ARCH_TEGRA_2x_SOC
bool "Enable support for Tegra20 family"
- select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
+ select ARCH_NEEDS_CPU_IDLE_COUPLED if (SMP && CPU_IDLE)
select ARM_ERRATA_720789
select ARM_ERRATA_754327 if SMP
select ARM_ERRATA_764369 if SMP
--
1.7.9.5
This patch series does the following:
1) Factors out possible common code, unifies the clk strutures used
for PLL35xx & PLL36xx and usues clk->base instead of clk->con0
2) Defines a common rate_table which will contain recommended p, m, s and k
values for supported rates that needs to be changed for changing
corresponding PLL's rate
3) Adds set_rate() and round_rate() clk_ops for PLL35xx and PLL36xx
changes since v1:
- removed sorting and bsearch
- modified the definition of struct "samsung_pll_rate_table"
- added generic round_rate()
- rectified the ops assignment for "rate table passed as NULL"
during PLL registration
Is rebased on branch kgene's "for-next"
https://git.kernel.org/cgit/linux/kernel/git/kgene/linux-samsung.git/log/?h…
And tested these patch on chromebook for EPLL settings for Audio on our chrome tree.
Vikas Sajjan (2):
clk: samsung: Add set_rate() clk_ops for PLL36xx
clk: samsung: Add EPLL and VPLL freq table for exynos5250 SoC
Yadwinder Singh Brar (3):
clk: samsung: Use clk->base instead of directly using clk->con0 for
PLL3xxx
clk: samsung: Add support to register rate_table for PLL3xxx
clk: samsung: Add set_rate() clk_ops for PLL35xx
drivers/clk/samsung/clk-exynos4.c | 10 +-
drivers/clk/samsung/clk-exynos5250.c | 30 +++--
drivers/clk/samsung/clk-pll.c | 226 ++++++++++++++++++++++++++++++----
drivers/clk/samsung/clk-pll.h | 33 ++++-
4 files changed, 260 insertions(+), 39 deletions(-)
--
1.7.9.5
=== Highlights ===
* Sent my 3.11 queue to Thomas
* Reviewed/Looked at queueing generic sched_clock logic from arch/arm
* Strange 3.9.4 regression from last week ended up being a gcc issue
* Reviewed blueprints and sent out weekly android upstreaming mail
* Dhaval G. (Mozilla) is interested in helping with Volatile Ranges, so
spent some time bringing him up to speed on volatile range work
* Continued some older discussions with Minchan on volatile ranges
* Started re-factoring volatile ranges patch to make shared volatility
the default and private an optimization
* Worked with Zoran on some new tasks (pushing wakeup_source driver
enablement upstream)
* Synced with AntonV on memcg pressure levels and userland low-memory
killer.
* Sent mail to Android devs to get their thoughts on userland low-memory
killer
* Pinged maintainers on KDB kiosk mode
=== Plans ===
* Continued volatile range work
* Send out refactored ION patches and comments to Google devs
* Finish queuing items for 3.11
* LSK / upstream review & mentoring discussions
=== Issues ===
* N/A
Hi,
On 6 June 2013 12:37, Lukasz Majewski <l.majewski(a)samsung.com> wrote:
> This commit adds support for software based frequency boosting.
> Exynos4 SoCs (e.g. 4x12) allow setting of frequency above its normal
> condition limits. This can be done for some short time.
>
> Overclocking (boost) support came from cpufreq driver (which is platform
> dependent). Hence the data structure describing it is defined at its file.
>
> To allow support for either SW and HW (Intel) based boosting, the cpufreq
> core code has been extended to support both solutions.
>
> The main boost switch has been put at /sys/devices/system/cpu/cpufreq/boost.
Log requires some better paragraphs but I am not concerned about it for now.
> Signed-off-by: Lukasz Majewski <l.majewski(a)samsung.com>
> Signed-off-by: Myungjoo Ham <myungjoo.ham(a)samsung.com>
> ---
> drivers/cpufreq/cpufreq.c | 156 ++++++++++++++++++++++++++++++++++++++++++
> drivers/cpufreq/freq_table.c | 87 ++++++++++++++++++++++-
> include/linux/cpufreq.h | 35 +++++++++-
> 3 files changed, 275 insertions(+), 3 deletions(-)
My initial view on this patch is: "It is overly engineered and needs
to get simplified"
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index ca74e27..8cf9a92 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -133,6 +133,11 @@ bool have_governor_per_policy(void)
> return cpufreq_driver->have_governor_per_policy;
> }
>
> +/**
> + * Global definition of cpufreq_boost structure
> + */
> +struct cpufreq_boost *cpufreq_boost;
Probably just a 'static bool' here cpufreq_boost_enabled. Which takes
care of selection from sysfs.
> static struct cpufreq_governor *__find_governor(const char *str_governor)
> {
> @@ -761,6 +805,18 @@ static int cpufreq_add_dev_interface(unsigned int cpu,
> if (cpufreq_set_drv_attr_files(policy, cpufreq_driver->attr))
> goto err_out_kobj_put;
>
> + if (cpufreq_driver->boost) {
> + if (sysfs_create_file(cpufreq_global_kobject,
> + &(global_boost.attr)))
This will report error for systems where we have two policy structures.
As we are creating something already present.
> + pr_warn("could not register global boost sysfs file\n");
> + else
> + pr_debug("registered global boost sysfs file\n");
Please make all your prints to print function name too:
pr_debug("%s: foo\n", __func__, foo);
> + if (cpufreq_set_drv_attr_files(policy,
> + cpufreq_driver->boost->attr))
Why is this required? Why do we want platforms to add some files
in sysfs?
> /*********************************************************************
> + * BOOST *
> + *********************************************************************/
> +int cpufreq_boost_trigger_state(struct cpufreq_policy *policy, int state)
> +{
> + struct cpufreq_boost *boost;
> + unsigned long flags;
> + int ret = 0;
> +
> + if (!policy || !policy->boost || !policy->boost->low_level_boost)
> + return -ENODEV;
> +
> + boost = policy->boost;
> + write_lock_irqsave(&cpufreq_driver_lock, flags);
> +
> + if (boost->status != state) {
> + policy->boost->status = state;
> + ret = boost->low_level_boost(policy, state);
> + if (ret) {
> + pr_err("BOOST cannot %sable low level code (%d)\n",
> + state ? "en" : "dis", ret);
> + return ret;
> + }
> + }
> +
> + write_unlock_irqrestore(&cpufreq_driver_lock, flags);
> +
> + pr_debug("cpufreq BOOST %sabled\n", state ? "en" : "dis");
> +
> + return 0;
> +}
> +
> +/**
> + * cpufreq_boost_notifier - notifier callback for cpufreq policy change.
> + * <at> nb: struct notifier_block * with callback info.
> + * <at> event: value showing cpufreq event for which this function invoked.
> + * <at> data: callback-specific data
> + */
> +static int cpufreq_boost_notifier(struct notifier_block *nb,
> + unsigned long event, void *data)
> +{
> + struct cpufreq_policy *policy = data;
> +
> + if (event == CPUFREQ_INCOMPATIBLE) {
> + if (!policy || !policy->boost)
> + return -ENODEV;
> +
> + if (policy->boost->status == CPUFREQ_BOOST_EN) {
> + pr_info("NOTIFIER BOOST: MAX: %d e:%lu cpu: %d\n",
> + policy->max, event, policy->cpu);
> + cpufreq_boost_trigger_state(policy, 0);
> + }
> + }
> +
> + return 0;
> +}
> +
> +/* Notifier for cpufreq policy change */
> +static struct notifier_block cpufreq_boost_notifier_block = {
> + .notifier_call = cpufreq_boost_notifier,
> +};
> +
> +int cpufreq_boost_init(struct cpufreq_policy *policy)
> +{
> + int ret = 0;
> +
> + if (!policy)
> + return -EINVAL;
Heh, policy can't be NULL here.
> + if (!cpufreq_driver->boost) {
> + pr_err("Boost mode not supported on this device\n");
Wow!! You want to screw everybody else's logs with this message.
Its not a crime if you don't have boost mode supported :)
Actually this routine must be called only if cpufreq_driver->boost
is valid.
> + return -ENODEV;
> + }
> +
> + policy->boost = cpufreq_boost = cpufreq_driver->boost;
Why are we copying same pointer to policy->boost? Driver is
passing pointer to a single memory location, just save it globally.
> + /* disable boost for newly created policy - as we e.g. change
> + governor */
> + policy->boost->status = CPUFREQ_BOOST_DIS;
Drivers supporting boost may want boost to be enabled by default,
maybe without any sysfs calls.
> + /* register policy notifier */
> + ret = cpufreq_register_notifier(&cpufreq_boost_notifier_block,
> + CPUFREQ_POLICY_NOTIFIER);
> + if (ret) {
> + pr_err("CPUFREQ BOOST notifier not registered.\n");
> + return ret;
> + }
> + /* add policy to policies list headed at struct cpufreq_boost */
> + list_add_tail(&policy->boost_list, &cpufreq_boost->policies);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(cpufreq_boost_init);
Why do we need to maintain a list of boost here? notifiers? complex :(
> +/*********************************************************************
> * REGISTER / UNREGISTER CPUFREQ DRIVER *
> *********************************************************************/
>
> @@ -1954,6 +2106,10 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
> pr_debug("unregistering driver %s\n", driver->name);
>
> subsys_interface_unregister(&cpufreq_interface);
> +
> + if (cpufreq_driver->boost)
> + sysfs_remove_file(cpufreq_global_kobject, &(global_boost.attr));
You haven't removed this from policy. Memory leak.
> unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
>
> write_lock_irqsave(&cpufreq_driver_lock, flags);
> diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
> index d7a7966..0e95524 100644
> --- a/drivers/cpufreq/freq_table.c
> +++ b/drivers/cpufreq/freq_table.c
> @@ -3,6 +3,8 @@
> *
> * Copyright (C) 2002 - 2003 Dominik Brodowski
> *
> + * Copyright (C) 2013 Lukasz Majewski <l.majewski(a)samsung.com>
> + *
You shouldn't add it unless you did some major work on this file. You aren't
maintaining this file in 2013.
> +static int cpufreq_frequency_table_skip_boost(struct cpufreq_policy *policy,
> + unsigned int index)
> +{
> + if (index == CPUFREQ_BOOST)
> + if (!policy->boost ||
This shouldn't be true. If index has got CPUFREQ_BOOST, then driver
has to support boost.
> + policy->boost->status == CPUFREQ_BOOST_DIS)
> + return 1;
> +
> + return 0;
> +}
> +
> +unsigned int
> +cpufreq_frequency_table_boost_max(struct cpufreq_frequency_table *freq_table)
> +{
> + int index, boost_freq_max;
> +
> + for (index = 0, boost_freq_max = 0;
> + freq_table[index].frequency != CPUFREQ_TABLE_END; index++)
> + if (freq_table[index].index == CPUFREQ_BOOST) {
> + if (freq_table[index].frequency > boost_freq_max)
> + boost_freq_max = freq_table[index].frequency;
> + }
> +
> + return boost_freq_max;
> +}
> +EXPORT_SYMBOL_GPL(cpufreq_frequency_table_boost_max);
why do we need this?
> /*
> * if you use these, you must assure that the frequency table is valid
> * all the time between get_attr and put_attr!
> diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
> index 037d36a..1294c8c 100644
> --- a/include/linux/cpufreq.h
> +++ b/include/linux/cpufreq.h
> @@ -88,6 +88,25 @@ struct cpufreq_real_policy {
> struct cpufreq_governor *governor; /* see below */
> };
>
> +#define CPUFREQ_BOOST_DIS (0)
> +#define CPUFREQ_BOOST_EN (1)
You don't need these.. Just create variable as bool and 0 & 1 would
be fine.
> +struct cpufreq_policy;
> +struct cpufreq_boost {
> + unsigned int max_boost_freq; /* maximum value of
> + * boosted freq */
> + unsigned int max_normal_freq; /* non boost max freq */
> + int status; /* status of boost */
> +
> + /* boost sysfs attributies */
> + struct freq_attr **attr;
> +
> + /* low-level trigger for boost */
> + int (*low_level_boost) (struct cpufreq_policy *policy, int state);
> +
> + struct list_head policies;
> +};
We don't need it. Just add two more fields to cpufreq_driver:
- have_boost_freqs and low_level_boost (maybe a better name.
What's its use?)
> struct cpufreq_policy {
> /* CPUs sharing clock, require sw coordination */
> cpumask_var_t cpus; /* Online CPUs only */
> @@ -113,6 +132,9 @@ struct cpufreq_policy {
>
> struct cpufreq_real_policy user_policy;
>
> + struct cpufreq_boost *boost;
> + struct list_head boost_list;
We don't need both of these.
> struct kobject kobj;
> struct completion kobj_unregister;
> };
> @@ -277,7 +302,6 @@ struct cpufreq_driver {
> int cpufreq_register_driver(struct cpufreq_driver *driver_data);
> int cpufreq_unregister_driver(struct cpufreq_driver *driver_data);
>
> -
??
> void cpufreq_notify_transition(struct cpufreq_policy *policy,
> struct cpufreq_freqs *freqs, unsigned int state);
>
> @@ -403,6 +427,9 @@ extern struct cpufreq_governor cpufreq_gov_conservative;
> #define CPUFREQ_ENTRY_INVALID ~0
> #define CPUFREQ_TABLE_END ~1
>
> +/* Define index for boost frequency */
> +#define CPUFREQ_BOOST ~2
s/CPUFREQ_BOOST/CPUFREQ_BOOST_FREQ
== Linus Walleij linusw ==
=== Highlights ===
* Wrote a patch series bringing runtime PM of pins
into the device core. Greg and Mark ACKed it
immediately so I have it queued in the pinctrl tree
now. Kevin and I continue to discuss runtime PM
implications and whether we can centralize it even
more. This basically have activated this long-dormant
blueprint:
https://blueprints.launchpad.net/linux-linaro/+spec/runtimepm-pinctrl
(WG leads: please approve this blueprint.)
* Olof J pulled my ux500-fixes branch to ARM SoC.
* Applied and queued various ux500 patches, collected
ACKs and sent five (5) pull requests for the following
branches on ux500:
ux500-core
ux500-clocksource
ux500-pinctrl
ux500-dma40
ux500-devicetree
I also have a ux500-defconfig branch, that will be
submitted later, turning on this and some more new
stuff that will hit the v3.11 merge window.
* Sent a pull request for the Integrator PCI DT patch
series to ARM SoC.
* Reviewed lots of pinctrl code. Qeueued some
pinctrl patches at least. A lot of the discussion revolves
around generic DT bindings for generic pin config.
* Put my nose into some submarine-type review of new
platforms like the Rockchip and HiSilicon.
=== Plans ===
* Finalize U300 DT+multiplatform patch set and send
a pull request for it. Utilizing the syscon MFD driver
this means I will actually look at regmap now!
* Start to delete Integrator board files and convert to
multiplatform once the PCI DT patches land in ARM
SoC.
* Convert Nomadik pinctrl driver to register GPIO ranges
from the gpiochip side.
* Test the PL08x patches on the Ericsson Research
PB11MPCore and submit platform data for using
pl08x DMA on that platform.
=== Issues ===
* Subsystem maintainers in the kernel community are
acting like Judge Dredd on DT review and commit issues,
as noted last week.
* Some impediments from internal turmoil @ST-Ericsson.
Thanks,
Linus Walleij
On 6 June 2013 15:25, Borislav Petkov <bp(a)suse.de> wrote:
> The correct "fix" for this whole deal is coupling cpufreq with
> the scheduler, as it has been said so many times before. You need
> "something" which can tell you whether raising the freq. is worth it or
> not (i.e. the process is waiting on IO or is executing instructions).
Linaro has got a blueprint in this direction but doesn't have any
proof of concept or RFC patches to share. But that will happen soon.
On 6 June 2013 12:37, Lukasz Majewski <l.majewski(a)samsung.com> wrote:
> Subject: cpufreq: Define cpufreq_set_drv_attr_files() to add per CPU sysfs attributes
Its not per-cpu. We just add it for policy->cpu and other routines
actually create links.
> The cpufreq_set_drv_attr_files() function creates sysfs file entry for
> each available CPU. With it in place it is possible to add different
> set of attributes without code duplication.
Not for each available cpu but are linked to a policy->kobj and so
shows up on each policy->cpus.
> Signed-off-by: Lukasz Majewski <l.majewski(a)samsung.com>
> Signed-off-by: Myungjoo Ham <myungjoo.ham(a)samsung.com>
> ---
> drivers/cpufreq/cpufreq.c | 23 +++++++++++++++--------
> 1 file changed, 15 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index 1b8a48e..ca74e27 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -730,12 +730,23 @@ static int cpufreq_add_dev_symlink(unsigned int cpu,
> return ret;
> }
>
> +static int cpufreq_set_drv_attr_files(struct cpufreq_policy *policy,
> + struct freq_attr **drv_attr)
> +{
> + while ((drv_attr) && (*drv_attr)) {
> + if (sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)))
> + return 1;
You are changing the semantics here. We used to return error
value from sysfs_create_file() and you are returning 1.
> + drv_attr++;
If drv_attr was valid initially, then drv_attr++ can't make it NULL.
So, we don't need to check validity of drv_attr for every loop.
Currently, the RTC IRQ is never wakeup-enabled so is not capable of
bringing the system out of suspend.
On OMAP platforms, we have gotten by without this because the TWL RTC
is on an I2C-connected chip which is capable of waking up the OMAP via
the IO ring when the OMAP is in low-power states.
However, if the OMAP suspends without hitting the low-power states
(and the IO ring is not enabled), RTC wakeups will not work because
the IRQ is not wakeup enabled.
To fix, ensure the RTC IRQ is wakeup enabled whenever the RTC alarm is
set.
Cc: Alessandro Zummo <a.zummo(a)towertech.it>
Cc: Andrew Morton <akpm(a)linux-foundation.org>
Cc: Tony Lindgren <tony(a)atomide.com>
Signed-off-by: Kevin Hilman <khilman(a)linaro.org>
---
drivers/rtc/rtc-twl.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c
index 8751a52..bbda0fd 100644
--- a/drivers/rtc/rtc-twl.c
+++ b/drivers/rtc/rtc-twl.c
@@ -213,12 +213,24 @@ static int mask_rtc_irq_bit(unsigned char bit)
static int twl_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
{
+ struct platform_device *pdev = to_platform_device(dev);
+ int irq = platform_get_irq(pdev, 0);
+ static bool twl_rtc_wake_enabled;
int ret;
- if (enabled)
+ if (enabled) {
ret = set_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
- else
+ if (device_can_wakeup(dev) && !twl_rtc_wake_enabled) {
+ enable_irq_wake(irq);
+ twl_rtc_wake_enabled = true;
+ }
+ } else {
ret = mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+ if (twl_rtc_wake_enabled) {
+ disable_irq_wake(irq);
+ twl_rtc_wake_enabled = false;
+ }
+ }
return ret;
}
--
1.8.2
I have faced a sequence where the Idle Load Balance was sometime not
triggered for a while on my platform.
CPU 0 and CPU 1 are running tasks and CPU 2 is idle
CPU 1 kicks the Idle Load Balance
CPU 1 selects CPU 2 as the new Idle Load Balancer
CPU 1 sets NOHZ_BALANCE_KICK for CPU 2
CPU 1 sends a reschedule IPI to CPU 2
While CPU 2 wakes up, CPU 0 or CPU 1 migrates a waking task A on CPU 2
CPU 2 finally wakes up, runs task A and discards the Idle Load Balance
Task A quickly goes back to sleep (before a tick occurs on CPU 2)
CPU 2 goes back to idle with NOHZ_BALANCE_KICK set
Whenever CPU 2 will be selected for the ILB, reschedule IPI will be not
sent to CPU2, which is idle, because NOHZ_BALANCE_KICK is already set
and no Idle Load Balance will be performed.
We must wait for the sched softirq to be raised on CPU 2 thanks to
another part of the kernel to clear NOHZ_BALANCE_KICKand come back to
a normal situation.
The proposed solution clears NOHZ_BALANCE_KICK in schedule_ipi if
we can't raise the sched_softirq for the Idle Load Balance.
Signed-off-by: Vincent Guittot <vincent.guittot(a)linaro.org>
---
kernel/sched/core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 58453b8..51fc715 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -1420,7 +1420,8 @@ void scheduler_ipi(void)
if (unlikely(got_nohz_idle_kick() && !need_resched())) {
this_rq()->idle_balance = 1;
raise_softirq_irqoff(SCHED_SOFTIRQ);
- }
+ } else
+ clear_bit(NOHZ_BALANCE_KICK, nohz_flags(smp_processor_id()));
irq_exit();
}
--
1.7.9.5
We are saving first scheduling domain for a cpu in build_sched_domains() by
iterating over the nested sd->child list. We don't actually need to do it this
way.
*per_cpu_ptr(d.sd, i) is guaranteed to be NULL in the beginning as we have
called __visit_domain_allocation_hell() which does a memset to zero for struct
s_data.
So, save pointer to first SD while running the iteration loop over tl's.
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
---
kernel/sched/core.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 58453b8..638f6cb 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6533,16 +6533,13 @@ static int build_sched_domains(const struct cpumask *cpu_map,
sd = NULL;
for (tl = sched_domain_topology; tl->init; tl++) {
sd = build_sched_domain(tl, &d, cpu_map, attr, sd, i);
+ if (!*per_cpu_ptr(d.sd, i))
+ *per_cpu_ptr(d.sd, i) = sd;
if (tl->flags & SDTL_OVERLAP || sched_feat(FORCE_SD_OVERLAP))
sd->flags |= SD_OVERLAP;
if (cpumask_equal(cpu_map, sched_domain_span(sd)))
break;
}
-
- while (sd->child)
- sd = sd->child;
-
- *per_cpu_ptr(d.sd, i) = sd;
}
/* Build the groups for the domains */
--
1.7.12.rc2.18.g61b472e
Commit bf4d1b5ddb78f86078ac6ae0415802d5f0c68f92 brought the multiple driver
support. The code added a couple of new API to register the driver per cpu.
That led to some code complexity to handle the kernel config options when
the multiple driver support is enabled or not, which is not really necessary.
The code has to be compatible when the multiple driver support is not enabled,
and the multiple driver support has to be compatible with the old api.
This patch removes this API, which is not yet used by any driver but needed
for the HMP cpuidle drivers which will come soon, and replaces its usage
by a cpumask pointer in the cpuidle driver structure telling what cpus are
handled by the driver. That let the API cpuidle_[un]register_driver to be used
for the multipled driver support and also the cpuidle_[un]register functions,
added recently in the cpuidle framework.
The current code, a bit poor in comments, has been commented and simplified.
Signed-off-by: Daniel Lezcano <daniel.lezcano(a)linaro.org>
---
[V2]:
- fixed bad refcount check
- inverted clockevent notify off order at unregister time
drivers/cpuidle/cpuidle.c | 4 +-
drivers/cpuidle/driver.c | 324 ++++++++++++++++++++++++++++-----------------
include/linux/cpuidle.h | 21 +--
3 files changed, 213 insertions(+), 136 deletions(-)
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index c3a93fe..fdc432f 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -466,7 +466,7 @@ void cpuidle_unregister(struct cpuidle_driver *drv)
int cpu;
struct cpuidle_device *device;
- for_each_possible_cpu(cpu) {
+ for_each_cpu(cpu, drv->cpumask) {
device = &per_cpu(cpuidle_dev, cpu);
cpuidle_unregister_device(device);
}
@@ -498,7 +498,7 @@ int cpuidle_register(struct cpuidle_driver *drv,
return ret;
}
- for_each_possible_cpu(cpu) {
+ for_each_cpu(cpu, drv->cpumask) {
device = &per_cpu(cpuidle_dev, cpu);
device->cpu = cpu;
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
index 8dfaaae..0268346 100644
--- a/drivers/cpuidle/driver.c
+++ b/drivers/cpuidle/driver.c
@@ -18,206 +18,266 @@
DEFINE_SPINLOCK(cpuidle_driver_lock);
-static void __cpuidle_set_cpu_driver(struct cpuidle_driver *drv, int cpu);
-static struct cpuidle_driver * __cpuidle_get_cpu_driver(int cpu);
+#ifdef CONFIG_CPU_IDLE_MULTIPLE_DRIVERS
-static void cpuidle_setup_broadcast_timer(void *arg)
+static DEFINE_PER_CPU(struct cpuidle_driver *, cpuidle_drivers);
+
+/**
+ * __cpuidle_get_cpu_driver: returns the cpuidle driver tied with the specified
+ * cpu.
+ *
+ * @cpu: an integer specifying the cpu number
+ *
+ * Returns a pointer to struct cpuidle_driver, NULL if no driver has been
+ * registered for this driver
+ */
+static struct cpuidle_driver *__cpuidle_get_cpu_driver(int cpu)
{
- int cpu = smp_processor_id();
- clockevents_notify((long)(arg), &cpu);
+ return per_cpu(cpuidle_drivers, cpu);
}
-static void __cpuidle_driver_init(struct cpuidle_driver *drv, int cpu)
+/**
+ * __cpuidle_set_driver: assign to the per cpu variable the driver pointer for
+ * each cpu the driver is assigned to with the cpumask.
+ *
+ * @drv: a pointer to a struct cpuidle_driver
+ *
+ * Returns 0 on success, < 0 otherwise
+ */
+static inline int __cpuidle_set_driver(struct cpuidle_driver *drv)
{
- int i;
+ int cpu;
- drv->refcnt = 0;
+ for_each_cpu(cpu, drv->cpumask) {
- for (i = drv->state_count - 1; i >= 0 ; i--) {
+ if (__cpuidle_get_cpu_driver(cpu))
+ return -EBUSY;
- if (!(drv->states[i].flags & CPUIDLE_FLAG_TIMER_STOP))
- continue;
-
- drv->bctimer = 1;
- on_each_cpu_mask(get_cpu_mask(cpu), cpuidle_setup_broadcast_timer,
- (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON, 1);
- break;
+ per_cpu(cpuidle_drivers, cpu) = drv;
}
+
+ return 0;
}
-static int __cpuidle_register_driver(struct cpuidle_driver *drv, int cpu)
+/**
+ * __cpuidle_unset_driver: for each cpu the driver is handling, set the per cpu
+ * variable driver to NULL.
+ *
+ * @drv: a pointer to a struct cpuidle_driver
+ */
+static inline void __cpuidle_unset_driver(struct cpuidle_driver *drv)
{
- if (!drv || !drv->state_count)
- return -EINVAL;
-
- if (cpuidle_disabled())
- return -ENODEV;
-
- if (__cpuidle_get_cpu_driver(cpu))
- return -EBUSY;
+ int cpu;
- __cpuidle_driver_init(drv, cpu);
+ for_each_cpu(cpu, drv->cpumask) {
- __cpuidle_set_cpu_driver(drv, cpu);
+ if (drv != __cpuidle_get_cpu_driver(cpu))
+ continue;
- return 0;
+ per_cpu(cpuidle_drivers, cpu) = NULL;
+ }
}
-static void __cpuidle_unregister_driver(struct cpuidle_driver *drv, int cpu)
-{
- if (drv != __cpuidle_get_cpu_driver(cpu))
- return;
+#else
- if (!WARN_ON(drv->refcnt > 0))
- __cpuidle_set_cpu_driver(NULL, cpu);
+static struct cpuidle_driver *cpuidle_curr_driver;
- if (drv->bctimer) {
- drv->bctimer = 0;
- on_each_cpu_mask(get_cpu_mask(cpu), cpuidle_setup_broadcast_timer,
- (void *)CLOCK_EVT_NOTIFY_BROADCAST_OFF, 1);
- }
+/**
+ * __cpuidle_get_cpu_driver: returns the global cpuidle driver pointer.
+ *
+ * @cpu: an integer specifying the cpu number, this parameter is ignored
+ *
+ * Returns a pointer to a struct cpuidle_driver, NULL if no driver was
+ * previously registered
+ */
+static inline struct cpuidle_driver *__cpuidle_get_cpu_driver(int cpu)
+{
+ return cpuidle_curr_driver;
}
-#ifdef CONFIG_CPU_IDLE_MULTIPLE_DRIVERS
+/**
+ * __cpuidle_set_driver: assign the cpuidle driver pointer to the global cpuidle
+ * driver variable.
+ *
+ * @drv: a pointer to a struct cpuidle_driver
+ *
+ * Returns 0 on success, < 0 otherwise
+ */
+static inline int __cpuidle_set_driver(struct cpuidle_driver *drv)
+{
+ if (cpuidle_curr_driver)
+ return -EBUSY;
-static DEFINE_PER_CPU(struct cpuidle_driver *, cpuidle_drivers);
+ cpuidle_curr_driver = drv;
-static void __cpuidle_set_cpu_driver(struct cpuidle_driver *drv, int cpu)
-{
- per_cpu(cpuidle_drivers, cpu) = drv;
+ return 0;
}
-static struct cpuidle_driver *__cpuidle_get_cpu_driver(int cpu)
+/**
+ * __cpuidle_unset_driver: reset the global cpuidle driver variable if the
+ * cpuidle driver pointer match it.
+ *
+ * @drv: a pointer to a struct cpuidle_driver
+ */
+static inline void __cpuidle_unset_driver(struct cpuidle_driver *drv)
{
- return per_cpu(cpuidle_drivers, cpu);
+ if (drv == cpuidle_curr_driver)
+ cpuidle_curr_driver = NULL;
}
-static void __cpuidle_unregister_all_cpu_driver(struct cpuidle_driver *drv)
+#endif
+
+/**
+ * cpuidle_setup_broadcast_timer: set the broadcast timer notification for the
+ * current cpu. This function is called per cpu context invoked by a smp cross
+ * call. It is not supposed to be called directly.
+ *
+ * @arg: a void pointer, actually used to match the smp cross call api but used
+ * as a long with two values:
+ * - CLOCK_EVT_NOTIFY_BROADCAST_ON
+ * - CLOCK_EVT_NOTIFY_BROADCAST_OFF
+ */
+static void cpuidle_setup_broadcast_timer(void *arg)
{
- int cpu;
- for_each_present_cpu(cpu)
- __cpuidle_unregister_driver(drv, cpu);
+ int cpu = smp_processor_id();
+ clockevents_notify((long)(arg), &cpu);
}
-static int __cpuidle_register_all_cpu_driver(struct cpuidle_driver *drv)
+/**
+ * __cpuidle_driver_init: initialize the driver internal data.
+ *
+ * @drv: a valid pointer to a struct cpuidle_driver
+ *
+ * Returns 0 on success, < 0 otherwise
+ */
+static int __cpuidle_driver_init(struct cpuidle_driver *drv)
{
- int ret = 0;
- int i, cpu;
+ int i;
- for_each_present_cpu(cpu) {
- ret = __cpuidle_register_driver(drv, cpu);
- if (ret)
- break;
- }
+ drv->refcnt = 0;
- if (ret)
- for_each_present_cpu(i) {
- if (i == cpu)
- break;
- __cpuidle_unregister_driver(drv, i);
- }
+ /*
+ * we default here to all cpu possible because if the kernel
+ * boots with some cpus offline and then we online one of them
+ * the cpu notifier won't know which driver to assign
+ */
+ if (!drv->cpumask)
+ drv->cpumask = (struct cpumask *)cpu_possible_mask;
+
+ /*
+ * we look for the timer stop flag in the different states,
+ * so know we have to setup the broadcast timer. The loop is
+ * in reverse order, because usually the deeper state has this
+ * flag set
+ */
+ for (i = drv->state_count - 1; i >= 0 ; i--) {
+ if (!(drv->states[i].flags & CPUIDLE_FLAG_TIMER_STOP))
+ continue;
- return ret;
+ drv->bctimer = 1;
+ break;
+ }
+
+ return 0;
}
-int cpuidle_register_cpu_driver(struct cpuidle_driver *drv, int cpu)
+/**
+ * __cpuidle_register_driver: do some sanity checks, initializes the driver,
+ * assign the driver to the global cpuidle driver variable(s) and setup the
+ * broadcast timer if the cpuidle driver has some states which shutdown the
+ * local timer.
+ *
+ * @drv: a valid pointer to a struct cpuidle_driver
+ *
+ * Returns 0 on success, < 0 otherwise
+ */
+static int __cpuidle_register_driver(struct cpuidle_driver *drv)
{
int ret;
- spin_lock(&cpuidle_driver_lock);
- ret = __cpuidle_register_driver(drv, cpu);
- spin_unlock(&cpuidle_driver_lock);
+ if (!drv || !drv->state_count)
+ return -EINVAL;
- return ret;
-}
+ if (cpuidle_disabled())
+ return -ENODEV;
-void cpuidle_unregister_cpu_driver(struct cpuidle_driver *drv, int cpu)
-{
- spin_lock(&cpuidle_driver_lock);
- __cpuidle_unregister_driver(drv, cpu);
- spin_unlock(&cpuidle_driver_lock);
-}
+ ret = __cpuidle_driver_init(drv);
+ if (ret)
+ return ret;
-/**
- * cpuidle_register_driver - registers a driver
- * @drv: the driver
- */
-int cpuidle_register_driver(struct cpuidle_driver *drv)
-{
- int ret;
+ ret = __cpuidle_set_driver(drv);
+ if (ret)
+ return ret;
- spin_lock(&cpuidle_driver_lock);
- ret = __cpuidle_register_all_cpu_driver(drv);
- spin_unlock(&cpuidle_driver_lock);
+ if (drv->bctimer)
+ on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer,
+ (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON, 1);
- return ret;
+ return 0;
}
-EXPORT_SYMBOL_GPL(cpuidle_register_driver);
/**
- * cpuidle_unregister_driver - unregisters a driver
- * @drv: the driver
+ * __cpuidle_unregister_driver: checks the driver is no longer in use, reset the
+ * global cpuidle driver variable(s) and disable the timer broadcast
+ * notification mechanism if it was in use.
+ *
+ * @drv: a valid pointer to a struct cpuidle_driver
+ *
*/
-void cpuidle_unregister_driver(struct cpuidle_driver *drv)
+static void __cpuidle_unregister_driver(struct cpuidle_driver *drv)
{
- spin_lock(&cpuidle_driver_lock);
- __cpuidle_unregister_all_cpu_driver(drv);
- spin_unlock(&cpuidle_driver_lock);
-}
-EXPORT_SYMBOL_GPL(cpuidle_unregister_driver);
-
-#else
-
-static struct cpuidle_driver *cpuidle_curr_driver;
+ if (WARN_ON(drv->refcnt > 0))
+ return;
-static inline void __cpuidle_set_cpu_driver(struct cpuidle_driver *drv, int cpu)
-{
- cpuidle_curr_driver = drv;
-}
+ if (drv->bctimer) {
+ drv->bctimer = 0;
+ on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer,
+ (void *)CLOCK_EVT_NOTIFY_BROADCAST_OFF, 1);
+ }
-static inline struct cpuidle_driver *__cpuidle_get_cpu_driver(int cpu)
-{
- return cpuidle_curr_driver;
+ __cpuidle_unset_driver(drv);
}
/**
- * cpuidle_register_driver - registers a driver
- * @drv: the driver
+ * cpuidle_register_driver: registers a driver by taking a lock to prevent
+ * multiple callers to [un]register a driver at the same time.
+ *
+ * @drv: a pointer to a valid struct cpuidle_driver
+ *
+ * Returns 0 on success, < 0 otherwise
*/
int cpuidle_register_driver(struct cpuidle_driver *drv)
{
- int ret, cpu;
+ int ret;
- cpu = get_cpu();
spin_lock(&cpuidle_driver_lock);
- ret = __cpuidle_register_driver(drv, cpu);
+ ret = __cpuidle_register_driver(drv);
spin_unlock(&cpuidle_driver_lock);
- put_cpu();
return ret;
}
EXPORT_SYMBOL_GPL(cpuidle_register_driver);
/**
- * cpuidle_unregister_driver - unregisters a driver
- * @drv: the driver
+ * cpuidle_unregister_driver: unregisters a driver by taking a lock to prevent
+ * multiple callers to [un]register a driver at the same time. The specified
+ * driver must match the driver currently registered.
+ *
+ * @drv: a pointer to a valid struct cpuidle_driver
*/
void cpuidle_unregister_driver(struct cpuidle_driver *drv)
{
- int cpu;
-
- cpu = get_cpu();
spin_lock(&cpuidle_driver_lock);
- __cpuidle_unregister_driver(drv, cpu);
+ __cpuidle_unregister_driver(drv);
spin_unlock(&cpuidle_driver_lock);
- put_cpu();
}
EXPORT_SYMBOL_GPL(cpuidle_unregister_driver);
-#endif
/**
- * cpuidle_get_driver - return the current driver
+ * cpuidle_get_driver: returns the driver tied with the current cpu.
+ *
+ * Returns a struct cpuidle_driver pointer, or NULL if no driver is registered
*/
struct cpuidle_driver *cpuidle_get_driver(void)
{
@@ -233,7 +293,12 @@ struct cpuidle_driver *cpuidle_get_driver(void)
EXPORT_SYMBOL_GPL(cpuidle_get_driver);
/**
- * cpuidle_get_cpu_driver - return the driver tied with a cpu
+ * cpuidle_get_cpu_driver: returns the driver registered with a cpu.
+ *
+ * @dev: a valid pointer to a struct cpuidle_device
+ *
+ * Returns a struct cpuidle_driver pointer, or NULL if no driver is registered
+ * for the specified cpu
*/
struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev)
{
@@ -244,6 +309,13 @@ struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev)
}
EXPORT_SYMBOL_GPL(cpuidle_get_cpu_driver);
+/**
+ * cpuidle_driver_ref: gets a refcount for the driver. Note this function takes
+ * a refcount for the driver assigned to the current cpu.
+ *
+ * Returns a struct cpuidle_driver pointer, or NULL if no driver is registered
+ * for the current cpu
+ */
struct cpuidle_driver *cpuidle_driver_ref(void)
{
struct cpuidle_driver *drv;
@@ -257,6 +329,10 @@ struct cpuidle_driver *cpuidle_driver_ref(void)
return drv;
}
+/**
+ * cpuidle_driver_unref: puts down the refcount for the driver. Note this
+ * function decrement the refcount for the driver assigned to the current cpu.
+ */
void cpuidle_driver_unref(void)
{
struct cpuidle_driver *drv = cpuidle_get_driver();
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 8f04062..63d78b1 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -101,16 +101,20 @@ static inline int cpuidle_get_last_residency(struct cpuidle_device *dev)
****************************/
struct cpuidle_driver {
- const char *name;
- struct module *owner;
- int refcnt;
+ const char *name;
+ struct module *owner;
+ int refcnt;
/* used by the cpuidle framework to setup the broadcast timer */
- unsigned int bctimer:1;
+ unsigned int bctimer:1;
+
/* states array must be ordered in decreasing power consumption */
- struct cpuidle_state states[CPUIDLE_STATE_MAX];
- int state_count;
- int safe_state_index;
+ struct cpuidle_state states[CPUIDLE_STATE_MAX];
+ int state_count;
+ int safe_state_index;
+
+ /* the driver handles the cpus in cpumask */
+ struct cpumask *cpumask;
};
#ifdef CONFIG_CPU_IDLE
@@ -135,9 +139,6 @@ extern void cpuidle_disable_device(struct cpuidle_device *dev);
extern int cpuidle_play_dead(void);
extern struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev);
-extern int cpuidle_register_cpu_driver(struct cpuidle_driver *drv, int cpu);
-extern void cpuidle_unregister_cpu_driver(struct cpuidle_driver *drv, int cpu);
-
#else
static inline void disable_cpuidle(void) { }
static inline int cpuidle_idle_call(void) { return -ENODEV; }
--
1.7.9.5
The current code considers every wakeup as spurious, which is not
correct. Handle the same way as other arm platforms are doing.
Signed-off-by: Sanjay Singh Rawat <sanjay.rawat(a)linaro.org>
---
arch/arm/mach-zynq/hotplug.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm/mach-zynq/hotplug.c b/arch/arm/mach-zynq/hotplug.c
index c89672b..a1ab22c 100644
--- a/arch/arm/mach-zynq/hotplug.c
+++ b/arch/arm/mach-zynq/hotplug.c
@@ -67,6 +67,13 @@ static inline void zynq_platform_do_lowpower(unsigned int cpu, int *spurious)
dsb();
wfi();
+ if (pen_release == cpu_logical_map(cpu)) {
+ /*
+ * OK, proper wakeup, we're done
+ */
+ break;
+ }
+
/*
* Getting here, means that we have come out of WFI without
* having been woken up - this shouldn't happen
--
1.7.9.5
This patch series adds support for DP on Exynos5250 based Arndale Board
Is based on branch "for-next"
http://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
Vikas Sajjan (3):
ARM: dts: Add DT node for DP controller for Arndale Board
ARM: dts: Add clock provider information for DP controller in
Exynos5250 SoC
ARM: dts: Add display timing node to exynos5250-arndale.dts
arch/arm/boot/dts/exynos5250-arndale.dts | 26 ++++++++++++++++++++++++++
arch/arm/boot/dts/exynos5250.dtsi | 2 ++
2 files changed, 28 insertions(+)
--
1.7.9.5
Most of the stuff from kernel/sched.c was moved to kernel/sched/core.c long time
back and the comments/Documentation never got updated.
I figured it out when I was going through sched-domains.txt and so thought of
fixing it globally.
I haven't crossed check if the stuff that is referenced in sched/core.c by all
these files is still present and hasn't changed as that wasn't the motive behind
this patch.
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
---
Documentation/cgroups/cpusets.txt | 2 +-
Documentation/rt-mutex-design.txt | 2 +-
Documentation/scheduler/sched-domains.txt | 4 ++--
Documentation/spinlocks.txt | 2 +-
Documentation/virtual/uml/UserModeLinux-HOWTO.txt | 4 ++--
arch/avr32/kernel/process.c | 2 +-
arch/cris/include/arch-v10/arch/bitops.h | 2 +-
arch/ia64/kernel/head.S | 2 +-
arch/mips/kernel/mips-mt-fpaff.c | 4 ++--
arch/mips/kernel/scall32-o32.S | 5 +++--
arch/powerpc/include/asm/mmu_context.h | 2 +-
arch/tile/include/asm/processor.h | 2 +-
arch/tile/kernel/stack.c | 2 +-
arch/um/kernel/sysrq.c | 2 +-
include/linux/completion.h | 2 +-
include/linux/perf_event.h | 2 +-
include/linux/spinlock_up.h | 2 +-
include/uapi/asm-generic/unistd.h | 2 +-
kernel/cpuset.c | 4 ++--
kernel/time.c | 2 +-
kernel/workqueue_internal.h | 2 +-
21 files changed, 27 insertions(+), 26 deletions(-)
diff --git a/Documentation/cgroups/cpusets.txt b/Documentation/cgroups/cpusets.txt
index 12e01d4..7740038 100644
--- a/Documentation/cgroups/cpusets.txt
+++ b/Documentation/cgroups/cpusets.txt
@@ -373,7 +373,7 @@ can become very uneven.
1.7 What is sched_load_balance ?
--------------------------------
-The kernel scheduler (kernel/sched.c) automatically load balances
+The kernel scheduler (kernel/sched/core.c) automatically load balances
tasks. If one CPU is underutilized, kernel code running on that
CPU will look for tasks on other more overloaded CPUs and move those
tasks to itself, within the constraints of such placement mechanisms
diff --git a/Documentation/rt-mutex-design.txt b/Documentation/rt-mutex-design.txt
index 33ed800..a5bcd7f 100644
--- a/Documentation/rt-mutex-design.txt
+++ b/Documentation/rt-mutex-design.txt
@@ -384,7 +384,7 @@ priority back.
__rt_mutex_adjust_prio examines the result of rt_mutex_getprio, and if the
result does not equal the task's current priority, then rt_mutex_setprio
is called to adjust the priority of the task to the new priority.
-Note that rt_mutex_setprio is defined in kernel/sched.c to implement the
+Note that rt_mutex_setprio is defined in kernel/sched/core.c to implement the
actual change in priority.
It is interesting to note that __rt_mutex_adjust_prio can either increase
diff --git a/Documentation/scheduler/sched-domains.txt b/Documentation/scheduler/sched-domains.txt
index 443f0c7..4af80b1 100644
--- a/Documentation/scheduler/sched-domains.txt
+++ b/Documentation/scheduler/sched-domains.txt
@@ -25,7 +25,7 @@ is treated as one entity. The load of a group is defined as the sum of the
load of each of its member CPUs, and only when the load of a group becomes
out of balance are tasks moved between groups.
-In kernel/sched.c, trigger_load_balance() is run periodically on each CPU
+In kernel/sched/core.c, trigger_load_balance() is run periodically on each CPU
through scheduler_tick(). It raises a softirq after the next regularly scheduled
rebalancing event for the current runqueue has arrived. The actual load
balancing workhorse, run_rebalance_domains()->rebalance_domains(), is then run
@@ -62,7 +62,7 @@ struct sched_domain fields, SD_FLAG_*, SD_*_INIT to get an idea of
the specifics and what to tune.
Architectures may retain the regular override the default SD_*_INIT flags
-while using the generic domain builder in kernel/sched.c if they wish to
+while using the generic domain builder in kernel/sched/core.c if they wish to
retain the traditional SMT->SMP->NUMA topology (or some subset of that). This
can be done by #define'ing ARCH_HASH_SCHED_TUNE.
diff --git a/Documentation/spinlocks.txt b/Documentation/spinlocks.txt
index 9dbe885..97eaf57 100644
--- a/Documentation/spinlocks.txt
+++ b/Documentation/spinlocks.txt
@@ -137,7 +137,7 @@ don't block on each other (and thus there is no dead-lock wrt interrupts.
But when you do the write-lock, you have to use the irq-safe version.
For an example of being clever with rw-locks, see the "waitqueue_lock"
-handling in kernel/sched.c - nothing ever _changes_ a wait-queue from
+handling in kernel/sched/core.c - nothing ever _changes_ a wait-queue from
within an interrupt, they only read the queue in order to know whom to
wake up. So read-locks are safe (which is good: they are very common
indeed), while write-locks need to protect themselves against interrupts.
diff --git a/Documentation/virtual/uml/UserModeLinux-HOWTO.txt b/Documentation/virtual/uml/UserModeLinux-HOWTO.txt
index a5f8436..f4099ca 100644
--- a/Documentation/virtual/uml/UserModeLinux-HOWTO.txt
+++ b/Documentation/virtual/uml/UserModeLinux-HOWTO.txt
@@ -3127,7 +3127,7 @@
at process_kern.c:156
#3 0x1006a052 in switch_to (prev=0x50072000, next=0x507e8000, last=0x50072000)
at process_kern.c:161
- #4 0x10001d12 in schedule () at sched.c:777
+ #4 0x10001d12 in schedule () at core.c:777
#5 0x1006a744 in __down (sem=0x507d241c) at semaphore.c:71
#6 0x1006aa10 in __down_failed () at semaphore.c:157
#7 0x1006c5d8 in segv_handler (sc=0x5006e940) at trap_user.c:174
@@ -3191,7 +3191,7 @@
at process_kern.c:161
161 _switch_to(prev, next);
(gdb)
- #4 0x10001d12 in schedule () at sched.c:777
+ #4 0x10001d12 in schedule () at core.c:777
777 switch_to(prev, next, prev);
(gdb)
#5 0x1006a744 in __down (sem=0x507d241c) at semaphore.c:71
diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c
index e7b6149..c273100 100644
--- a/arch/avr32/kernel/process.c
+++ b/arch/avr32/kernel/process.c
@@ -341,7 +341,7 @@ unsigned long get_wchan(struct task_struct *p)
* is actually quite ugly. It might be possible to
* determine the frame size automatically at build
* time by doing this:
- * - compile sched.c
+ * - compile sched/core.c
* - disassemble the resulting sched.o
* - look for 'sub sp,??' shortly after '<schedule>:'
*/
diff --git a/arch/cris/include/arch-v10/arch/bitops.h b/arch/cris/include/arch-v10/arch/bitops.h
index be85f6d..03d9cfd 100644
--- a/arch/cris/include/arch-v10/arch/bitops.h
+++ b/arch/cris/include/arch-v10/arch/bitops.h
@@ -17,7 +17,7 @@ static inline unsigned long cris_swapnwbrlz(unsigned long w)
in another register:
! __asm__ ("swapnwbr %2\n\tlz %2,%0"
! : "=r,r" (res), "=r,X" (dummy) : "1,0" (w));
- confuses gcc (sched.c, gcc from cris-dist-1.14). */
+ confuses gcc (core.c, gcc from cris-dist-1.14). */
unsigned long res;
__asm__ ("swapnwbr %0 \n\t"
diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S
index 9be4e49..991ca33 100644
--- a/arch/ia64/kernel/head.S
+++ b/arch/ia64/kernel/head.S
@@ -1035,7 +1035,7 @@ END(ia64_delay_loop)
* Return a CPU-local timestamp in nano-seconds. This timestamp is
* NOT synchronized across CPUs its return value must never be
* compared against the values returned on another CPU. The usage in
- * kernel/sched.c ensures that.
+ * kernel/sched/core.c ensures that.
*
* The return-value of sched_clock() is NOT supposed to wrap-around.
* If it did, it would cause some scheduling hiccups (at the worst).
diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c
index fd814e0..cb09862 100644
--- a/arch/mips/kernel/mips-mt-fpaff.c
+++ b/arch/mips/kernel/mips-mt-fpaff.c
@@ -27,12 +27,12 @@ unsigned long mt_fpemul_threshold;
* FPU affinity with the user's requested processor affinity.
* This code is 98% identical with the sys_sched_setaffinity()
* and sys_sched_getaffinity() system calls, and should be
- * updated when kernel/sched.c changes.
+ * updated when kernel/sched/core.c changes.
*/
/*
* find_process_by_pid - find a process with a matching PID value.
- * used in sys_sched_set/getaffinity() in kernel/sched.c, so
+ * used in sys_sched_set/getaffinity() in kernel/sched/core.c, so
* cloned here.
*/
static inline struct task_struct *find_process_by_pid(pid_t pid)
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index 9b36424..e9127ec 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -476,8 +476,9 @@ einval: li v0, -ENOSYS
/*
* For FPU affinity scheduling on MIPS MT processors, we need to
* intercept sys_sched_xxxaffinity() calls until we get a proper hook
- * in kernel/sched.c. Considered only temporary we only support these
- * hooks for the 32-bit kernel - there is no MIPS64 MT processor atm.
+ * in kernel/sched/core.c. Considered only temporary we only support
+ * these hooks for the 32-bit kernel - there is no MIPS64 MT processor
+ * atm.
*/
sys mipsmt_sys_sched_setaffinity 3
sys mipsmt_sys_sched_getaffinity 3
diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h
index a73668a..b467530 100644
--- a/arch/powerpc/include/asm/mmu_context.h
+++ b/arch/powerpc/include/asm/mmu_context.h
@@ -38,7 +38,7 @@ extern void drop_cop(unsigned long acop, struct mm_struct *mm);
/*
* switch_mm is the entry point called from the architecture independent
- * code in kernel/sched.c
+ * code in kernel/sched/core.c
*/
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *tsk)
diff --git a/arch/tile/include/asm/processor.h b/arch/tile/include/asm/processor.h
index 2b70dfb..b3f1049 100644
--- a/arch/tile/include/asm/processor.h
+++ b/arch/tile/include/asm/processor.h
@@ -225,7 +225,7 @@ extern int do_work_pending(struct pt_regs *regs, u32 flags);
/*
* Return saved (kernel) PC of a blocked thread.
- * Only used in a printk() in kernel/sched.c, so don't work too hard.
+ * Only used in a printk() in kernel/sched/core.c, so don't work too hard.
*/
#define thread_saved_pc(t) ((t)->thread.pc)
diff --git a/arch/tile/kernel/stack.c b/arch/tile/kernel/stack.c
index ed258b8..af8dfc9 100644
--- a/arch/tile/kernel/stack.c
+++ b/arch/tile/kernel/stack.c
@@ -442,7 +442,7 @@ void _KBacktraceIterator_init_current(struct KBacktraceIterator *kbt, ulong pc,
regs_to_pt_regs(®s, pc, lr, sp, r52));
}
-/* This is called only from kernel/sched.c, with esp == NULL */
+/* This is called only from kernel/sched/core.c, with esp == NULL */
void show_stack(struct task_struct *task, unsigned long *esp)
{
struct KBacktraceIterator kbt;
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
index 7d101a2..0dc4d1c 100644
--- a/arch/um/kernel/sysrq.c
+++ b/arch/um/kernel/sysrq.c
@@ -39,7 +39,7 @@ void show_trace(struct task_struct *task, unsigned long * stack)
static const int kstack_depth_to_print = 24;
/* This recently started being used in arch-independent code too, as in
- * kernel/sched.c.*/
+ * kernel/sched/core.c.*/
void show_stack(struct task_struct *task, unsigned long *esp)
{
unsigned long *stack;
diff --git a/include/linux/completion.h b/include/linux/completion.h
index 33f0280..3cd574d 100644
--- a/include/linux/completion.h
+++ b/include/linux/completion.h
@@ -5,7 +5,7 @@
* (C) Copyright 2001 Linus Torvalds
*
* Atomic wait-for-completion handler data structures.
- * See kernel/sched.c for details.
+ * See kernel/sched/core.c for details.
*/
#include <linux/wait.h>
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index f463a46..5ec99e5 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -803,7 +803,7 @@ static inline void perf_restore_debug_store(void) { }
#define perf_output_put(handle, x) perf_output_copy((handle), &(x), sizeof(x))
/*
- * This has to have a higher priority than migration_notifier in sched.c.
+ * This has to have a higher priority than migration_notifier in sched/core.c.
*/
#define perf_cpu_notifier(fn) \
do { \
diff --git a/include/linux/spinlock_up.h b/include/linux/spinlock_up.h
index e2369c1..8b3ac0d 100644
--- a/include/linux/spinlock_up.h
+++ b/include/linux/spinlock_up.h
@@ -67,7 +67,7 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
#else /* DEBUG_SPINLOCK */
#define arch_spin_is_locked(lock) ((void)(lock), 0)
-/* for sched.c and kernel_lock.c: */
+/* for sched/core.c and kernel_lock.c: */
# define arch_spin_lock(lock) do { barrier(); (void)(lock); } while (0)
# define arch_spin_lock_flags(lock, flags) do { barrier(); (void)(lock); } while (0)
# define arch_spin_unlock(lock) do { barrier(); (void)(lock); } while (0)
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 0cc74c4..a20a9b4 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -361,7 +361,7 @@ __SYSCALL(__NR_syslog, sys_syslog)
#define __NR_ptrace 117
__SYSCALL(__NR_ptrace, sys_ptrace)
-/* kernel/sched.c */
+/* kernel/sched/core.c */
#define __NR_sched_setparam 118
__SYSCALL(__NR_sched_setparam, sys_sched_setparam)
#define __NR_sched_setscheduler 119
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 64b3f79..902d13f 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -540,7 +540,7 @@ static void update_domain_attr_tree(struct sched_domain_attr *dattr,
* This function builds a partial partition of the systems CPUs
* A 'partial partition' is a set of non-overlapping subsets whose
* union is a subset of that set.
- * The output of this function needs to be passed to kernel/sched.c
+ * The output of this function needs to be passed to kernel/sched/core.c
* partition_sched_domains() routine, which will rebuild the scheduler's
* load balancing domains (sched domains) as specified by that partial
* partition.
@@ -569,7 +569,7 @@ static void update_domain_attr_tree(struct sched_domain_attr *dattr,
* is a subset of one of these domains, while there are as
* many such domains as possible, each as small as possible.
* doms - Conversion of 'csa' to an array of cpumasks, for passing to
- * the kernel/sched.c routine partition_sched_domains() in a
+ * the kernel/sched/core.c routine partition_sched_domains() in a
* convenient format, that can be easily compared to the prior
* value to determine what partition elements (sched domains)
* were changed (added or removed.)
diff --git a/kernel/time.c b/kernel/time.c
index d3617db..7c7964c 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -11,7 +11,7 @@
* Modification history kernel/time.c
*
* 1993-09-02 Philip Gladstone
- * Created file with time related functions from sched.c and adjtimex()
+ * Created file with time related functions from sched/core.c and adjtimex()
* 1993-10-08 Torsten Duwe
* adjtime interface update and CMOS clock write code
* 1995-08-13 Torsten Duwe
diff --git a/kernel/workqueue_internal.h b/kernel/workqueue_internal.h
index ad83c96..7e2204d 100644
--- a/kernel/workqueue_internal.h
+++ b/kernel/workqueue_internal.h
@@ -64,7 +64,7 @@ static inline struct worker *current_wq_worker(void)
/*
* Scheduler hooks for concurrency managed workqueue. Only to be used from
- * sched.c and workqueue.c.
+ * sched/core.c and workqueue.c.
*/
void wq_worker_waking_up(struct task_struct *task, int cpu);
struct task_struct *wq_worker_sleeping(struct task_struct *task, int cpu);
--
1.7.12.rc2.18.g61b472e
I have faced a sequence where the Idle Load Balance was sometime not
triggered for a while on my platform.
CPU 0 and CPU 1 are running tasks and CPU 2 is idle
CPU 1 kicks the Idle Load Balance
CPU 1 selects CPU 2 as the new Idle Load Balancer
CPU 2 sets NOHZ_BALANCE_KICK for CPU 2
CPU 2 sends a reschedule IPI to CPU 2
While CPU 3 wakes up, CPU 0 or CPU 1 migrates a waking up task A on CPU 2
CPU 2 finally wakes up, runs task A and discards the Idle Load Balance
task A quickly goes back to sleep (before a tick occurs on CPU 2)
CPU 2 goes back to idle with NOHZ_BALANCE_KICK set
Whenever CPU 2 will be selected as the ILB, no reschedule IPI will be sent
because NOHZ_BALANCE_KICK is already set and no Idle Load Balance will be
performed.
We must wait for the sched softirq to be raised on CPU 2 thanks to another
part the kernel to come back to clear NOHZ_BALANCE_KICK.
The proposed solution clears NOHZ_BALANCE_KICK in schedule_ipi if
we can't raise the sched_softirq for the Idle Load Balance.
Change since V1:
- move the clear of NOHZ_BALANCE_KICK in got_nohz_idle_kick if the ILB
can't run on this CPU (as suggested by Peter)
Signed-off-by: Vincent Guittot <vincent.guittot(a)linaro.org>
---
kernel/sched/core.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 58453b8..919bee6 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -633,7 +633,19 @@ void wake_up_nohz_cpu(int cpu)
static inline bool got_nohz_idle_kick(void)
{
int cpu = smp_processor_id();
- return idle_cpu(cpu) && test_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu));
+
+ if (!test_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu)))
+ return false;
+
+ if (idle_cpu(cpu) && !need_resched())
+ return true;
+
+ /*
+ * We can't run Idle Load Balance on this CPU for this time so we
+ * cancel it and clear NOHZ_BALANCE_KICK
+ */
+ clear_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu));
+ return false;
}
#else /* CONFIG_NO_HZ_COMMON */
@@ -1393,8 +1405,9 @@ static void sched_ttwu_pending(void)
void scheduler_ipi(void)
{
- if (llist_empty(&this_rq()->wake_list) && !got_nohz_idle_kick()
- && !tick_nohz_full_cpu(smp_processor_id()))
+ if (llist_empty(&this_rq()->wake_list)
+ && !tick_nohz_full_cpu(smp_processor_id())
+ && !got_nohz_idle_kick())
return;
/*
@@ -1417,7 +1430,7 @@ void scheduler_ipi(void)
/*
* Check if someone kicked us for doing the nohz idle load balance.
*/
- if (unlikely(got_nohz_idle_kick() && !need_resched())) {
+ if (unlikely(got_nohz_idle_kick())) {
this_rq()->idle_balance = 1;
raise_softirq_irqoff(SCHED_SOFTIRQ);
}
--
1.7.9.5
On 5 June 2013 08:54, Xiaoguang Chen <chenxg.marvell(a)gmail.com> wrote:
> Hi, Guys
Hi Xiaoguang,
> I met another question for cpufreq governor. When hotplug out one cpu,
> cpufreq will remove the cpu device and also call governor stop, if
> there are more than 1 cpu and cpu0 is the root for cpufreq, other cpus
> are linked to cpu0. then policy->cpu is 0 always.
Not really.. There are situations when this will not hold true..
If you hot-unplug cpu0, then next cpu in line, i.e. cpu 1, will become
policy->cpu :)
> in userspace governor, when governor stop is called, it will set
> per_cpu(cpu_is_managed, cpu) = 0
To make it clear, cpu_is_managed isn't telling which cpu is managing
'cpu' but if governor is enabled for cpu 'cpu' or not.
> but the cpu is policy->cpu which is 0 always.
>
> case CPUFREQ_GOV_STOP:
> mutex_lock(&userspace_mutex);
> cpus_using_userspace_governor--;
> if (cpus_using_userspace_governor == 0) {
> cpufreq_unregister_notifier(
> &userspace_cpufreq_notifier_block,
> CPUFREQ_TRANSITION_NOTIFIER);
> }
>
> per_cpu(cpu_is_managed, cpu) = 0;
> per_cpu(cpu_min_freq, cpu) = 0;
> per_cpu(cpu_max_freq, cpu) = 0;
> per_cpu(cpu_set_freq, cpu) = 0;
> pr_debug("managing cpu %u stopped\n", cpu);
> mutex_unlock(&userspace_mutex);
> break;
>
>
> also in userspace governor store_setspeed function cpufreq_set will
> retun error if per_cpu(cpu_is_managed, cpu) is 0 which means it will
> not change frequency .
>
> static int cpufreq_set(struct cpufreq_policy *policy, unsigned int freq)
> {
> int ret = -EINVAL;
>
> pr_debug("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq);
>
> mutex_lock(&userspace_mutex);
> if (!per_cpu(cpu_is_managed, policy->cpu))
> goto err;
>
> per_cpu(cpu_set_freq, policy->cpu) = freq;
> ...........
>
>
>
> So consider below case:
> 1) cpu0 tries to hotplug cpu3, it calls userspace governor stop
> function, it should stop cpu3's userspace governor, but it actually
> set cpu0's per_cpu(cpu_is_managed, cpu) to 0.
> 2) cpu0 tries to change cpu freuqency through userspace governor, but
> it will never succeed since cpufreq_set will return err if cpu0'
> percpu variable cpu_is_managed is 0.
> 3) unless there is another cpu hotplug in operation, in which it calls
> governor start and set cpu_is_managed to 1, then the frequency change
> will go on and doesn't report error.
>
> The reason here is policy->cpu is always 0 if we use managed policy
> for all cpus. but we can't see which cpu's governor want's to
> start/stop in userspace goveror. we can only get the information from
> struct policy, but this policy doesn't include the exact cpu that
> wants to do governor start/stop.
>
>
> Any suggestions for this issue?
Hmm.. the problem is bigger than what you observed..
I am starting to cleanup userspace governor now and will cc you
for my patches. Please test them and give your Tested-by :)
Hi Ard!
As we've discussed today in IRC I'm sending you my asm based implementation for
RAID syndrome functions. I would be glad if you can compare this implementation
to intrinsics based one you are currently working on.
I don't post here my code for VFP/NEON context save/restore. People who are
interested may find patches developed by Ard on [1]. However, I'm using "fpu"
notation in these patches. Therefore, some changes to vfp/neon might be
necessary to make things working.
[1] https://patchwork.kernel.org/patch/2605041/
Thanks!
Vladimir Murzin
Each governor is suitable for different kernel configurations: the menu
governor suits better for a tickless system, while the ladder governor fits
better for a periodic timer tick system.
The Kconfig does not allow to [un]select a governor, thus both are compiled in
the kernel but the init order makes the menu governor to be the last one to be
registered, so becoming the default. The only way to switch back to the ladder
governor is to enable the sysfs governor switch in the kernel command line.
Because it seems nobody complained about this, the menu governor is used by
default most of the time on the system, having both governors is not really
necessary on a tickless system but there isn't a config option to disable one
or another governor.
Create a submenu for cpuidle and add a label for each governor, so we can see
the option in the menu config and enable/disable it.
The governors will be enabled depending on the CONFIG_NO_HZ option:
- If CONFIG_NO_HZ is set, then the menu governor is selected and the ladder
governor is optional, defaulting to 'yes'
- If CONFIG_NO_HZ is not set, then the ladder governor is selected and the
menu governor is optional, defaulting to 'yes'
Before this patch, the ARCH_NEEDS_CPU_IDLE_COUPLED option was wrongly not
depending on the CPU_IDLE and the Kconfig for OMAP / TEGRA was not checking
this dependency when setting the option.
With this patch, the ARCH_NEEDS_CPU_IDLE_COUPLED has been moved under the
CPU_IDLE option. The dependency has been fixed in the relevant arch's Kconfig.
Signed-off-by: Daniel Lezcano <daniel.lezcano(a)linaro.org>
---
V3:
- Fixed Kconfig dependency between CPU_IDLE and ARCH_NEEDS_CPU_IDLE_COUPLED
V2:
- Set default values to 'yes' for the governors
arch/arm/mach-omap2/Kconfig | 2 +-
arch/arm/mach-tegra/Kconfig | 2 +-
drivers/cpuidle/Kconfig | 16 +++++++---------
3 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index f49cd51..831e89e 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -83,7 +83,7 @@ config ARCH_OMAP4
depends on ARCH_OMAP2PLUS
depends on ARCH_MULTI_V7
select ARCH_HAS_OPP
- select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
+ select ARCH_NEEDS_CPU_IDLE_COUPLED if (SMP && CPU_IDLE)
select ARM_CPU_SUSPEND if PM
select ARM_ERRATA_720789
select ARM_GIC
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 84d72fc..04c6221 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -23,7 +23,7 @@ menu "NVIDIA Tegra options"
config ARCH_TEGRA_2x_SOC
bool "Enable support for Tegra20 family"
- select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
+ select ARCH_NEEDS_CPU_IDLE_COUPLED if (SMP && CPU_IDLE)
select ARM_ERRATA_720789
select ARM_ERRATA_754327 if SMP
select ARM_ERRATA_764369 if SMP
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index c4cc27e..e997f15 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -1,7 +1,9 @@
-config CPU_IDLE
+menuconfig CPU_IDLE
bool "CPU idle PM support"
default y if ACPI || PPC_PSERIES
+ select CPU_IDLE_GOV_LADDER if (!NO_HZ && !NO_HZ_IDLE)
+ select CPU_IDLE_GOV_MENU if (NO_HZ || NO_HZ_IDLE)
help
CPU idle is a generic framework for supporting software-controlled
idle processor power management. It includes modular cross-platform
@@ -9,9 +11,10 @@ config CPU_IDLE
If you're using an ACPI-enabled platform, you should say Y here.
+if CPU_IDLE
+
config CPU_IDLE_MULTIPLE_DRIVERS
bool "Support multiple cpuidle drivers"
- depends on CPU_IDLE
default n
help
Allows the cpuidle framework to use different drivers for each CPU.
@@ -19,24 +22,19 @@ config CPU_IDLE_MULTIPLE_DRIVERS
states. If unsure say N.
config CPU_IDLE_GOV_LADDER
- bool
- depends on CPU_IDLE
+ bool "Ladder governor (for periodic timer tick)"
default y
config CPU_IDLE_GOV_MENU
- bool
- depends on CPU_IDLE && NO_HZ
+ bool "Menu governor (for tickless system)"
default y
config ARCH_NEEDS_CPU_IDLE_COUPLED
def_bool n
-if CPU_IDLE
-
config CPU_IDLE_CALXEDA
bool "CPU Idle Driver for Calxeda processors"
depends on ARCH_HIGHBANK
help
Select this to enable cpuidle on Calxeda processors.
-
endif
--
1.7.9.5
It seems I had to install more recent linaro image tools in order to
create a 13.05 SD card. Based on previous experience this was not a
complete surprise, but I had issues making linaro-media-create work on
my 12.04 system. After upgrading to 13.04 I found I had issues getting
the image tools to reinstall. Has anyone else run into this? Sorry for
not being more specific, but it was quite a bit of flailing before I got
back to something I could use.
Thanks,
-dl
=== Highlights ===
* Monday holiday! Took my first day off this year! :P
* Queued a bunch of community timekeeping patches for 3.10 and 3.11
* Sent my 3.10 queue to Thomas
* Lots of back and forth discussion on some community Xen patches
* Spent some time chasing a reported timekeeping regression in 3.9.4
* Reviewed Kahsim's slides and provided feedback, attended hangout for
more feedback.
* Reviewed blueprints and sent out weekly android upstreaming mail
* Worked a bit with DanielL on ramping up for drivers/clocksource timer
sub-maintainership
* Covered some linux-linaro process questions w/ MarkH
* Synced up with Deepak
=== Plans ===
* Send my 3.11 queue to tglx
* Probably handle a few remaining community items (Xen patches, 3.9.4
regression)
* Respond to Arnd's review of the ION patch & try to take some of the
issues to Rebecca
* Get back to Minchan on some of his private volatile range questions
* Start looking into generic sched_clock work being done in the community
=== Issues ===
* N/A
== Linus Walleij linusw ==
=== Highlights ===
* Collected and prepared a set of new GPIO patches
targeted at v3.11, handshake with Grant on IRC.
* Continued to apply DMA40 patches from Lee on a
specific DMA40 branch targeted for ARM SoC. The first
batch of patches has been pulled into ARM SoC and
we're now waiting for some final ACKs from Vinod on
the remaining patches.
* Applied and queued various ux500 patches, including
a patch I prepared for abx500 pinctrl tables. I now have
these pending ux500 branches:
ux500-core
ux500-defconfig
ux500-devicetree
ux500-dma40
ux500-fixes
ux500-pinctrl
ux500-fixes will be send to ARM SoC ASAP, ux500-dma40
is partly landed in ARM SoC (for v3.11) and the rest remain
to be funneled when stabilized.
* Reviewed lots of pinctrl and GPIO code. Much time has
been spent on DT issues.
* Discussed at length about the option to create generic
DT bindings and DT parsing code for the pinconf-generic
consumers so we do not need to replicate this in all
pinctrl drivers using the generic pinconf library.
* Iterated the U300 device tree + multiplatform patch
series. Arnd has some final comments so we'll iterate
it some more.
* Nomadik DT clocks and some more Nomadik changes
like DT pinctrl were pulled into ARM SoC.
* Ethernet fix for the Nomadik S8815 is upstream.
* Tested an IRQ branch from Grant on the Integrator/AP.
=== Plans ===
* Finalize U300 DT+multiplatform patch set.
* Integrate Integrator PCI patch set, then start to delete
board files and convert to multiplatform.
* Convert Nomadik pinctrl driver to register GPIO ranges
from the gpiochip side.
* Test the PL08x patches on the Ericsson Research
PB11MPCore and submit platform data for using
pl08x DMA on that platform.
* Get hands dirty with regmap.
=== Issues ===
* Subsystem maintainers in the kernel community are forced
to act as standardization comittee for device tree bindings
due to lack of review power. As they have to merge the
bindings in the end, reviewing fall upward to the subsystem
maintainers, this is something of a workload issue.
* Need a PCI branch at ARM SoC to request Integrator PCI
DT patches to be pulled into. (Still blocked on this for
Integrator single zImage.)
* Some impediments from internal turmoil @ST-Ericsson.
Thanks,
Linus Walleij
This patch series adds support for DP on Exynos5250 based Arndale Board
changes since v1:
- moved display-timimg node inside fimd DT node as suggested by
Steffen Trumtrar s.trumtrar(a)pengutronix.de
Is based on branch "for-next"
http://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
Vikas Sajjan (3):
ARM: dts: Add DT node for DP controller for Arndale Board
ARM: dts: Add clock provider information for DP controller in
Exynos5250 SoC
ARM: dts: Add display timing node to exynos5250-arndale.dts
arch/arm/boot/dts/exynos5250-arndale.dts | 28 ++++++++++++++++++++++++++++
arch/arm/boot/dts/exynos5250.dtsi | 2 ++
2 files changed, 30 insertions(+)
--
1.7.9.5
The governors are defined as module in the code, but the Kconfig options do not
allow to compile them as module. This is not really a problem but the init
order is: the cpuidle init functions (framework and driver) and then the
governors. That leads to some weirdness in the cpuidle framework because the
function cpuidle_register_device calls cpuidle_enable_device which in turns
fails at the first attempt because no governor is registered. When the
governor is registered, the framework calls cpuidle_enable_device again which
will invoke the __cpuidle_register_device function. Of course, in order to make
this to work, the return code of cpuidle_enable_device is not checked by the
caller in cpuidle_register_device.
Instead of having this cyclic call graph and relying on a positive side effect
of the hackish back and forth call to cpuidle_enable_device, let's change the
init order for the governor in order to clean up the cpuidle_enable_device
function.
Signed-off-by: Daniel Lezcano <daniel.lezcano(a)linaro.org>
---
drivers/cpuidle/Makefile | 2 +-
drivers/cpuidle/governors/ladder.c | 14 ++------------
drivers/cpuidle/governors/menu.c | 14 ++------------
3 files changed, 5 insertions(+), 25 deletions(-)
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 0d8bd55..05e2035 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -2,7 +2,7 @@
# Makefile for cpuidle.
#
-obj-y += cpuidle.o driver.o governor.o sysfs.o governors/
+obj-y += governors/ cpuidle.o driver.o governor.o sysfs.o
obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o
diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c
index 9b78405..928dc59 100644
--- a/drivers/cpuidle/governors/ladder.c
+++ b/drivers/cpuidle/governors/ladder.c
@@ -187,19 +187,9 @@ static struct cpuidle_governor ladder_governor = {
/**
* init_ladder - initializes the governor
*/
-static int __init init_ladder(void)
+static int __init ladder_init(void)
{
return cpuidle_register_governor(&ladder_governor);
}
-/**
- * exit_ladder - exits the governor
- */
-static void __exit exit_ladder(void)
-{
- cpuidle_unregister_governor(&ladder_governor);
-}
-
-MODULE_LICENSE("GPL");
-module_init(init_ladder);
-module_exit(exit_ladder);
+core_initcall(ladder_init);
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index fe343a0..483bac1 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -535,19 +535,9 @@ static struct cpuidle_governor menu_governor = {
/**
* init_menu - initializes the governor
*/
-static int __init init_menu(void)
+static int __init menu_init(void)
{
return cpuidle_register_governor(&menu_governor);
}
-/**
- * exit_menu - exits the governor
- */
-static void __exit exit_menu(void)
-{
- cpuidle_unregister_governor(&menu_governor);
-}
-
-MODULE_LICENSE("GPL");
-module_init(init_menu);
-module_exit(exit_menu);
+core_initcall(menu_init);
--
1.7.9.5
To reduce cpufreq maintenance load on Rafael, ARM specific patches would be
Applied by me now. Rafael will pull in these changes from time to time (at
rc's). Additionally I would be sending him pull request for every merge window
and rc's (for fixes).
Web interface of my tree is present here:
https://git.linaro.org/gitweb?p=people/vireshk/linux.git;a=summary
Branch names would be: cpufreq-next and cpufreq-fixes.
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
---
MAINTAINERS | 1 +
1 file changed, 1 insertion(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index fd3a495..50c81bd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2216,6 +2216,7 @@ L: cpufreq(a)vger.kernel.org
L: linux-pm(a)vger.kernel.org
S: Maintained
T: git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git
+T: git://git.linaro.org/people/vireshk/linux.git (For ARM Updates)
F: drivers/cpufreq/
F: include/linux/cpufreq.h
--
1.7.12.rc2.18.g61b472e
In commit 0377b5acba2 (ACPICA: Merge all debug output macros into
a single file, acoutput.), the patch introduces redundant macro
defines for ACPI_DEBUG_PRINT() and ACPI_DEBUG_PRINT_RAW(), just
remove it.
Signed-off-by: Hanjun Guo <hanjun.guo(a)linaro.org>
---
include/acpi/acoutput.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/include/acpi/acoutput.h b/include/acpi/acoutput.h
index 4f52ea7..e1c7474 100644
--- a/include/acpi/acoutput.h
+++ b/include/acpi/acoutput.h
@@ -447,8 +447,6 @@
#define ACPI_DUMP_TABLES(a, b)
#define ACPI_DUMP_PATHNAME(a, b, c, d)
#define ACPI_DUMP_BUFFER(a, b)
-#define ACPI_DEBUG_PRINT(pl)
-#define ACPI_DEBUG_PRINT_RAW(pl)
#define ACPI_IS_DEBUG_ENABLED(level, component) 0
/* Return macros must have a return statement at the minimum */
-- 1.8.2.1