[PATCH] PM-QA: remove obsolete test scripts
From: Rajagopal Venkat The updated version of these test scripts are available in their respective directories. Signed-off-by: Rajagopal Venkat --- run_template |7 -- testcases.awk | 40 -- testcases/Makefile| 39 -- testcases/cpufreq/Makefile| 31 testcases/cpufreq/avail_freq01.sh | 56 -- testcases/cpufreq/avail_freq02.sh | 68 testcases/cpufreq/avail_gov01.sh | 45 --- testcases/cpufreq/avail_gov02.sh | 48 testcases/cpuhotplug/Makefile | 32 testcases/cpuhotplug/cpu_hotplug_latency.sh | 88 - testcases/cpuidle/Makefile| 34 testcases/cpuidle/test_usb_cpuidle.c | 102 - testcases/proof_o_concept/Makefile| 31 testcases/proof_o_concept/PM-list_c_states.sh | 36 - testcases/proof_o_concept/PM-list_p_states.sh | 32 15 files changed, 0 insertions(+), 689 deletions(-) delete mode 100644 run_template delete mode 100644 testcases.awk delete mode 100644 testcases/Makefile delete mode 100644 testcases/cpufreq/Makefile delete mode 100755 testcases/cpufreq/avail_freq01.sh delete mode 100755 testcases/cpufreq/avail_freq02.sh delete mode 100755 testcases/cpufreq/avail_gov01.sh delete mode 100755 testcases/cpufreq/avail_gov02.sh delete mode 100644 testcases/cpuhotplug/Makefile delete mode 100755 testcases/cpuhotplug/cpu_hotplug_latency.sh delete mode 100644 testcases/cpuidle/Makefile delete mode 100644 testcases/cpuidle/test_usb_cpuidle.c delete mode 100644 testcases/proof_o_concept/Makefile delete mode 100755 testcases/proof_o_concept/PM-list_c_states.sh delete mode 100755 testcases/proof_o_concept/PM-list_p_states.sh diff --git a/run_template b/run_template deleted file mode 100644 index 8c866f9..000 --- a/run_template +++ /dev/null @@ -1,7 +0,0 @@ -pm-qa-cexists proof_o_concept PM-list_c_states.sh -pm-qa-pexists proof_o_concept PM-list_p_states.sh -pm-qa-availfreq01 cpufreq avail_freq01.sh -pm-qa-availfreq02 cpufreq avail_freq02.sh -pm-qa-availgov01 cpufreq avail_gov01.sh -pm-qa-availgov02 cpufreq avail_gov02.sh -pm-qa-cpuidle cpuidle test_usb_cpuidle /dev/sdb 5 1 diff --git a/testcases.awk b/testcases.awk deleted file mode 100644 index 71ce9ee..000 --- a/testcases.awk +++ /dev/null @@ -1,40 +0,0 @@ -# -# PM-QA validation test suite for the power management on Linux -# -# Copyright (C) 2011, Linaro Limited. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# Contributors: -# Torez Smith (IBM Corporation) -# - initial API and implementation -# - -### - # For a series of power management related test, cycle through and - # execute. Each test to be executed is in file testcases where the - # following columns make sense - # column 1: name of the test case - # column 2: sub directory housing the test - # column 3: name of file for the test case - # column 4: from column 4 onwards, any arguments to pass on to the test -### -{ - printf $1 ":" - cmd = "cd ./testcases/"$2 " ; sudo ./"$3 " " substr($0, length($1 $2 $3) +4) - system(cmd) - printf "\n" -} - diff --git a/testcases/Makefile b/testcases/Makefile deleted file mode 100644 index 08b3233..000 --- a/testcases/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -# -# PM-QA validation test suite for the power management on Linux -# -# Copyright (C) 2011, Linaro Limited. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program
[Powertop][PATCH] fix cpuidle state name parsing
parse cpuidle C state based on sysfs file entry(stateX) instead of state name/description Signed-off-by: Rajagopal Venkat --- src/cpu/abstract_cpu.cpp |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/abstract_cpu.cpp b/src/cpu/abstract_cpu.cpp index cd4eba0..72969fc 100644 --- a/src/cpu/abstract_cpu.cpp +++ b/src/cpu/abstract_cpu.cpp @@ -147,7 +147,7 @@ void abstract_cpu::insert_cstate(const char *linux_name, const char *human_name, strcpy(state->linux_name, linux_name); strcpy(state->human_name, human_name); - c = human_name; + c = linux_name; while (*c) { if (strcmp(linux_name, "active")==0) { state->line_level = LEVEL_C0; -- 1.7.9.5 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[Powertop][PATCH] conditionally disable pci support on ARM platforms
Signed-off-by: Rajagopal Venkat --- configure.ac | 16 +--- src/lib.cpp | 20 ++-- src/lib.h|4 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 4da4eea..c2ff430 100644 --- a/configure.ac +++ b/configure.ac @@ -22,6 +22,8 @@ AC_PROG_LIBTOOL AC_PROG_CC AC_PROG_INSTALL AM_PROG_CC_C_O +AC_CANONICAL_HOST +PKG_PROG_PKG_CONFIG # Checks for libraries. # Checks for header files. @@ -47,9 +49,17 @@ AC_CHECK_FUNCS([fdatasync getpagesize gettimeofday memmove memset mkdir munmap p AC_SEARCH_LIBS([delwin], [ncursesw ncurses], [], AC_MSG_ERROR([ncurses is required but was not found]), []) -PKG_CHECK_MODULES([PCIUTILS], [libpci],[],[ - AC_SEARCH_LIBS([pci_get_dev], [pci], [], AC_MSG_ERROR([libpci is required but was not found]), []) -]) +case "$host" in +arm*) + AC_DEFINE([HAVE_NO_PCI],[1],[Define if host platform is ARM]) + ;; +*) + PKG_CHECK_MODULES([PCIUTILS], [libpci],[],[ + AC_SEARCH_LIBS([pci_get_dev], [pci], [], AC_MSG_ERROR([libpci is required but was not found]), []) + ]) + ;; +esac + PKG_CHECK_MODULES([LIBZ], [zlib],[],[ AC_SEARCH_LIBS([deflate], [z], [], AC_MSG_ERROR([zlib is required but was not found]), []) ]) diff --git a/src/lib.cpp b/src/lib.cpp index 0f87e48..77e49a2 100644 --- a/src/lib.cpp +++ b/src/lib.cpp @@ -35,11 +35,13 @@ #include #include +#include "lib.h" + +#ifndef HAVE_NO_PCI extern "C" { #include } - -#include "lib.h" +#endif #include #include @@ -266,6 +268,7 @@ void format_watts(double W, char *buffer, unsigned int len) } +#ifndef HAVE_NO_PCI static struct pci_access *pci_access; char *pci_id_to_name(uint16_t vendor, uint16_t device, char *buffer, int len) @@ -290,6 +293,19 @@ void end_pci_access(void) pci_free_name_list(pci_access); } +#else + +char *pci_id_to_name(uint16_t vendor, uint16_t device, char *buffer, int len) +{ + return NULL; +} + +void end_pci_access(void) +{ +} + +#endif /* HAVE_NO_PCI */ + int utf_ok = -1; diff --git a/src/lib.h b/src/lib.h index 588c023..d354151 100644 --- a/src/lib.h +++ b/src/lib.h @@ -30,6 +30,10 @@ #endif #include +#if HAVE_CONFIG_H +#include "config.h" +#endif + #ifndef DISABLE_I18N #define _(STRING)gettext(STRING) #else -- 1.7.9.5 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [Powertop] [PATCH] conditionally disable pci support on ARM platforms
On 23 June 2012 01:31, Arjan van de Ven wrote: > On 6/22/2012 11:42 AM, Rajagopal Venkat wrote: > > +case "$host" in > > +arm*) > > + AC_DEFINE([HAVE_NO_PCI],[1],[Define if host platform is ARM]) > > + ;; > > +*) > > + PKG_CHECK_MODULES([PCIUTILS], [libpci],[],[ > > + AC_SEARCH_LIBS([pci_get_dev], [pci], [], > AC_MSG_ERROR([libpci is required but was not found]), []) > > + ]) > > + ;; > > +esac > > + > > I don't like this part. > > if libpci is option, it is optional. > > Agree. libpci should be optional. At present build script is enforcing to install libpci which may not be necessarily true for all platforms. Solution can be something like, PKG_CHECK_MODULES([PCIUTILS], [libpci],[],[ AC_SEARCH_LIBS([pci_get_dev], [pci], [], [AC_DEFINE([HAVE_NO_PCI],[1],[Define if pci is not supported])], []) ]) > being arm or not is completely irrelevant in this regard. > (and there will undoubtedly ARM systems at some point that will have PCI > in them) > > > ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[Powertop][PATCH v2] conditionally disable pci if not supported
Signed-off-by: Rajagopal Venkat --- configure.ac |5 +++-- src/lib.cpp | 20 ++-- src/lib.h|4 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 4da4eea..3cbc7b0 100644 --- a/configure.ac +++ b/configure.ac @@ -48,8 +48,9 @@ AC_CHECK_FUNCS([fdatasync getpagesize gettimeofday memmove memset mkdir munmap p AC_SEARCH_LIBS([delwin], [ncursesw ncurses], [], AC_MSG_ERROR([ncurses is required but was not found]), []) PKG_CHECK_MODULES([PCIUTILS], [libpci],[],[ - AC_SEARCH_LIBS([pci_get_dev], [pci], [], AC_MSG_ERROR([libpci is required but was not found]), []) -]) + AC_SEARCH_LIBS([pci_get_dev], [pci], [], AC_DEFINE([HAVE_NO_PCI],[1],[Define if pci is not supported]), []) +]) + PKG_CHECK_MODULES([LIBZ], [zlib],[],[ AC_SEARCH_LIBS([deflate], [z], [], AC_MSG_ERROR([zlib is required but was not found]), []) ]) diff --git a/src/lib.cpp b/src/lib.cpp index 0f87e48..77e49a2 100644 --- a/src/lib.cpp +++ b/src/lib.cpp @@ -35,11 +35,13 @@ #include #include +#include "lib.h" + +#ifndef HAVE_NO_PCI extern "C" { #include } - -#include "lib.h" +#endif #include #include @@ -266,6 +268,7 @@ void format_watts(double W, char *buffer, unsigned int len) } +#ifndef HAVE_NO_PCI static struct pci_access *pci_access; char *pci_id_to_name(uint16_t vendor, uint16_t device, char *buffer, int len) @@ -290,6 +293,19 @@ void end_pci_access(void) pci_free_name_list(pci_access); } +#else + +char *pci_id_to_name(uint16_t vendor, uint16_t device, char *buffer, int len) +{ + return NULL; +} + +void end_pci_access(void) +{ +} + +#endif /* HAVE_NO_PCI */ + int utf_ok = -1; diff --git a/src/lib.h b/src/lib.h index 588c023..d354151 100644 --- a/src/lib.h +++ b/src/lib.h @@ -30,6 +30,10 @@ #endif #include +#if HAVE_CONFIG_H +#include "config.h" +#endif + #ifndef DISABLE_I18N #define _(STRING)gettext(STRING) #else -- 1.7.9.5 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [Powertop] [PATCH v2] conditionally disable pci if not supported
On 25 June 2012 21:34, Arjan van de Ven wrote: > On 6/25/2012 9:00 AM, Rajagopal Venkat wrote: > > > > Ok. Taken care. > > > > > diff --git a/src/lib.h b/src/lib.h > > index 588c023..d354151 100644 > > --- a/src/lib.h > > +++ b/src/lib.h > > @@ -30,6 +30,10 @@ > > #endif > > #include > > > > +#if HAVE_CONFIG_H > > +#include "config.h" > > +#endif > > + > > #ifndef DISABLE_I18N > > #define _(STRING)gettext(STRING) > > #else > > > > > > ok this chunk I do not understand; > the rest of your patch looks very reasonable. > why is config.h inside an if ? > config.h is auto generated by autoconf and is not applicable for Android build. Yes. it should be wrapped in ifdef. ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[Powertop][PATCH v3] conditionally disable pci if not supported
disable pci if not supported by host platform. When libpci is not found, define a macro which will be used for conditional compilation. Signed-off-by: Rajagopal Venkat --- configure.ac |5 +++-- src/lib.cpp | 20 ++-- src/lib.h|5 + 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 4da4eea..3cbc7b0 100644 --- a/configure.ac +++ b/configure.ac @@ -48,8 +48,9 @@ AC_CHECK_FUNCS([fdatasync getpagesize gettimeofday memmove memset mkdir munmap p AC_SEARCH_LIBS([delwin], [ncursesw ncurses], [], AC_MSG_ERROR([ncurses is required but was not found]), []) PKG_CHECK_MODULES([PCIUTILS], [libpci],[],[ - AC_SEARCH_LIBS([pci_get_dev], [pci], [], AC_MSG_ERROR([libpci is required but was not found]), []) -]) + AC_SEARCH_LIBS([pci_get_dev], [pci], [], AC_DEFINE([HAVE_NO_PCI],[1],[Define if pci is not supported]), []) +]) + PKG_CHECK_MODULES([LIBZ], [zlib],[],[ AC_SEARCH_LIBS([deflate], [z], [], AC_MSG_ERROR([zlib is required but was not found]), []) ]) diff --git a/src/lib.cpp b/src/lib.cpp index 0f87e48..77e49a2 100644 --- a/src/lib.cpp +++ b/src/lib.cpp @@ -35,11 +35,13 @@ #include #include +#include "lib.h" + +#ifndef HAVE_NO_PCI extern "C" { #include } - -#include "lib.h" +#endif #include #include @@ -266,6 +268,7 @@ void format_watts(double W, char *buffer, unsigned int len) } +#ifndef HAVE_NO_PCI static struct pci_access *pci_access; char *pci_id_to_name(uint16_t vendor, uint16_t device, char *buffer, int len) @@ -290,6 +293,19 @@ void end_pci_access(void) pci_free_name_list(pci_access); } +#else + +char *pci_id_to_name(uint16_t vendor, uint16_t device, char *buffer, int len) +{ + return NULL; +} + +void end_pci_access(void) +{ +} + +#endif /* HAVE_NO_PCI */ + int utf_ok = -1; diff --git a/src/lib.h b/src/lib.h index 588c023..7093b7f 100644 --- a/src/lib.h +++ b/src/lib.h @@ -30,6 +30,11 @@ #endif #include +/* Include only for Automake builds */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #ifndef DISABLE_I18N #define _(STRING)gettext(STRING) #else -- 1.7.9.5 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH] pm-qa: run sanity check before running test cases
From: root run sanity test for each functionality if present. If functionality enabled, then run all respective test cases. This patch also adds sanity checks for cpuidle and sched_mc. Signed-off-by: Rajagopal Venkat --- Test.mk| 17 ++--- cpuidle/cpuidle_sanity.sh | 35 +++ cpuidle/cpuidle_sanity.txt |1 + sched_mc/sched_sanity.sh | 35 +++ sched_mc/sched_sanity.txt |1 + 5 files changed, 86 insertions(+), 3 deletions(-) create mode 100755 cpuidle/cpuidle_sanity.sh create mode 100644 cpuidle/cpuidle_sanity.txt create mode 100755 sched_mc/sched_sanity.sh create mode 100644 sched_mc/sched_sanity.txt diff --git a/Test.mk b/Test.mk index 1d69d7a..76f79b5 100644 --- a/Test.mk +++ b/Test.mk @@ -21,15 +21,22 @@ # Daniel Lezcano (IBM Corporation) # - initial API and implementation # - -TST=$(wildcard *.sh) +SNT=$(wildcard *sanity.sh) +TST=$(wildcard *[^(sanity)].sh) LOG=$(TST:.sh=.log) CFLAGS?=-g -Wall -pthread CC?=gcc SRC=$(wildcard *.c) EXEC=$(SRC:%.c=%) -check: uncheck $(EXEC) $(LOG) +check: run_tests + +SANITY_STATUS:= $(shell if test $(SNT) && test -f $(SNT); then \ + ./$(SNT); if test "$$?" -eq 0; then echo 0; else \ + echo 1; fi; else echo 1; fi) + +ifeq "$(SANITY_STATUS)" "1" +run_tests: uncheck $(EXEC) $(LOG) %.log: %.sh @echo "###" @@ -38,6 +45,10 @@ check: uncheck $(EXEC) $(LOG) @echo -n "### "; grep "URL :" ./$< | awk '/http/{print $$NF}' @echo "###" @./$< 2> $@ +else +run_tests: $(SNT) + @cat $(<:.sh=.txt) +endif clean: rm -f *.o $(EXEC) diff --git a/cpuidle/cpuidle_sanity.sh b/cpuidle/cpuidle_sanity.sh new file mode 100755 index 000..a8336fa --- /dev/null +++ b/cpuidle/cpuidle_sanity.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# +# PM-QA validation test suite for the power management on Linux +# +# Copyright (C) 2011, Linaro Limited. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Contributors: +# Rajagopal Venkat +# - initial API and implementation +# + +source ../include/functions.sh + +check_cpuidle_sysfs_entry() { + +local dirpath=$CPU_PATH/cpuidle + +test -d $dirpath && return 1 || return 0 +} + +check_cpuidle_sysfs_entry diff --git a/cpuidle/cpuidle_sanity.txt b/cpuidle/cpuidle_sanity.txt new file mode 100644 index 000..03d3f7c --- /dev/null +++ b/cpuidle/cpuidle_sanity.txt @@ -0,0 +1 @@ +cpuidle is not enabled. Skipping all cpudile tests... diff --git a/sched_mc/sched_sanity.sh b/sched_mc/sched_sanity.sh new file mode 100755 index 000..1b1b58b --- /dev/null +++ b/sched_mc/sched_sanity.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# +# PM-QA validation test suite for the power management on Linux +# +# Copyright (C) 2011, Linaro Limited. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Contributors: +# Daniel Lezcano (IBM Corporation) +# - initial API and implementation +# + +source ../include/functions.sh + +check_sched_mc_sysfs_entry() { + +local filepath=$CPU_PATH/sched_mc_power_savings + +test -f $filepath && return 1 || return 0 +} + +check_sched_mc_sysfs_entry diff --git a/sched_mc/sched_sanity.txt b/sched_mc/sched_sanity.txt new file mode 100644 index 000..c79c23e --- /dev/null +++ b/sched_mc/sched_sanity.txt @@ -0,0 +1 @@ +sched_mc is not enabled. Skipping all sched_mc tests... -- 1.7.9.5 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [PATCH] pm-qa: run sanity check before running test cases
On 2 July 2012 13:20, Hongbo Zhang wrote: > > > On 28 June 2012 00:55, Rajagopal Venkat wrote: > >> From: root >> > It seems that you did this work on the snowball. > the git is not completely configed? > > Yes. Thanks for pointing this out. I will submit the new patch. > run sanity test for each functionality if present. >> If functionality enabled, then run all respective >> test cases. This patch also adds sanity checks for >> cpuidle and sched_mc. >> >> Signed-off-by: Rajagopal Venkat >> --- >> Test.mk| 17 ++--- >> cpuidle/cpuidle_sanity.sh | 35 +++ >> cpuidle/cpuidle_sanity.txt |1 + >> sched_mc/sched_sanity.sh | 35 +++ >> sched_mc/sched_sanity.txt |1 + >> 5 files changed, 86 insertions(+), 3 deletions(-) >> create mode 100755 cpuidle/cpuidle_sanity.sh >> create mode 100644 cpuidle/cpuidle_sanity.txt >> create mode 100755 sched_mc/sched_sanity.sh >> create mode 100644 sched_mc/sched_sanity.txt >> >> diff --git a/Test.mk b/Test.mk >> index 1d69d7a..76f79b5 100644 >> --- a/Test.mk >> +++ b/Test.mk >> @@ -21,15 +21,22 @@ >> # Daniel Lezcano (IBM Corporation) >> # - initial API and implementation >> # >> - >> -TST=$(wildcard *.sh) >> +SNT=$(wildcard *sanity.sh) >> +TST=$(wildcard *[^(sanity)].sh) >> LOG=$(TST:.sh=.log) >> CFLAGS?=-g -Wall -pthread >> CC?=gcc >> SRC=$(wildcard *.c) >> EXEC=$(SRC:%.c=%) >> >> -check: uncheck $(EXEC) $(LOG) >> +check: run_tests >> + >> +SANITY_STATUS:= $(shell if test $(SNT) && test -f $(SNT); then \ >> + ./$(SNT); if test "$$?" -eq 0; then echo 0; else \ >> + echo 1; fi; else echo 1; fi) >> + >> +ifeq "$(SANITY_STATUS)" "1" >> +run_tests: uncheck $(EXEC) $(LOG) >> >> %.log: %.sh >> @echo "###" >> @@ -38,6 +45,10 @@ check: uncheck $(EXEC) $(LOG) >> @echo -n "### "; grep "URL :" ./$< | awk '/http/{print $$NF}' >> @echo "###" >> @./$< 2> $@ >> +else >> +run_tests: $(SNT) >> + @cat $(<:.sh=.txt) >> +endif >> >> clean: >> rm -f *.o $(EXEC) >> diff --git a/cpuidle/cpuidle_sanity.sh b/cpuidle/cpuidle_sanity.sh >> new file mode 100755 >> index 000..a8336fa >> --- /dev/null >> +++ b/cpuidle/cpuidle_sanity.sh >> @@ -0,0 +1,35 @@ >> +#!/bin/bash >> +# >> +# PM-QA validation test suite for the power management on Linux >> +# >> +# Copyright (C) 2011, Linaro Limited. >> +# >> +# This program is free software; you can redistribute it and/or >> +# modify it under the terms of the GNU General Public License >> +# as published by the Free Software Foundation; either version 2 >> +# of the License, or (at your option) any later version. >> +# >> +# This program is distributed in the hope that it will be useful, >> +# but WITHOUT ANY WARRANTY; without even the implied warranty of >> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> +# GNU General Public License for more details. >> +# >> +# You should have received a copy of the GNU General Public License >> +# along with this program; if not, write to the Free Software >> +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA >> 02110-1301, USA. >> +# >> +# Contributors: >> +# Rajagopal Venkat >> +# - initial API and implementation >> +# >> + >> +source ../include/functions.sh >> + >> +check_cpuidle_sysfs_entry() { >> + >> +local dirpath=$CPU_PATH/cpuidle >> + >> +test -d $dirpath && return 1 || return 0 >> +} >> + >> +check_cpuidle_sysfs_entry >> diff --git a/cpuidle/cpuidle_sanity.txt b/cpuidle/cpuidle_sanity.txt >> new file mode 100644 >> index 000..03d3f7c >> --- /dev/null >> +++ b/cpuidle/cpuidle_sanity.txt >> @@ -0,0 +1 @@ >> +cpuidle is not enabled. Skipping all cpudile tests... >> diff --git a/sched_mc/sched_sanity.sh b/sched_mc/sched_sanity.sh >> new file mode 100755 >> index 000..1b1b58b >> --- /dev/null >> +++ b/sched_mc/sched_sanity.sh >> @@ -0,0 +1,35 @@ >> +#!/bin/bash >> +# >> +# PM-QA validation test suite for the power management on Linux >> +# >> +# Copyright (C) 2011, Linaro Limited. >> +#
[PATCH v2] pm-qa: run sanity check before running test cases
run sanity test for each functionality if present. If functionality enabled, then run all respective test cases. This patch also adds sanity checks for cpuidle and sched_mc. Signed-off-by: Rajagopal Venkat --- Test.mk| 17 ++--- cpuidle/cpuidle_sanity.sh | 35 +++ cpuidle/cpuidle_sanity.txt |1 + sched_mc/sched_sanity.sh | 35 +++ sched_mc/sched_sanity.txt |1 + 5 files changed, 86 insertions(+), 3 deletions(-) create mode 100755 cpuidle/cpuidle_sanity.sh create mode 100644 cpuidle/cpuidle_sanity.txt create mode 100755 sched_mc/sched_sanity.sh create mode 100644 sched_mc/sched_sanity.txt diff --git a/Test.mk b/Test.mk index 1d69d7a..76f79b5 100644 --- a/Test.mk +++ b/Test.mk @@ -21,15 +21,22 @@ # Daniel Lezcano (IBM Corporation) # - initial API and implementation # - -TST=$(wildcard *.sh) +SNT=$(wildcard *sanity.sh) +TST=$(wildcard *[^(sanity)].sh) LOG=$(TST:.sh=.log) CFLAGS?=-g -Wall -pthread CC?=gcc SRC=$(wildcard *.c) EXEC=$(SRC:%.c=%) -check: uncheck $(EXEC) $(LOG) +check: run_tests + +SANITY_STATUS:= $(shell if test $(SNT) && test -f $(SNT); then \ + ./$(SNT); if test "$$?" -eq 0; then echo 0; else \ + echo 1; fi; else echo 1; fi) + +ifeq "$(SANITY_STATUS)" "1" +run_tests: uncheck $(EXEC) $(LOG) %.log: %.sh @echo "###" @@ -38,6 +45,10 @@ check: uncheck $(EXEC) $(LOG) @echo -n "### "; grep "URL :" ./$< | awk '/http/{print $$NF}' @echo "###" @./$< 2> $@ +else +run_tests: $(SNT) + @cat $(<:.sh=.txt) +endif clean: rm -f *.o $(EXEC) diff --git a/cpuidle/cpuidle_sanity.sh b/cpuidle/cpuidle_sanity.sh new file mode 100755 index 000..a8336fa --- /dev/null +++ b/cpuidle/cpuidle_sanity.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# +# PM-QA validation test suite for the power management on Linux +# +# Copyright (C) 2011, Linaro Limited. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Contributors: +# Rajagopal Venkat +# - initial API and implementation +# + +source ../include/functions.sh + +check_cpuidle_sysfs_entry() { + +local dirpath=$CPU_PATH/cpuidle + +test -d $dirpath && return 1 || return 0 +} + +check_cpuidle_sysfs_entry diff --git a/cpuidle/cpuidle_sanity.txt b/cpuidle/cpuidle_sanity.txt new file mode 100644 index 000..03d3f7c --- /dev/null +++ b/cpuidle/cpuidle_sanity.txt @@ -0,0 +1 @@ +cpuidle is not enabled. Skipping all cpudile tests... diff --git a/sched_mc/sched_sanity.sh b/sched_mc/sched_sanity.sh new file mode 100755 index 000..1b1b58b --- /dev/null +++ b/sched_mc/sched_sanity.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# +# PM-QA validation test suite for the power management on Linux +# +# Copyright (C) 2011, Linaro Limited. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Contributors: +# Daniel Lezcano (IBM Corporation) +# - initial API and implementation +# + +source ../include/functions.sh + +check_sched_mc_sysfs_entry() { + +local filepath=$CPU_PATH/sched_mc_power_savings + +test -f $filepath && return 1 || return 0 +} + +check_sched_mc_sysfs_entry diff --git a/sched_mc/sched_sanity.txt b/sched_mc/sched_sanity.txt new file mode 100644 index 000..c79c23e --- /dev/null +++ b/sched_mc/sched_sanity.txt @@ -0,0 +1 @@ +sched_mc is not enabled. Skipping all sched_mc tests... -- 1.7.9.5 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH] pm-qa: add powertop test cases
add powertop test cases into pm-qa. Run the powertop sanity test to check if tool is available. If yes, then run powertop in report generation mode and validate the output. Signed-off-by: Rajagopal Venkat --- Makefile |1 + powertop/Makefile| 25 ++ powertop/powertop_01.sh | 58 ++ powertop/powertop_01.txt |1 + powertop/powertop_sanity.sh | 35 + powertop/powertop_sanity.txt |1 + 6 files changed, 121 insertions(+) create mode 100644 powertop/Makefile create mode 100755 powertop/powertop_01.sh create mode 100644 powertop/powertop_01.txt create mode 100755 powertop/powertop_sanity.sh create mode 100644 powertop/powertop_sanity.txt diff --git a/Makefile b/Makefile index f85e5ac..1e73608 100644 --- a/Makefile +++ b/Makefile @@ -33,6 +33,7 @@ check: @(cd sched_mc; $(MAKE) check) # @(cd suspend; $(MAKE) check) # @(cd thermal; $(MAKE) check) +# @(cd powertop; $(MAKE) check) uncheck: @(cd cpufreq; $(MAKE) uncheck) diff --git a/powertop/Makefile b/powertop/Makefile new file mode 100644 index 000..412edb5 --- /dev/null +++ b/powertop/Makefile @@ -0,0 +1,25 @@ +# +# PM-QA validation test suite for the power management on Linux +# +# Copyright (C) 2011, Linaro Limited. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Contributors: +# Rajagopal Venkat +# - initial API and implementation +# + +include ../Test.mk diff --git a/powertop/powertop_01.sh b/powertop/powertop_01.sh new file mode 100755 index 000..3427899 --- /dev/null +++ b/powertop/powertop_01.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# +# PM-QA validation test suite for the power management on Linux +# +# Copyright (C) 2011, Linaro Limited. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Contributors: +# Rajagopal Venkat +# - initial API and implementation +# + +# URL : https://wiki.linaro.org/WorkingGroups/PowerManagement/Doc/QA/Scripts#powertop_01 + +source ../include/functions.sh + +run_powertop() { + +local bin_name=powertop +local report=csv +local seconds=10 +local iterations=2 +local report_name=PowerTOP*.csv + +# remove old reports if exists +rm -f $report_name + +# run powertop for $(iterations) in report generation mode +start_time=`date +%s` +sudo $bin_name --$report --time=$seconds --iteration=$iterations +end_time=`date +%s` + +# check if powertop run for desired time +let expected_time="$iterations * $seconds" +let actual_time="$end_time - $start_time" + +check "if powertop run for $expected_time sec" "test $actual_time -ge $expected_time" + +# check if $(iterations) number of reports are generated +check "if reports are generated" "test $(ls $report_name | wc -l) -eq $iterations" + +return 0 +} + +run_powertop diff --git a/powertop/powertop_01.txt b/powertop/powertop_01.txt new file mode 100644 index 000..0caa6f0 --- /dev/null +++ b/powertop/powertop_01.txt @@ -0,0 +1 @@ +run powertop for 2 iterations of 10sec each diff --git a/powertop/powertop_sanity.sh b/powertop/powertop_sanity.sh new file mode 100755 index 000..3ae3065 --- /dev/null +++ b/powertop/powertop_sanity.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# +# PM-QA validation test suite for the power management on Linux +# +# Copyright (C) 2011, Linaro Limited. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free
Re: [PATCH] pm-qa: add powertop test cases
On 2 July 2012 23:40, Amit Kucheria wrote: > On Mon, Jul 2, 2012 at 9:13 PM, Rajagopal Venkat > wrote: > > add powertop test cases into pm-qa. Run the powertop sanity > > test to check if tool is available. If yes, then run > > powertop in report generation mode and validate the output. > > > > Signed-off-by: Rajagopal Venkat > > --- > > Makefile |1 + > > powertop/Makefile| 25 ++ > > powertop/powertop_01.sh | 58 > ++ > > powertop/powertop_01.txt |1 + > > powertop/powertop_sanity.sh | 35 + > > powertop/powertop_sanity.txt |1 + > > 6 files changed, 121 insertions(+) > > create mode 100644 powertop/Makefile > > create mode 100755 powertop/powertop_01.sh > > create mode 100644 powertop/powertop_01.txt > > create mode 100755 powertop/powertop_sanity.sh > > create mode 100644 powertop/powertop_sanity.txt > > > > diff --git a/Makefile b/Makefile > > index f85e5ac..1e73608 100644 > > --- a/Makefile > > +++ b/Makefile > > @@ -33,6 +33,7 @@ check: > > @(cd sched_mc; $(MAKE) check) > > # @(cd suspend; $(MAKE) check) > > # @(cd thermal; $(MAKE) check) > > +# @(cd powertop; $(MAKE) check) > > > > uncheck: > > @(cd cpufreq; $(MAKE) uncheck) > > diff --git a/powertop/Makefile b/powertop/Makefile > > new file mode 100644 > > index 000..412edb5 > > --- /dev/null > > +++ b/powertop/Makefile > > @@ -0,0 +1,25 @@ > > +# > > +# PM-QA validation test suite for the power management on Linux > > +# > > +# Copyright (C) 2011, Linaro Limited. > > +# > > +# This program is free software; you can redistribute it and/or > > +# modify it under the terms of the GNU General Public License > > +# as published by the Free Software Foundation; either version 2 > > +# of the License, or (at your option) any later version. > > +# > > +# This program is distributed in the hope that it will be useful, > > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > +# GNU General Public License for more details. > > +# > > +# You should have received a copy of the GNU General Public License > > +# along with this program; if not, write to the Free Software > > +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA > 02110-1301, USA. > > +# > > +# Contributors: > > +# Rajagopal Venkat > > +# - initial API and implementation > > +# > > + > > +include ../Test.mk > > diff --git a/powertop/powertop_01.sh b/powertop/powertop_01.sh > > new file mode 100755 > > index 000..3427899 > > --- /dev/null > > +++ b/powertop/powertop_01.sh > > @@ -0,0 +1,58 @@ > > +#!/bin/bash > > +# > > +# PM-QA validation test suite for the power management on Linux > > +# > > +# Copyright (C) 2011, Linaro Limited. > > +# > > +# This program is free software; you can redistribute it and/or > > +# modify it under the terms of the GNU General Public License > > +# as published by the Free Software Foundation; either version 2 > > +# of the License, or (at your option) any later version. > > +# > > +# This program is distributed in the hope that it will be useful, > > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > +# GNU General Public License for more details. > > +# > > +# You should have received a copy of the GNU General Public License > > +# along with this program; if not, write to the Free Software > > +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA > 02110-1301, USA. > > +# > > +# Contributors: > > +# Rajagopal Venkat > > +# - initial API and implementation > > +# > > + > > +# URL : > https://wiki.linaro.org/WorkingGroups/PowerManagement/Doc/QA/Scripts#powertop_01 > > + > > +source ../include/functions.sh > > + > > +run_powertop() { > > + > > +local bin_name=powertop > > Is is safe to assume that powertop is always in the PATH? Even on Android? > > Though powertop is available in the PATH on ubuntu and Android, it is not safe to assume. This will be fixed. > > +local report=csv > > +local seconds=10 > > +local iterations=2 > > +local report_name=PowerTOP*.csv > > + > > +# remove
[PATCH v2] pm-qa: add powertop test cases
add powertop test cases into pm-qa. Run the powertop sanity test to check if tool is available. If yes, then run powertop in report generation mode and validate the output. Signed-off-by: Rajagopal Venkat --- Makefile |1 + powertop/Makefile| 25 ++ powertop/powertop_01.sh | 58 ++ powertop/powertop_01.txt |1 + powertop/powertop_sanity.sh | 35 + powertop/powertop_sanity.txt |1 + 6 files changed, 121 insertions(+) create mode 100644 powertop/Makefile create mode 100755 powertop/powertop_01.sh create mode 100644 powertop/powertop_01.txt create mode 100755 powertop/powertop_sanity.sh create mode 100644 powertop/powertop_sanity.txt diff --git a/Makefile b/Makefile index f85e5ac..1e73608 100644 --- a/Makefile +++ b/Makefile @@ -33,6 +33,7 @@ check: @(cd sched_mc; $(MAKE) check) # @(cd suspend; $(MAKE) check) # @(cd thermal; $(MAKE) check) +# @(cd powertop; $(MAKE) check) uncheck: @(cd cpufreq; $(MAKE) uncheck) diff --git a/powertop/Makefile b/powertop/Makefile new file mode 100644 index 000..412edb5 --- /dev/null +++ b/powertop/Makefile @@ -0,0 +1,25 @@ +# +# PM-QA validation test suite for the power management on Linux +# +# Copyright (C) 2011, Linaro Limited. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Contributors: +# Rajagopal Venkat +# - initial API and implementation +# + +include ../Test.mk diff --git a/powertop/powertop_01.sh b/powertop/powertop_01.sh new file mode 100755 index 000..cf243f1 --- /dev/null +++ b/powertop/powertop_01.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# +# PM-QA validation test suite for the power management on Linux +# +# Copyright (C) 2011, Linaro Limited. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Contributors: +# Rajagopal Venkat +# - initial API and implementation +# + +# URL : https://wiki.linaro.org/WorkingGroups/PowerManagement/Doc/QA/Scripts#powertop_01 + +source ../include/functions.sh + +run_powertop() { + +local bin_path=`command -v powertop` +local report=csv +local seconds=10 +local iterations=2 +local report_name=PowerTOP*.csv + +# remove old reports if exists +rm -f $report_name + +# run powertop for $(iterations) in report generation mode +start_time=`date +%s` +sudo $bin_path --$report --time=$seconds --iteration=$iterations +end_time=`date +%s` + +# check if powertop run for desired time +let expected_time="$iterations * $seconds" +let actual_time="$end_time - $start_time" + +check "if powertop run for $expected_time sec" "test $actual_time -ge $expected_time" + +# check if $(iterations) number of reports are generated +check "if reports are generated" "test $(ls -1 $report_name | wc -l) -eq $iterations" + +return 0 +} + +run_powertop diff --git a/powertop/powertop_01.txt b/powertop/powertop_01.txt new file mode 100644 index 000..0caa6f0 --- /dev/null +++ b/powertop/powertop_01.txt @@ -0,0 +1 @@ +run powertop for 2 iterations of 10sec each diff --git a/powertop/powertop_sanity.sh b/powertop/powertop_sanity.sh new file mode 100755 index 000..3ae3065 --- /dev/null +++ b/powertop/powertop_sanity.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# +# PM-QA validation test suite for the power management on Linux +# +# Copyright (C) 2011, Linaro Limited. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as publi
[PATCH v2] pm-qa: add powertop test cases
add powertop test cases into pm-qa. Run the powertop sanity test to check if tool is available. If yes, then run powertop in report generation mode and validate the output. Signed-off-by: Rajagopal Venkat --- Makefile |1 + powertop/Makefile| 25 ++ powertop/powertop_01.sh | 58 ++ powertop/powertop_01.txt |1 + powertop/powertop_sanity.sh | 35 + powertop/powertop_sanity.txt |1 + 6 files changed, 121 insertions(+) create mode 100644 powertop/Makefile create mode 100755 powertop/powertop_01.sh create mode 100644 powertop/powertop_01.txt create mode 100755 powertop/powertop_sanity.sh create mode 100644 powertop/powertop_sanity.txt diff --git a/Makefile b/Makefile index f85e5ac..1e73608 100644 --- a/Makefile +++ b/Makefile @@ -33,6 +33,7 @@ check: @(cd sched_mc; $(MAKE) check) # @(cd suspend; $(MAKE) check) # @(cd thermal; $(MAKE) check) +# @(cd powertop; $(MAKE) check) uncheck: @(cd cpufreq; $(MAKE) uncheck) diff --git a/powertop/Makefile b/powertop/Makefile new file mode 100644 index 000..412edb5 --- /dev/null +++ b/powertop/Makefile @@ -0,0 +1,25 @@ +# +# PM-QA validation test suite for the power management on Linux +# +# Copyright (C) 2011, Linaro Limited. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Contributors: +# Rajagopal Venkat +# - initial API and implementation +# + +include ../Test.mk diff --git a/powertop/powertop_01.sh b/powertop/powertop_01.sh new file mode 100755 index 000..cf243f1 --- /dev/null +++ b/powertop/powertop_01.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# +# PM-QA validation test suite for the power management on Linux +# +# Copyright (C) 2011, Linaro Limited. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Contributors: +# Rajagopal Venkat +# - initial API and implementation +# + +# URL : https://wiki.linaro.org/WorkingGroups/PowerManagement/Doc/QA/Scripts#powertop_01 + +source ../include/functions.sh + +run_powertop() { + +local bin_path=`command -v powertop` +local report=csv +local seconds=10 +local iterations=2 +local report_name=PowerTOP*.csv + +# remove old reports if exists +rm -f $report_name + +# run powertop for $(iterations) in report generation mode +start_time=`date +%s` +sudo $bin_path --$report --time=$seconds --iteration=$iterations +end_time=`date +%s` + +# check if powertop run for desired time +let expected_time="$iterations * $seconds" +let actual_time="$end_time - $start_time" + +check "if powertop run for $expected_time sec" "test $actual_time -ge $expected_time" + +# check if $(iterations) number of reports are generated +check "if reports are generated" "test $(ls -1 $report_name | wc -l) -eq $iterations" + +return 0 +} + +run_powertop diff --git a/powertop/powertop_01.txt b/powertop/powertop_01.txt new file mode 100644 index 000..0caa6f0 --- /dev/null +++ b/powertop/powertop_01.txt @@ -0,0 +1 @@ +run powertop for 2 iterations of 10sec each diff --git a/powertop/powertop_sanity.sh b/powertop/powertop_sanity.sh new file mode 100755 index 000..3ae3065 --- /dev/null +++ b/powertop/powertop_sanity.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# +# PM-QA validation test suite for the power management on Linux +# +# Copyright (C) 2011, Linaro Limited. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as publi
[PATCH v2] pm-qa: add powertop test cases
add powertop test cases into pm-qa. Run the powertop sanity test to check if tool is available. If yes, then run powertop in report generation mode and validate the output. Signed-off-by: Rajagopal Venkat --- Makefile |1 + powertop/Makefile| 25 ++ powertop/powertop_01.sh | 58 ++ powertop/powertop_01.txt |1 + powertop/powertop_sanity.sh | 35 + powertop/powertop_sanity.txt |1 + 6 files changed, 121 insertions(+) create mode 100644 powertop/Makefile create mode 100755 powertop/powertop_01.sh create mode 100644 powertop/powertop_01.txt create mode 100755 powertop/powertop_sanity.sh create mode 100644 powertop/powertop_sanity.txt diff --git a/Makefile b/Makefile index f85e5ac..1e73608 100644 --- a/Makefile +++ b/Makefile @@ -33,6 +33,7 @@ check: @(cd sched_mc; $(MAKE) check) # @(cd suspend; $(MAKE) check) # @(cd thermal; $(MAKE) check) +# @(cd powertop; $(MAKE) check) uncheck: @(cd cpufreq; $(MAKE) uncheck) diff --git a/powertop/Makefile b/powertop/Makefile new file mode 100644 index 000..412edb5 --- /dev/null +++ b/powertop/Makefile @@ -0,0 +1,25 @@ +# +# PM-QA validation test suite for the power management on Linux +# +# Copyright (C) 2011, Linaro Limited. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Contributors: +# Rajagopal Venkat +# - initial API and implementation +# + +include ../Test.mk diff --git a/powertop/powertop_01.sh b/powertop/powertop_01.sh new file mode 100755 index 000..cf243f1 --- /dev/null +++ b/powertop/powertop_01.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# +# PM-QA validation test suite for the power management on Linux +# +# Copyright (C) 2011, Linaro Limited. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Contributors: +# Rajagopal Venkat +# - initial API and implementation +# + +# URL : https://wiki.linaro.org/WorkingGroups/PowerManagement/Doc/QA/Scripts#powertop_01 + +source ../include/functions.sh + +run_powertop() { + +local bin_path=`command -v powertop` +local report=csv +local seconds=10 +local iterations=2 +local report_name=PowerTOP*.csv + +# remove old reports if exists +rm -f $report_name + +# run powertop for $(iterations) in report generation mode +start_time=`date +%s` +sudo $bin_path --$report --time=$seconds --iteration=$iterations +end_time=`date +%s` + +# check if powertop run for desired time +let expected_time="$iterations * $seconds" +let actual_time="$end_time - $start_time" + +check "if powertop run for $expected_time sec" "test $actual_time -ge $expected_time" + +# check if $(iterations) number of reports are generated +check "if reports are generated" "test $(ls -1 $report_name | wc -l) -eq $iterations" + +return 0 +} + +run_powertop diff --git a/powertop/powertop_01.txt b/powertop/powertop_01.txt new file mode 100644 index 000..0caa6f0 --- /dev/null +++ b/powertop/powertop_01.txt @@ -0,0 +1 @@ +run powertop for 2 iterations of 10sec each diff --git a/powertop/powertop_sanity.sh b/powertop/powertop_sanity.sh new file mode 100755 index 000..3ae3065 --- /dev/null +++ b/powertop/powertop_sanity.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# +# PM-QA validation test suite for the power management on Linux +# +# Copyright (C) 2011, Linaro Limited. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as publi
Re: [Powertop][PATCH] fix cpuidle state name parsing
Can someone consider this patch for merge? On 23 June 2012 00:08, Rajagopal Venkat wrote: > parse cpuidle C state based on sysfs file entry(stateX) > instead of state name/description > > Signed-off-by: Rajagopal Venkat > --- > src/cpu/abstract_cpu.cpp |2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/src/cpu/abstract_cpu.cpp b/src/cpu/abstract_cpu.cpp > index cd4eba0..72969fc 100644 > --- a/src/cpu/abstract_cpu.cpp > +++ b/src/cpu/abstract_cpu.cpp > @@ -147,7 +147,7 @@ void abstract_cpu::insert_cstate(const char > *linux_name, const char *human_name, > strcpy(state->linux_name, linux_name); > strcpy(state->human_name, human_name); > > - c = human_name; > + c = linux_name; > while (*c) { > if (strcmp(linux_name, "active")==0) { > state->line_level = LEVEL_C0; > -- > 1.7.9.5 > > ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [Powertop][PATCH v3] conditionally disable pci if not supported
Can someone consider this patch for merge? On 25 June 2012 22:44, Rajagopal Venkat wrote: > disable pci if not supported by host platform. When > libpci is not found, define a macro which will be > used for conditional compilation. > > Signed-off-by: Rajagopal Venkat > --- > configure.ac |5 +++-- > src/lib.cpp | 20 ++-- > src/lib.h|5 + > 3 files changed, 26 insertions(+), 4 deletions(-) > > diff --git a/configure.ac b/configure.ac > index 4da4eea..3cbc7b0 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -48,8 +48,9 @@ AC_CHECK_FUNCS([fdatasync getpagesize gettimeofday > memmove memset mkdir munmap p > AC_SEARCH_LIBS([delwin], [ncursesw ncurses], [], AC_MSG_ERROR([ncurses is > required but was not found]), []) > > PKG_CHECK_MODULES([PCIUTILS], [libpci],[],[ > - AC_SEARCH_LIBS([pci_get_dev], [pci], [], AC_MSG_ERROR([libpci is > required but was not found]), []) > -]) > + AC_SEARCH_LIBS([pci_get_dev], [pci], [], > AC_DEFINE([HAVE_NO_PCI],[1],[Define if pci is not supported]), []) > +]) > + > PKG_CHECK_MODULES([LIBZ], [zlib],[],[ > AC_SEARCH_LIBS([deflate], [z], [], AC_MSG_ERROR([zlib is required > but was not found]), []) > ]) > diff --git a/src/lib.cpp b/src/lib.cpp > index 0f87e48..77e49a2 100644 > --- a/src/lib.cpp > +++ b/src/lib.cpp > @@ -35,11 +35,13 @@ > #include > #include > > +#include "lib.h" > + > +#ifndef HAVE_NO_PCI > extern "C" { > #include > } > - > -#include "lib.h" > +#endif > > #include > #include > @@ -266,6 +268,7 @@ void format_watts(double W, char *buffer, unsigned int > len) > } > > > +#ifndef HAVE_NO_PCI > static struct pci_access *pci_access; > > char *pci_id_to_name(uint16_t vendor, uint16_t device, char *buffer, int > len) > @@ -290,6 +293,19 @@ void end_pci_access(void) > pci_free_name_list(pci_access); > } > > +#else > + > +char *pci_id_to_name(uint16_t vendor, uint16_t device, char *buffer, int > len) > +{ > + return NULL; > +} > + > +void end_pci_access(void) > +{ > +} > + > +#endif /* HAVE_NO_PCI */ > + > int utf_ok = -1; > > > diff --git a/src/lib.h b/src/lib.h > index 588c023..7093b7f 100644 > --- a/src/lib.h > +++ b/src/lib.h > @@ -30,6 +30,11 @@ > #endif > #include > > +/* Include only for Automake builds */ > +#ifdef HAVE_CONFIG_H > +#include "config.h" > +#endif > + > #ifndef DISABLE_I18N > #define _(STRING)gettext(STRING) > #else > -- > 1.7.9.5 > > ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [Powertop][PATCH v3] conditionally disable pci if not supported
On 13 July 2012 11:03, Ricardo Salveti wrote: > On Fri, Jul 13, 2012 at 2:02 AM, Rajagopal Venkat > wrote: > > Can someone consider this patch for merge? > > As we will have libpci available at most distros by default, isn't > there a way of doing run-time detection instead of disabling it at > build time? > This patch disables powertop PCI support only when libpci is not available on a system. Nothing specific to ARM platforms. I don't think it can be done at run-time. Without this patch if libpci is not available, powertop compilation itself will fail. > This is just because we'll be getting more and more ARM boards which > have PCI-e as well, so we'll need to handle systems with and without > any PCI available. > > Cheers, > -- > Ricardo Salveti de Araujo > ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [PATCH] Add -fno-exceptions and -fno-rtti in Android.mk
On 26 July 2012 08:45, kejun.zhou wrote: > From: "kejun.zhou" > > Signed-off-by: kejun.zhou > --- > Android.mk |4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/Android.mk b/Android.mk > index c82cd95..fa1c225 100644 > --- a/Android.mk > +++ b/Android.mk > @@ -28,7 +28,9 @@ LOCAL_CPPFLAGS += -DDISABLE_I18N \ > -DNCURSES_NOMACROS \ > -DHAVE_NO_PCI \ > -DDEFAULT_TERM=\"xterm\" \ > - -DTERMINFO_PATH=\"/system/etc/terminfo\" > + -DTERMINFO_PATH=\"/system/etc/terminfo\" \ > + -fno-exceptions \ > + -fno-rtti \ > > I think no-exceptions and no-rtti options are enabled by default in Android toolchain. Compiler throws "exception handling disabled, use -fexceptions to enable" error when powertop is compiled with exceptions. Moreover for Android, powertop exception handling is disabled through DISABLE_TRYCATCH macro which is set in Android.mk. > LOCAL_C_INCLUDES += external/stlport/stlport/ \ > external/stlport/stlport/stl \ > -- > 1.7.10 > > ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [Powertop][PATCH] fix cpuidle state name parsing
This patch fixes powertop to display cpuidle states on platforms where cpuidle stateX directory name field does not contain "CX" string. On some platforms, the name field contains meaningful strings like WFI, Sleep, DeepSleep. Please review the patch. On 23 June 2012 00:08, Rajagopal Venkat wrote: > parse cpuidle C state based on sysfs file entry(stateX) > instead of state name/description > > Signed-off-by: Rajagopal Venkat > --- > src/cpu/abstract_cpu.cpp |2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/src/cpu/abstract_cpu.cpp b/src/cpu/abstract_cpu.cpp > index cd4eba0..72969fc 100644 > --- a/src/cpu/abstract_cpu.cpp > +++ b/src/cpu/abstract_cpu.cpp > @@ -147,7 +147,7 @@ void abstract_cpu::insert_cstate(const char > *linux_name, const char *human_name, > strcpy(state->linux_name, linux_name); > strcpy(state->human_name, human_name); > > - c = human_name; > + c = linux_name; > while (*c) { > if (strcmp(linux_name, "active")==0) { > state->line_level = LEVEL_C0; > -- > 1.7.9.5 > > ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [Powertop] [PATCH] fix cpuidle state name parsing
On 1 August 2012 03:34, Chris Ferron wrote: > > This patch fixes powertop to display cpuidle states on platforms > > where cpuidle stateX directory name field does not contain > > "CX" string. On some platforms, the name field contains meaningful > > strings like WFI, Sleep, DeepSleep. > > > > Please review the patch. > > > Im not sure this is doing what you think it is, and if it is doing > something; then i fear its an weird artifact of something else. > > I assume when you say "some platforms" you mean "ARM"? > Can you detail out with data what the bug is you are having, along with > expected results? This patch is not specific to ARM but for any platform on which cpuidle state name filed doesn't follow "CX" string pattern. For instance the snowball cpuidle states are defined as follows[1] { .enter = arm_cpuidle_simple_enter, .. .name = "WFI", .desc = "ARM WFI", }, { .enter = ux500_enter_idle, .. .name = "ApIdle", .desc = "ARM Retention", }, Now, while parsing for C states, powertop is using .name field(human_name) for detecting supported cpuidle state levels. This is done with an assumption that, name field value contains "CX" substring, which is not true in above case. Infact, I could find good number of cpuidle drivers of this kind in mainline kernel. None of above cpuidle states should get added in insert_cstate() function. Fortunately, the deepest idle state is added as C0 state because of memset(state, 0, sizeof(*state));. Hence powertop displays only one idle state. Parsing idle states based on directory name stateX(linux_name) is safe. This patch does that. [1] arch/arm/mach-ux500/cpuidle.c<http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=arch/arm/mach-ux500/cpuidle.c;h=b54884bd254987f105d5f8ab0701b458ece1396e;hb=HEAD> What is your test platform, kernel version, etc. > By your comment of what fields contents, I am betting there is more work > to be done here > then just what you sent regardless. > Im not going to take this patch at this time, until I understand the full > details. > > Please be verbose, I have no ARM platforms to experiment or test with. > > -Chris > > > > On 23 June 2012 00:08, Rajagopal Venkat > > wrote: > > > >> parse cpuidle C state based on sysfs file entry(stateX) > >> instead of state name/description > >> > >> Signed-off-by: Rajagopal Venkat > >> --- > >> src/cpu/abstract_cpu.cpp |2 +- > >> 1 file changed, 1 insertion(+), 1 deletion(-) > >> > >> diff --git a/src/cpu/abstract_cpu.cpp b/src/cpu/abstract_cpu.cpp > >> index cd4eba0..72969fc 100644 > >> --- a/src/cpu/abstract_cpu.cpp > >> +++ b/src/cpu/abstract_cpu.cpp > >> @@ -147,7 +147,7 @@ void abstract_cpu::insert_cstate(const char > >> *linux_name, const char *human_name, > >> strcpy(state->linux_name, linux_name); > >> strcpy(state->human_name, human_name); > >> > >> - c = human_name; > >> + c = linux_name; > >> while (*c) { > >> if (strcmp(linux_name, "active")==0) { > >> state->line_level = LEVEL_C0; > >> -- > >> 1.7.9.5 > >> > >> > > ___ > > PowerTop mailing list > > power...@lists.01.org > > https://lists.01.org/mailman/listinfo/powertop > > > > -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH] manifest: (all) update powertop to new version
From: Rajagopal Venkat Update all manifest files to include new powertop-2.0 version. Signed-off-by: Rajagopal Venkat --- default.xml | 2 +- landing-snowball.xml | 2 +- linaro-default.xml| 2 +- staging-galaxynexus.xml | 2 +- staging-origen.xml| 2 +- staging-panda.xml | 2 +- staging-vexpress-rtsm-isw.xml | 2 +- staging-vexpress-rtsm.xml | 2 +- staging-vexpress.xml | 2 +- tracking-panda.xml| 2 +- tracking-vexpress.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/default.xml b/default.xml index 4b90695..f82ee51 100644 --- a/default.xml +++ b/default.xml @@ -35,7 +35,7 @@ - + diff --git a/landing-snowball.xml b/landing-snowball.xml index 16758f2..61224b6 100644 --- a/landing-snowball.xml +++ b/landing-snowball.xml @@ -38,7 +38,7 @@ - + diff --git a/linaro-default.xml b/linaro-default.xml index ae9d298..de9e957 100644 --- a/linaro-default.xml +++ b/linaro-default.xml @@ -36,7 +36,7 @@ - + diff --git a/staging-galaxynexus.xml b/staging-galaxynexus.xml index 41e5e23..1645c7d 100644 --- a/staging-galaxynexus.xml +++ b/staging-galaxynexus.xml @@ -32,7 +32,7 @@ - + diff --git a/staging-origen.xml b/staging-origen.xml index c2dce1c..9be6f8c 100644 --- a/staging-origen.xml +++ b/staging-origen.xml @@ -37,7 +37,7 @@ - + diff --git a/staging-panda.xml b/staging-panda.xml index 9c2c1b5..a2a108a 100644 --- a/staging-panda.xml +++ b/staging-panda.xml @@ -34,7 +34,7 @@ - + diff --git a/staging-vexpress-rtsm-isw.xml b/staging-vexpress-rtsm-isw.xml index c57c505..3b6f53f 100644 --- a/staging-vexpress-rtsm-isw.xml +++ b/staging-vexpress-rtsm-isw.xml @@ -46,7 +46,7 @@ - + diff --git a/staging-vexpress-rtsm.xml b/staging-vexpress-rtsm.xml index 939f06e..a3138d1 100644 --- a/staging-vexpress-rtsm.xml +++ b/staging-vexpress-rtsm.xml @@ -45,7 +45,7 @@ - + diff --git a/staging-vexpress.xml b/staging-vexpress.xml index 46b47c6..5c0d338 100644 --- a/staging-vexpress.xml +++ b/staging-vexpress.xml @@ -37,7 +37,7 @@ - + diff --git a/tracking-panda.xml b/tracking-panda.xml index 834c57a..50cfa55 100644 --- a/tracking-panda.xml +++ b/tracking-panda.xml @@ -33,7 +33,7 @@ - + diff --git a/tracking-vexpress.xml b/tracking-vexpress.xml index 9a073a4..dba2752 100644 --- a/tracking-vexpress.xml +++ b/tracking-vexpress.xml @@ -36,7 +36,7 @@ - + -- 1.7.11.1 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH 0/3][RFC] devfreq: Add support for devices which can idle
This patchset updates devfreq core to add support for devices which can idle. When device idleness is detected perhaps through runtime-pm, need some mechanism to suspend devfreq load monitoring and resume when device is back online. patch 1 adds core design changes mainly moving monitoring logic to ondemand governor, introducing per device work and events for core to governor communication. patch 2 adds devfreq suspend and resume apis. patch 3 does current frequency bug fix. The existing devfreq apis are kept intact. Two new apis devfreq_suspend_device() and devfreq_resume_device() are added to support suspend/resume of device devfreq. -- Rajagopal Venkat (3): devfreq: core updates to support devices which can idle devfreq: Add suspend and resume apis devfreq: Add current freq callback in device profile Documentation/ABI/testing/sysfs-class-devfreq | 33 +- drivers/devfreq/devfreq.c | 448 ++ drivers/devfreq/governor.h| 6 +- drivers/devfreq/governor_performance.c| 34 +- drivers/devfreq/governor_powersave.c | 31 +- drivers/devfreq/governor_simpleondemand.c | 231 +++-- drivers/devfreq/governor_userspace.c | 142 include/linux/devfreq.h | 78 +++-- 8 files changed, 467 insertions(+), 536 deletions(-) -- 1.7.11.3 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH 2/3][RFC] devfreq: Add suspend and resume apis
This patch adds suspend and resume apis needed for devices which can idle. Suspend/resume apis are called from driver to suspend/resume devfreq load monitoring of that device. Signed-off-by: Rajagopal Venkat --- drivers/devfreq/devfreq.c | 30 ++ drivers/devfreq/governor_simpleondemand.c | 15 +++ include/linux/devfreq.h | 16 3 files changed, 61 insertions(+) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 5aa23a8..375b5aa1 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -233,6 +233,36 @@ int devfreq_remove_device(struct devfreq *devfreq) } EXPORT_SYMBOL(devfreq_remove_device); +/** + * devfreq_suspend_device() - Suspend devfreq of a device. + * @devfreqthe devfreq instance to be suspended + */ +int devfreq_suspend_device(struct devfreq *devfreq) +{ + if (!devfreq) + return -EINVAL; + + devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_SUSPEND); + + return 0; +} +EXPORT_SYMBOL(devfreq_suspend_device); + +/** + * devfreq_resume_device() - Resume devfreq of a device. + * @devfreqthe devfreq instance to be resumed + */ +int devfreq_resume_device(struct devfreq *devfreq) +{ + if (!devfreq) + return -EINVAL; + + devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_RESUME); + + return 0; +} +EXPORT_SYMBOL(devfreq_resume_device); + static ssize_t show_governor(struct device *dev, struct device_attribute *attr, char *buf) { diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c index 7c70c30..95e4db9 100644 --- a/drivers/devfreq/governor_simpleondemand.c +++ b/drivers/devfreq/governor_simpleondemand.c @@ -221,6 +221,21 @@ static int devfreq_simple_ondemand_func(struct devfreq *df, ondemand_exit(df); break; + case DEVFREQ_GOV_SUSPEND: + if (delayed_work_pending(&data->work)) { + data->stop_queuing = true; + cancel_delayed_work_sync(&data->work); + } + break; + + case DEVFREQ_GOV_RESUME: + if (!delayed_work_pending(&data->work)) { + data->stop_queuing = false; + queue_delayed_work(devfreq_wq, &data->work, + msecs_to_jiffies(df->profile->polling_ms)); + } + break; + case DEVFREQ_GOV_LIMITS: if (delayed_work_pending(&data->work)) { mutex_lock(&df->lock); diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 600cc2e..7c6517f 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -56,6 +56,8 @@ struct devfreq_dev_status { #define DEVFREQ_GOV_START 0x1 #define DEVFREQ_GOV_STOP 0x2 #define DEVFREQ_GOV_LIMITS 0x3 +#define DEVFREQ_GOV_SUSPEND0x4 +#define DEVFREQ_GOV_RESUME 0x5 /** * struct devfreq_dev_profile - Devfreq's user device profile @@ -155,6 +157,10 @@ extern struct devfreq *devfreq_add_device(struct device *dev, void *data); extern int devfreq_remove_device(struct devfreq *devfreq); +extern int devfreq_suspend_device(struct devfreq *devfreq); + +extern int devfreq_resume_device(struct devfreq *devfreq); + /* Helper functions for devfreq user device driver with OPP. */ extern struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, u32 flags); @@ -207,6 +213,16 @@ static int devfreq_remove_device(struct devfreq *devfreq) return 0; } +static int devfreq_suspend_device(struct devfreq *devfreq) +{ + return 0; +} + +extern int devfreq_resume_device(struct devfreq *devfreq) +{ + return 0; +} + static struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, u32 flags) { -- 1.7.11.3 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH 3/3][RFC] devfreq: Add current freq callback in device profile
Devfreq returns governor predicted frequency as current frequency via sysfs interface. But device may not support all frequencies that governor predicts. As per the design its driver responsibility to maintain current frequency at which device is operating. So add a callback in device profile to fix this. Signed-off-by: Rajagopal Venkat --- drivers/devfreq/devfreq.c | 14 -- include/linux/devfreq.h | 6 +++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 375b5aa1..798e8ca 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -176,7 +176,6 @@ struct devfreq *devfreq_add_device(struct device *dev, devfreq->dev.release = devfreq_dev_release; devfreq->profile = profile; devfreq->governor = governor; - devfreq->previous_freq = profile->initial_freq; devfreq->governor_data = data; devfreq->nb.notifier_call = devfreq_notifier_call; devfreq->min_freq = profile->min_freq; @@ -272,7 +271,18 @@ static ssize_t show_governor(struct device *dev, static ssize_t show_freq(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "%lu\n", to_devfreq(dev)->previous_freq); + int ret; + unsigned long freq; + struct devfreq *devfreq = to_devfreq(dev); + + if (devfreq->profile->get_cur_freq) { + ret = devfreq->profile->get_cur_freq(devfreq->dev.parent, + &freq); + if (!ret) + return sprintf(buf, "%lu\n", freq); + } + + return sprintf(buf, ""); } static ssize_t store_min_freq(struct device *dev, struct device_attribute *attr, diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 7c6517f..43f111f 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -76,6 +76,8 @@ struct devfreq_dev_status { * explained above with "DEVFREQ_FLAG_*" macros. * @get_dev_status The device should provide the current performance * status to devfreq, which is used by governors. + * @get_cur_freq The device should provide the current frequency + * at which it is operating. * @exit An optional callback that is called when devfreq * is removing the devfreq object due to error or * from devfreq_remove_device() call. If the user @@ -91,6 +93,7 @@ struct devfreq_dev_profile { int (*target)(struct device *dev, unsigned long *freq, u32 flags); int (*get_dev_status)(struct device *dev, struct devfreq_dev_status *stat); + int (*get_cur_freq)(struct device *dev, unsigned long *freq); void (*exit)(struct device *dev); }; @@ -119,7 +122,6 @@ struct devfreq_governor { * @nb notifier block used to notify devfreq object that it should * reevaluate operable frequencies. Devfreq users may use * devfreq.nb to the corresponding register notifier call chain. - * @previous_freq previously configured frequency value. * @governor_data Private data of the governor. The devfreq framework * does not touch this. * @min_freq Limit minimum frequency requested by user (0: none) @@ -142,8 +144,6 @@ struct devfreq { const struct devfreq_governor *governor; struct notifier_block nb; - unsigned long previous_freq; - void *governor_data; /* private data for governors */ unsigned long min_freq; -- 1.7.11.3 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH 1/3][RFC] devfreq: Core updates to support devices which can idle
Prepare devfreq core framework to support devices which can idle. When device idleness is detected perhaps through runtime-pm, need some mechanism to suspend devfreq load monitoring and resume when device is back online. Present code continues monitoring unless device is removed from devfreq core. This patch introduces following updates, - move device load monitoring logic to ondemand governor as it is specific to ondemand. - devfreq core interacts with governors via events to perform specific actions. These events include start/stop devfreq, and frequency limit changes outside devfreq. This sets ground for adding suspend/resume events. - use per device work instead of global work to monitor device load. This enables suspend/resume of device devfreq and reduces monitoring code complexity. - Force devfreq users to set min/max supported frequencies in device profile to help governors to predict target frequecy with in limits. The devfreq apis are not modified and are kept intact. Signed-off-by: Rajagopal Venkat --- Documentation/ABI/testing/sysfs-class-devfreq | 33 +- drivers/devfreq/devfreq.c | 418 -- drivers/devfreq/governor.h| 6 +- drivers/devfreq/governor_performance.c| 34 +-- drivers/devfreq/governor_powersave.c | 31 +- drivers/devfreq/governor_simpleondemand.c | 216 +++-- drivers/devfreq/governor_userspace.c | 142 - include/linux/devfreq.h | 56 ++-- 8 files changed, 398 insertions(+), 538 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq index 23d78b5..c083433 100644 --- a/Documentation/ABI/testing/sysfs-class-devfreq +++ b/Documentation/ABI/testing/sysfs-class-devfreq @@ -21,27 +21,32 @@ Description: The /sys/class/devfreq/.../cur_freq shows the current frequency of the corresponding devfreq object. -What: /sys/class/devfreq/.../central_polling +What: /sys/class/devfreq/.../max_freq Date: September 2011 Contact: MyungJoo Ham Description: - The /sys/class/devfreq/.../central_polling shows whether - the devfreq ojbect is using devfreq-provided central - polling mechanism or not. + The /sys/class/devfreq/.../max_freq shows the current + max frequency of the corresponding devfreq object. This + max frequency is guaranteed to be with in device + operating frequency limits. -What: /sys/class/devfreq/.../polling_interval +What: /sys/class/devfreq/.../min_freq Date: September 2011 Contact: MyungJoo Ham Description: - The /sys/class/devfreq/.../polling_interval shows and sets - the requested polling interval of the corresponding devfreq - object. The values are represented in ms. If the value is - less than 1 jiffy, it is considered to be 0, which means - no polling. This value is meaningless if the governor is - not polling; thus. If the governor is not using - devfreq-provided central polling - (/sys/class/devfreq/.../central_polling is 0), this value - may be useless. + The /sys/class/devfreq/.../min_freq shows the current + min frequency of the corresponding devfreq object. This + min frequency is guaranteed to be with in device + operating frequency limits. + +What: /sys/class/devfreq/.../ondemand/polling_interval +Date: September 2011 +Contact: MyungJoo Ham +Description: + The /sys/class/devfreq/.../ondemand/polling_interval shows + and sets the requested polling interval of the corresponding + devfreq object if ondemand governor is in effect. The values + are represented in ms. What: /sys/class/devfreq/.../userspace/set_freq Date: September 2011 diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 70c31d4..5aa23a8 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -11,7 +11,6 @@ */ #include -#include #include #include #include @@ -20,28 +19,12 @@ #include #include #include -#include #include #include -#include -#include #include "governor.h" struct class *devfreq_class; -/* - * devfreq_work periodically monitors every registered device. - * The minimum polling interval is one jiffy. The polling interval is - * determined by the minimum polling period among all polling devfreq - * devices. The resolution of polling interval is one jiffy. - */ -static bool polling; -static struct workqueue_struct *devfreq_wq; -static struct delayed_work devfreq_work; - -/* wait removing if this is to be removed */ -sta
Re: [PATCH 1/3][RFC] devfreq: Core updates to support devices which can idle
On 20 August 2012 12:50, 함명주 wrote: > > Prepare devfreq core framework to support devices which > > can idle. When device idleness is detected perhaps through > > runtime-pm, need some mechanism to suspend devfreq load > > monitoring and resume when device is back online. Present > > code continues monitoring unless device is removed from > > devfreq core. > > > > This patch introduces following updates, > > > > - move device load monitoring logic to ondemand governor as > > it is specific to ondemand. > > We have this ondemand governor in the mainline devfreq. However, > we have (not upstreamed yet) governors with specific purpose (for > GPU or for a specific chip) with load monitoring logic. Although > we don't have them upstreamed yet, why don't you keep the monitoring > logic sharable by other governors. (From today, I'm not objecting to > have individual workqueue, but I still don't want to let each active > governor reimplement the same things.) > > If more governors are planned based on load monitoring, possibly ondemand is not good enough even after adding additional configurable parameters. Could you please describe one such case which demand new governor? Please find my next comments. > > - devfreq core interacts with governors via events to perform > > specific actions. These events include start/stop devfreq, > > and frequency limit changes outside devfreq. This sets ground > > for adding suspend/resume events. > > event_handler with START/STOP/UPDATE seem fine. > > However, init() and exit() should be different from START/STOP. > We do not need to do init and exit every time when we do runtime > suspend/resume. > > I agree and its already taken care in this patch. DEVFREQ_GOV_START : Event for initializing and starting of devfreq governor for a device. Happens only when device is added using devfreq_add_device(). DEVFREQ_GOV_STOP: Event for stopping and uninitialization of devfreq governor for a device. Happens only when device is removed using devfreq_remove_device(). Events introduced in next patch (2/3) - DEVFREQ_GOV_SUSPEND: Event for suspending devfreq of a device. I.e suspending of load monitoring of device in case of ondemand governor. Happens only when devfreq_suspend_device() is called. DEVFREQ_GOV_RESUME: Event for resuming devfreq of a device. I.e continue load monitoring of already suspended device in case of ondemand governor. Happens only when devfreq_resume_device() is called. > > - use per device work instead of global work to monitor device > > load. This enables suspend/resume of device devfreq and > > reduces monitoring code complexity. > > It's fine to have a delayed work struct per device. > > However, please try to keep as many things/features in devfreq.c as > possible; i.e., reduce features and code size of governors. Because, > we will be supporting various types of devices with devfreq, there > will be various governors and I don't want them to have shared things > reimplemented. Dealing with the delayed work at devfreq.c and let > governors choose to use it (at its struct) or not should be fine. > > Delayed work is of only relevance to ondemand governor - justifies why struct delayed work moved from devfreq.c to governor_simpleondemand.c. When delayed work is optional for governors to use, then let governors handle them if needed instead of devfreq core. With this change, we will not be forcing next upcoming devfreq governors to use delayed work for load monitoring(if required) but instead flexibility to have their own mechanisms. Its up to the governors to decide how it wants to do dvfs of a device. But imperative to respond the events. In this patchset, the size of ondemand governor has been enlarged > too much for that purpose. > > > - Force devfreq users to set min/max supported frequencies in > > device profile to help governors to predict target frequecy > > with in limits. > > Is this really necessary? > Yes. Mainly for two reasons, 1. Devfreq core provides sysfs interface for usespace to set min/max operating frequency for a device. These values must be within device supported min/max frequency limits. 2. Governors should know device supported min/max opps and use them where ever needed. Never assume UINT_MAX as max frequency. > > > > > The devfreq apis are not modified and are kept intact. > > The ABIs are not. > > You can no longer do "# echo 0 > ABI_path" in order to deactivate. > Only relevant for ondemand governor. Load monitoring can be deactivated when polling_ms is set to zero. Next version of patch will fix this. Thanks. > Cheers! > MyungJoo > > > > > Signed-off-by: Rajagopal Venkat > > --- > > ps. please make the patch a bit more readable. (please don't shuffle > the location of pre-existed functions) > -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [PATCH 2/3][RFC] devfreq: Add suspend and resume apis
On 20 August 2012 15:49, MyungJoo Ham wrote: > > This patch adds suspend and resume apis needed > > for devices which can idle. Suspend/resume apis > > are called from driver to suspend/resume devfreq > > load monitoring of that device. > > > > Signed-off-by: Rajagopal Venkat > > 1. Some devfreq devices may need their own code to do suspend/resume; e.g., > setting a specific frequency for suspend (especially with suspend-to-RAM). > Assuming device driver is using devfreq ondemand governor, when driver detects idleness perhaps through runtime-pm, let driver set specific frequency and then suspend its devfreq. Also let driver resume its devfreq when device is back online. > 2. Are these new APIs (devfreq_suspend/resume_device()) intended to be > used by runtime_pm and pm(Suspend-to-RAM) callbacks of the parent devices? > If so, could you consider use the structure of runtime-pm (I don't have > an idea on how to do this for now)? For example, when a device is being > suspended, devfreq device's suspend is also called without calling it > explicitly at the device driver's suspend callback. > These new apis are not coupled with runtime-pm. Though runtime-pm is good candidate for detecting idleness, drivers can have their own logic. So its at device drivers discretion when to call devfreq_suspend_device() and devfreq_resume_device(). > 3. As in the patch 1/3, could you consider to integrate class-wide > features in devfreq.c, not in a governor? > > Yes, these apis are part of devfreq core. Core sends events to governors for taking specific actions. Again, only governor knows what to do with DEVFREQ_GOV_SUSPEND and DEVFREQ_GOV_RESUME events. For instance ondemand cancels/queues delayed work. > Cheers! > MyungJoo > > > --- > > drivers/devfreq/devfreq.c | 30 > ++ > > drivers/devfreq/governor_simpleondemand.c | 15 +++ > > include/linux/devfreq.h | 16 > > 3 files changed, 61 insertions(+) > > > > diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c > > index 5aa23a8..375b5aa1 100644 > > --- a/drivers/devfreq/devfreq.c > > +++ b/drivers/devfreq/devfreq.c > > @@ -233,6 +233,36 @@ int devfreq_remove_device(struct devfreq *devfreq) > > } > > EXPORT_SYMBOL(devfreq_remove_device); > > > > +/** > > + * devfreq_suspend_device() - Suspend devfreq of a device. > > + * @devfreq the devfreq instance to be suspended > > + */ > > +int devfreq_suspend_device(struct devfreq *devfreq) > > +{ > > + if (!devfreq) > > + return -EINVAL; > > + > > + devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_SUSPEND); > > + > > + return 0; > > +} > > +EXPORT_SYMBOL(devfreq_suspend_device); > > + > > +/** > > + * devfreq_resume_device() - Resume devfreq of a device. > > + * @devfreq the devfreq instance to be resumed > > + */ > > +int devfreq_resume_device(struct devfreq *devfreq) > > +{ > > + if (!devfreq) > > + return -EINVAL; > > + > > + devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_RESUME); > > + > > + return 0; > > +} > > +EXPORT_SYMBOL(devfreq_resume_device); > > + > > static ssize_t show_governor(struct device *dev, > >struct device_attribute *attr, char *buf) > > { > > diff --git a/drivers/devfreq/governor_simpleondemand.c > b/drivers/devfreq/governor_simpleondemand.c > > index 7c70c30..95e4db9 100644 > > --- a/drivers/devfreq/governor_simpleondemand.c > > +++ b/drivers/devfreq/governor_simpleondemand.c > > @@ -221,6 +221,21 @@ static int devfreq_simple_ondemand_func(struct > devfreq *df, > > ondemand_exit(df); > > break; > > > > + case DEVFREQ_GOV_SUSPEND: > > + if (delayed_work_pending(&data->work)) { > > + data->stop_queuing = true; > > + cancel_delayed_work_sync(&data->work); > > + } > > + break; > > + > > + case DEVFREQ_GOV_RESUME: > > + if (!delayed_work_pending(&data->work)) { > > + data->stop_queuing = false; > > + queue_delayed_work(devfreq_wq, &data->work, > > + msecs_to_jiffies(df->profile->polling_ms)); > > + } > > + break; > > + > > case DEVFREQ_GOV_LIMITS: > > if (delayed_work_pending(&am
Fwd: [PATCH 0/3][RFC] devfreq: Add support for devices which can idle
-- Forwarded message -- From: Rajagopal Venkat Date: 17 August 2012 23:50 Subject: [PATCH 0/3][RFC] devfreq: Add support for devices which can idle To: mturque...@linaro.org, myungjoo@samsung.com, kyungmin.p...@samsung.com, r...@sisk.pl Cc: patc...@linaro.org, linaro-dev@lists.linaro.org, linux...@vger.kernel.org, Rajagopal Venkat This patchset updates devfreq core to add support for devices which can idle. When device idleness is detected perhaps through runtime-pm, need some mechanism to suspend devfreq load monitoring and resume when device is back online. patch 1 adds core design changes mainly moving monitoring logic to ondemand governor, introducing per device work and events for core to governor communication. patch 2 adds devfreq suspend and resume apis. patch 3 does current frequency bug fix. The existing devfreq apis are kept intact. Two new apis devfreq_suspend_device() and devfreq_resume_device() are added to support suspend/resume of device devfreq. -- Rajagopal Venkat (3): devfreq: core updates to support devices which can idle devfreq: Add suspend and resume apis devfreq: Add current freq callback in device profile Documentation/ABI/testing/sysfs-class-devfreq | 33 +- drivers/devfreq/devfreq.c | 448 ++ drivers/devfreq/governor.h| 6 +- drivers/devfreq/governor_performance.c| 34 +- drivers/devfreq/governor_powersave.c | 31 +- drivers/devfreq/governor_simpleondemand.c | 231 +++-- drivers/devfreq/governor_userspace.c | 142 include/linux/devfreq.h | 78 +++-- 8 files changed, 467 insertions(+), 536 deletions(-) -- 1.7.11.3 -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [PATCH 3/3][RFC] devfreq: Add current freq callback in device profile
On 20 August 2012 15:15, 함명주 wrote: >> Devfreq returns governor predicted frequency as current >> frequency via sysfs interface. But device may not support >> all frequencies that governor predicts. As per the design >> its driver responsibility to maintain current frequency >> at which device is operating. So add a callback in device >> profile to fix this. >> >> Signed-off-by: Rajagopal Venkat > > We still need to support "intended frequency". > > The "cur_freq" node is to show the intended frequency. > As told before, you need to make additional API and ABI for the > "actual frequency". > I don't think userspace will be interested in "intended frequency", i.e governor predicted next target frequency unless code is being debugged. More over device may not support all opps that governor predicts. Hence cur_freq node is fixed to show freq at the which device is operating. Let me know if you still think, intended frequency should be exposed to userspace. > > Cheers! > MyungJoo > >> --- >> drivers/devfreq/devfreq.c | 14 -- >> include/linux/devfreq.h | 6 +++--- >> 2 files changed, 15 insertions(+), 5 deletions(-) >> >> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c >> index 375b5aa1..798e8ca 100644 >> --- a/drivers/devfreq/devfreq.c >> +++ b/drivers/devfreq/devfreq.c >> @@ -176,7 +176,6 @@ struct devfreq *devfreq_add_device(struct device *dev, >> devfreq->dev.release = devfreq_dev_release; >> devfreq->profile = profile; >> devfreq->governor = governor; >> - devfreq->previous_freq = profile->initial_freq; >> devfreq->governor_data = data; >> devfreq->nb.notifier_call = devfreq_notifier_call; >> devfreq->min_freq = profile->min_freq; >> @@ -272,7 +271,18 @@ static ssize_t show_governor(struct device *dev, >> static ssize_t show_freq(struct device *dev, >>struct device_attribute *attr, char *buf) >> { >> - return sprintf(buf, "%lu\n", to_devfreq(dev)->previous_freq); >> + int ret; >> + unsigned long freq; >> + struct devfreq *devfreq = to_devfreq(dev); >> + >> + if (devfreq->profile->get_cur_freq) { >> + ret = devfreq->profile->get_cur_freq(devfreq->dev.parent, >> + &freq); >> + if (!ret) >> + return sprintf(buf, "%lu\n", freq); >> + } >> + >> + return sprintf(buf, ""); >> } >> >> static ssize_t store_min_freq(struct device *dev, struct device_attribute >> *attr, >> diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h >> index 7c6517f..43f111f 100644 >> --- a/include/linux/devfreq.h >> +++ b/include/linux/devfreq.h >> @@ -76,6 +76,8 @@ struct devfreq_dev_status { >> * explained above with "DEVFREQ_FLAG_*" macros. >> * @get_dev_status The device should provide the current performance >> * status to devfreq, which is used by governors. >> + * @get_cur_freq The device should provide the current frequency >> + * at which it is operating. >> * @exit An optional callback that is called when devfreq >> * is removing the devfreq object due to error or >> * from devfreq_remove_device() call. If the user >> @@ -91,6 +93,7 @@ struct devfreq_dev_profile { >> int (*target)(struct device *dev, unsigned long *freq, u32 flags); >> int (*get_dev_status)(struct device *dev, >> struct devfreq_dev_status *stat); >> + int (*get_cur_freq)(struct device *dev, unsigned long *freq); >> void (*exit)(struct device *dev); >> }; >> >> @@ -119,7 +122,6 @@ struct devfreq_governor { >> * @nb notifier block used to notify devfreq object that it >> should >> * reevaluate operable frequencies. Devfreq users may use >> * devfreq.nb to the corresponding register notifier call chain. >> - * @previous_freqpreviously configured frequency value. >> * @governor_dataPrivate data of the governor. The devfreq framework >> * does not touch this. >> * @min_freq Limit minimum frequency requested by user (0: none) >> @@ -142,8 +144,6 @@ struct devfreq { >> const struct devfreq_governor *governor; >> struct notifier_block nb; >> >> - unsigned long previous_freq; >> - >> void *governor_data; /* private data for governors */ >> >> unsigned long min_freq; >> -- >> 1.7.11.3 >> >> >> >> >> >> >> >> -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH 1/3][RFC] devfreq: Core updates to support devices which can idle
On 20 August 2012 12:50, 함명주 wrote: > > > Prepare devfreq core framework to support devices which > > can idle. When device idleness is detected perhaps through > > runtime-pm, need some mechanism to suspend devfreq load > > monitoring and resume when device is back online. Present > > code continues monitoring unless device is removed from > > devfreq core. > > > > This patch introduces following updates, > > > > - move device load monitoring logic to ondemand governor as > > it is specific to ondemand. > > We have this ondemand governor in the mainline devfreq. However, > we have (not upstreamed yet) governors with specific purpose (for > GPU or for a specific chip) with load monitoring logic. Although > we don't have them upstreamed yet, why don't you keep the monitoring > logic sharable by other governors. (From today, I'm not objecting to > have individual workqueue, but I still don't want to let each active > governor reimplement the same things.) > If more governors are planned based on load monitoring, possibly ondemand is not good enough even after adding additional configurable parameters. Could you please describe one such case which demand new governor? Please find my next comments. > > > > - devfreq core interacts with governors via events to perform > > specific actions. These events include start/stop devfreq, > > and frequency limit changes outside devfreq. This sets ground > > for adding suspend/resume events. > > event_handler with START/STOP/UPDATE seem fine. > > However, init() and exit() should be different from START/STOP. > We do not need to do init and exit every time when we do runtime > suspend/resume. > I agree and its already taken care in this patch. DEVFREQ_GOV_START : Event for initializing and starting of devfreq governor for a device. Happens only when device is added using devfreq_add_device(). DEVFREQ_GOV_STOP: Event for stopping and uninitialization of devfreq governor for a device. Happens only when device is removed using devfreq_remove_device(). Events introduced in next patch (2/3) - DEVFREQ_GOV_SUSPEND: Event for suspending devfreq of a device. I.e suspending of load monitoring of device in case of ondemand governor. Happens only when devfreq_suspend_device() is called. DEVFREQ_GOV_RESUME: Event for resuming devfreq of a device. I.e continue load monitoring of already suspended device in case of ondemand governor. Happens only when devfreq_resume_device() is called. > > > - use per device work instead of global work to monitor device > > load. This enables suspend/resume of device devfreq and > > reduces monitoring code complexity. > > It's fine to have a delayed work struct per device. > > However, please try to keep as many things/features in devfreq.c as > possible; i.e., reduce features and code size of governors. Because, > we will be supporting various types of devices with devfreq, there > will be various governors and I don't want them to have shared things > reimplemented. Dealing with the delayed work at devfreq.c and let > governors choose to use it (at its struct) or not should be fine. > Delayed work is of only relevance to ondemand governor - justifies why struct delayed work moved from devfreq.c to governor_simpleondemand.c. When delayed work is optional for governors to use, then let governors handle them if needed instead of devfreq core. With this change, we will not be forcing next upcoming devfreq governors to use delayed work for load monitoring(if required) but instead flexibility to have their own mechanisms. Its up to the governors to decide how it wants to do dvfs of a device. But imperative to respond the events. > In this patchset, the size of ondemand governor has been enlarged > too much for that purpose. > > > - Force devfreq users to set min/max supported frequencies in > > device profile to help governors to predict target frequecy > > with in limits. > > Is this really necessary? Yes. Mainly for two reasons, 1. Devfreq core provides sysfs interface for usespace to set min/max operating frequency for a device. These values must be within device supported min/max frequency limits. 2. Governors should know device supported min/max opps and use them where ever needed. Never assume UINT_MAX as max frequency. > > > > > > The devfreq apis are not modified and are kept intact. > > The ABIs are not. > > You can no longer do "# echo 0 > ABI_path" in order to deactivate. Only relevant for ondemand governor. Load monitoring can be deactivated when polling_ms is set to zero. Next version of patch will fix this. Thanks. > > Cheers! > MyungJoo > > > > > Signed-off-by: Rajagopal Venkat > > --- > > ps. please make the patch a bit more readable. (please don't shuffle > the location of pre-existed functions) -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH 2/3][RFC] devfreq: Add suspend and resume apis
On 20 August 2012 15:49, MyungJoo Ham wrote: > > > This patch adds suspend and resume apis needed > > for devices which can idle. Suspend/resume apis > > are called from driver to suspend/resume devfreq > > load monitoring of that device. > > > > Signed-off-by: Rajagopal Venkat > > 1. Some devfreq devices may need their own code to do suspend/resume; e.g., > setting a specific frequency for suspend (especially with suspend-to-RAM). Assuming device driver is using devfreq ondemand governor, when driver detects idleness perhaps through runtime-pm, let driver set specific frequency and then suspend its devfreq. Also let driver resume its devfreq when device is back online. > > 2. Are these new APIs (devfreq_suspend/resume_device()) intended to be > used by runtime_pm and pm(Suspend-to-RAM) callbacks of the parent devices? > If so, could you consider use the structure of runtime-pm (I don't have > an idea on how to do this for now)? For example, when a device is being > suspended, devfreq device's suspend is also called without calling it > explicitly at the device driver's suspend callback. These new apis are not coupled with runtime-pm. Though runtime-pm is good candidate for detecting idleness, drivers can have their own logic. So its at device drivers discretion when to call devfreq_suspend_device() and devfreq_resume_device(). > > 3. As in the patch 1/3, could you consider to integrate class-wide > features in devfreq.c, not in a governor? > Yes, these apis are part of devfreq core. Core sends events to governors for taking specific actions. Again, only governor knows what to do with DEVFREQ_GOV_SUSPEND and DEVFREQ_GOV_RESUME events. For instance ondemand cancels/queues delayed work. > > Cheers! > MyungJoo > > > --- > > drivers/devfreq/devfreq.c | 30 > > ++ > > drivers/devfreq/governor_simpleondemand.c | 15 +++ > > include/linux/devfreq.h | 16 > > 3 files changed, 61 insertions(+) > > > > diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c > > index 5aa23a8..375b5aa1 100644 > > --- a/drivers/devfreq/devfreq.c > > +++ b/drivers/devfreq/devfreq.c > > @@ -233,6 +233,36 @@ int devfreq_remove_device(struct devfreq *devfreq) > > } > > EXPORT_SYMBOL(devfreq_remove_device); > > > > +/** > > + * devfreq_suspend_device() - Suspend devfreq of a device. > > + * @devfreq the devfreq instance to be suspended > > + */ > > +int devfreq_suspend_device(struct devfreq *devfreq) > > +{ > > + if (!devfreq) > > + return -EINVAL; > > + > > + devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_SUSPEND); > > + > > + return 0; > > +} > > +EXPORT_SYMBOL(devfreq_suspend_device); > > + > > +/** > > + * devfreq_resume_device() - Resume devfreq of a device. > > + * @devfreq the devfreq instance to be resumed > > + */ > > +int devfreq_resume_device(struct devfreq *devfreq) > > +{ > > + if (!devfreq) > > + return -EINVAL; > > + > > + devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_RESUME); > > + > > + return 0; > > +} > > +EXPORT_SYMBOL(devfreq_resume_device); > > + > > static ssize_t show_governor(struct device *dev, > >struct device_attribute *attr, char *buf) > > { > > diff --git a/drivers/devfreq/governor_simpleondemand.c > > b/drivers/devfreq/governor_simpleondemand.c > > index 7c70c30..95e4db9 100644 > > --- a/drivers/devfreq/governor_simpleondemand.c > > +++ b/drivers/devfreq/governor_simpleondemand.c > > @@ -221,6 +221,21 @@ static int devfreq_simple_ondemand_func(struct devfreq > > *df, > > ondemand_exit(df); > > break; > > > > + case DEVFREQ_GOV_SUSPEND: > > + if (delayed_work_pending(&data->work)) { > > + data->stop_queuing = true; > > + cancel_delayed_work_sync(&data->work); > > + } > > + break; > > + > > + case DEVFREQ_GOV_RESUME: > > + if (!delayed_work_pending(&data->work)) { > > + data->stop_queuing = false; > > + queue_delayed_work(devfreq_wq, &data->work, > > + msecs_to_jiffies(df->profile->polling_ms)); > > + } > > + break; > > + > > case DEVFREQ_GOV_LIMITS: > > if (delayed_work
Re: Re: [PATCH 1/3][RFC] devfreq: Core updates to support devices which can idle
per device. >> > >> > However, please try to keep as many things/features in devfreq.c as >> > possible; i.e., reduce features and code size of governors. Because, >> > we will be supporting various types of devices with devfreq, there >> > will be various governors and I don't want them to have shared things >> > reimplemented. Dealing with the delayed work at devfreq.c and let >> > governors choose to use it (at its struct) or not should be fine. >> > >> > >> >> Delayed work is of only relevance to ondemand governor - justifies why >> struct delayed work moved from devfreq.c to governor_simpleondemand.c. >> When delayed work is optional for governors to use, then let governors >> handle them if needed instead of devfreq core. >> >> With this change, we will not be forcing next upcoming devfreq governors >> to use delayed work for load monitoring(if required) but instead flexibility >> to have their own mechanisms. Its up to the governors to decide >> how it wants to do dvfs of a device. But imperative to respond the events. > > As mentioned above, please do not assume that the default governors > (drivers/devfreq/governor_*.c) will be only governors available and > ondemand will be the only "active" governor for the future. > > I think it'd be better for the driver writes to reuse code than to > copy and paste the code. > > Some governors may use some other polling/sampling mechanisms; however, > still, providing delayed work at the core does not mean that governors > must use the default delayed work struct. They may simply not use it > as userspace, performance, and powersave do. > If code re-use is only the concern, instead of core handling delayed work which is optional for governors, how about providing load monitoring helper functions to governors? something like, drivers/devfreq/governor.h int devfreq_monitor_start(struct devfreq *devfreq); int devfreq_monitor_stop(struct devfreq *devfreq); int devfreq_monitor_suspend(struct devfreq *devfreq); int devfreq_monitor_resume(struct devfreq *devfreq); These delayed work handling functions will be implemented by devfreq.c and are called from governors in response to events. With this, governors can re-use the delayed work based load monitoring mechanism and also have flexibility to implement their own monitoring mechanism based on their objectives. >> >> > >> > In this patchset, the size of ondemand governor has been enlarged >> > too much for that purpose. > > I said this because I do not want governors to act as if they are core > and I do not want to make writing governors too difficult for device > driver writers. I want them to focus on the "policy" only, not the > mechanism. > >> > >> > >> > > - Force devfreq users to set min/max supported frequencies in >> > > device profile to help governors to predict target frequecy >> > > with in limits. >> > >> > >> > Is this really necessary? >> > >> > >> Yes. Mainly for two reasons, >> >> 1. Devfreq core provides sysfs interface for usespace to set min/max >> operating frequency for a device. These values must be within device >> supported min/max frequency limits. > > No. they do not need to be within device supported limits. > > When I say "CPU should be running at least 50MHz" when the CPU supports > 1000MHz ~ 3000MHz, there is no problem. Running at 1000MHz does not > contradict with the condition. > > When I say "CPU should be running at least 4000MHz" for the same CPU, > It is fine to set the CPU at max available. > >> 2. Governors should know device supported min/max opps and use >> them where ever needed. Never assume UINT_MAX as max frequency. > > The core and governors do not need to know such information. > They only need to provide "recommended" frequency. The corresponding > driver is going to interpret it properly. Whenever we can, > it's better to remove device specific information from governors > and cores as long as it does not significantly increase the > complexity of drivers. > Sorry, but I disagree on this point. Devfreq core should not consider user input for granted and suggest next recommended target freq which is beyond device supported frequency and let driver to interpret it. I don't think passing device supported min/max from driver would increase the complexity of driver. Rather it would help in recommending freq with in limits. This information also helps user space to know the device operating limits. > UINT_MAX means "I recommend to run as fast as possible." Then, the > driver only needs to provide the fastest frequency. The core and > governor does not need to say the specific frequency. > > > Cheers! > MyungJoo > > >> >> >> >> > >> > The devfreq apis are not modified and are kept intact. >> >> >> The ABIs are not. >> >> You can no longer do "# echo 0 > ABI_path" in order to deactivate. >> >> >> Only relevant for ondemand governor. Load monitoring can be >> deactivated when polling_ms is set to zero. Next version of patch >> will fix this. Thanks. >> >> >> >> Cheers! >> MyungJoo >> >> >> > >> > Signed-off-by: Rajagopal Venkat >> > --- >> >> >> ps. please make the patch a bit more readable. (please don't shuffle >> the location of pre-existed functions) >> >> >> >> >> -- >> Regards, >> Rajagopal >> >> >> >> >> >> >> -- >> >> MyungJoo Ham (함명주), PHD >> >> System S/W Lab, S/W Platform Team, Software Center >> Samsung Electronics >> Cell: +82-10-6714-2858 >> >> >> >> >> -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: Re: [PATCH 3/3][RFC] devfreq: Add current freq callback in device profile
On 23 August 2012 12:37, MyungJoo Ham wrote: >> On 20 August 2012 15:15, 함명주 wrote: >> >> Devfreq returns governor predicted frequency as current >> >> frequency via sysfs interface. But device may not support >> >> all frequencies that governor predicts. As per the design >> >> its driver responsibility to maintain current frequency >> >> at which device is operating. So add a callback in device >> >> profile to fix this. >> >> >> >> Signed-off-by: Rajagopal Venkat >> > >> > We still need to support "intended frequency". >> > >> > The "cur_freq" node is to show the intended frequency. >> > As told before, you need to make additional API and ABI for the >> > "actual frequency". >> > >> I don't think userspace will be interested in "intended frequency", i.e >> governor predicted next target frequency unless code is being >> debugged. More over device may not support all opps that >> governor predicts. Hence cur_freq node is fixed to show freq >> at the which device is operating. >> >> Let me know if you still think, intended frequency should be >> exposed to userspace. > > Like CPUfreq, (scaling_cur_freq vs cpuinfo_cur_freq) device driver > developers are often very interested in such values. At least for me, > such information has been very helpful for production kernels. > Ok. I will add new sysfs node in next version. > Cheers! > MyungJoo > >> >> > >> > Cheers! >> > MyungJoo >> > >> >> --- >> >> drivers/devfreq/devfreq.c | 14 -- >> >> include/linux/devfreq.h | 6 +++--- >> >> 2 files changed, 15 insertions(+), 5 deletions(-) >> >> >> >> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c >> >> index 375b5aa1..798e8ca 100644 >> >> --- a/drivers/devfreq/devfreq.c >> >> +++ b/drivers/devfreq/devfreq.c >> >> @@ -176,7 +176,6 @@ struct devfreq *devfreq_add_device(struct device *dev, >> >> devfreq->dev.release = devfreq_dev_release; >> >> devfreq->profile = profile; >> >> devfreq->governor = governor; >> >> - devfreq->previous_freq = profile->initial_freq; >> >> devfreq->governor_data = data; >> >> devfreq->nb.notifier_call = devfreq_notifier_call; >> >> devfreq->min_freq = profile->min_freq; >> >> @@ -272,7 +271,18 @@ static ssize_t show_governor(struct device *dev, >> >> static ssize_t show_freq(struct device *dev, >> >>struct device_attribute *attr, char *buf) >> >> { >> >> - return sprintf(buf, "%lu\n", to_devfreq(dev)->previous_freq); >> >> + int ret; >> >> + unsigned long freq; >> >> + struct devfreq *devfreq = to_devfreq(dev); >> >> + >> >> + if (devfreq->profile->get_cur_freq) { >> >> + ret = devfreq->profile->get_cur_freq(devfreq->dev.parent, >> >> + &freq); >> >> + if (!ret) >> >> + return sprintf(buf, "%lu\n", freq); >> >> + } >> >> + >> >> + return sprintf(buf, ""); >> >> } >> >> >> >> static ssize_t store_min_freq(struct device *dev, struct >> >> device_attribute *attr, >> >> diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h >> >> index 7c6517f..43f111f 100644 >> >> --- a/include/linux/devfreq.h >> >> +++ b/include/linux/devfreq.h >> >> @@ -76,6 +76,8 @@ struct devfreq_dev_status { >> >> * explained above with "DEVFREQ_FLAG_*" macros. >> >> * @get_dev_status The device should provide the current performance >> >> * status to devfreq, which is used by governors. >> >> + * @get_cur_freq The device should provide the current frequency >> >> + * at which it is operating. >> >> * @exit An optional callback that is called when devfreq >> >> * is removing the devfreq object due to error or >> >> * from devfreq_remove_device() call. If the user >> >> @@ -91,6 +93,7 @@ struct devfreq_dev_profile { >> &g
Re: Re: Re: [PATCH 1/3][RFC] devfreq: Core updates to support devices which can idle
governors can re-use the delayed work based load monitoring >> mechanism and also have flexibility to implement their own monitoring >> mechanism based on their objectives. >> >> >> >> >> > >> >> > In this patchset, the size of ondemand governor has been enlarged >> >> > too much for that purpose. >> > >> > I said this because I do not want governors to act as if they are core >> > and I do not want to make writing governors too difficult for device >> > driver writers. I want them to focus on the "policy" only, not the >> > mechanism. >> > >> >> > >> >> > >> >> > > - Force devfreq users to set min/max supported frequencies in >> >> > > device profile to help governors to predict target frequecy >> >> > > with in limits. >> >> > >> >> > >> >> > Is this really necessary? >> >> > >> >> > >> >> Yes. Mainly for two reasons, >> >> >> >> 1. Devfreq core provides sysfs interface for usespace to set min/max >> >> operating frequency for a device. These values must be within device >> >> supported min/max frequency limits. >> > >> > No. they do not need to be within device supported limits. >> > >> > When I say "CPU should be running at least 50MHz" when the CPU supports >> > 1000MHz ~ 3000MHz, there is no problem. Running at 1000MHz does not >> > contradict with the condition. >> > >> > When I say "CPU should be running at least 4000MHz" for the same CPU, >> > It is fine to set the CPU at max available. >> > >> >> 2. Governors should know device supported min/max opps and use >> >> them where ever needed. Never assume UINT_MAX as max frequency. >> > >> > The core and governors do not need to know such information. >> > They only need to provide "recommended" frequency. The corresponding >> > driver is going to interpret it properly. Whenever we can, >> > it's better to remove device specific information from governors >> > and cores as long as it does not significantly increase the >> > complexity of drivers. >> > >> >> Sorry, but I disagree on this point. Devfreq core should not consider user >> input for granted and suggest next recommended target freq which is beyond >> device supported frequency and let driver to interpret it. I don't think >> passing >> device supported min/max from driver would increase the complexity of driver. >> Rather it would help in recommending freq with in limits. >> >> This information also helps user space to know the device operating limits. > > With the optional frequency statistics support proposed by Jonghwa Lee, > devfreq.c is going to be accepting the list of operable frequencies, > where the max/min values are trivially extracted. > With this optional values, we can create sysfs entries to show max/min > possible or operable frequencies. (they are difference from the > min_freq and max_freq, which are user's limits) > Yes agree. > I still don't understand why enforcing devfreq device drivers to > declare min/max frequencies to devfreq core. Because the devfreq > device drivers already know the hardware limits (otherwise, we > are not able to enforce them to do so), it is not beneficial for > the device driver to let devfreq core provide such limits to > the device drivers (they already know). > > Yes, passing values filtered by min/max values reported by device drivers > from core does not increase the complexity at device drivers. However, it > adds codes at _every_ governor to filter the values, which is going to > be filtered at each device driver anyway. For devices supporting 100, 200, > 400 MHz, governors will pass 150, 151, 201, 203, and such even if we > filter min/max. > > I just don't see a benefic to enforce device drivers to declare > min/max to the core and enforce governors to recommend between the > restricted values, which are going to be regulated at device drivers > anyway. (and very trivial to be regulated by drivers) > > If this is meant to show the min/max values to the users, making it optional > should be enough. > > Besides, allowing users to enter any arbitrary large values (e.g., 99) > to make it run at maximum frequency and enter any small values (e.g., 1) to > make it run at minimum frequency makes things easier. I don't see why > we should get them errors for such inputs. > > > Cheers! > MyungJoo > >> >> > UINT_MAX means "I recommend to run as fast as possible." Then, the >> > driver only needs to provide the fastest frequency. The core and >> > governor does not need to say the specific frequency. >> > >> > >> > Cheers! >> > MyungJoo >> > >> > >> >> >> >> >> >> >> >> > >> >> > The devfreq apis are not modified and are kept intact. >> >> >> >> >> >> The ABIs are not. >> >> >> >> You can no longer do "# echo 0 > ABI_path" in order to deactivate. >> >> >> >> >> >> Only relevant for ondemand governor. Load monitoring can be >> >> deactivated when polling_ms is set to zero. Next version of patch >> >> will fix this. Thanks. >> >> >> >> >> >> >> >> Cheers! >> >> MyungJoo >> >> >> >> >> >> > >> >> > Signed-off-by: Rajagopal Venkat >> >> > --- >> >> >> >> >> >> ps. please make the patch a bit more readable. (please don't shuffle >> >> the location of pre-existed functions) >> >> >> >> >> >> >> >> >> >> -- >> >> Regards, >> >> Rajagopal >> >> >> >> >> >> >> >> >> >> >> >> >> >> -- >> >> >> >> MyungJoo Ham (함명주), PHD >> >> >> >> System S/W Lab, S/W Platform Team, Software Center >> >> Samsung Electronics >> >> Cell: +82-10-6714-2858 >> >> >> >> >> >> >> >> >> >> >> >> >> >> -- >> Regards, >> Rajagopal >> >> >> >> >> >> >> -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH 0/3] devfreq: Add support for devices which can idle
This patchset updates devfreq core to add support for devices which can idle. When device idleness is detected perhaps through runtime-pm, need some mechanism to suspend devfreq load monitoring and resume when device is back online. patch 1 introduce core design changes - per device work, decouple delayed work from core and event based interaction. patch 2 add devfreq suspend and resume apis. patch 3 current frequency bug fix and add new sysfs attribute for governor predicted next target frequency. The existing devfreq apis are kept intact. Two new apis devfreq_suspend_device() and devfreq_resume_device() are added to support suspend/resume of device devfreq. -- Rajagopal Venkat (3): devfreq: core updates to support devices which can idle devfreq: Add suspend and resume apis devfreq: Add current freq callback in device profile Documentation/ABI/testing/sysfs-class-devfreq | 7 + drivers/devfreq/devfreq.c | 412 +++--- drivers/devfreq/governor.h| 11 + drivers/devfreq/governor_performance.c| 16 +- drivers/devfreq/governor_powersave.c | 16 +- drivers/devfreq/governor_simpleondemand.c | 42 +++ drivers/devfreq/governor_userspace.c | 23 +- include/linux/devfreq.h | 46 ++- 8 files changed, 291 insertions(+), 282 deletions(-) -- 1.7.11.3 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH 2/3] devfreq: Add suspend and resume apis
Add devfreq suspend/resume apis for devfreq users. This patch supports suspend and resume of devfreq load monitoring, required for devices which can idle. Signed-off-by: Rajagopal Venkat --- drivers/devfreq/devfreq.c | 26 ++ drivers/devfreq/governor.h| 2 ++ drivers/devfreq/governor_simpleondemand.c | 9 + include/linux/devfreq.h | 12 4 files changed, 49 insertions(+) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index be524c7..3a5f126 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -365,6 +365,32 @@ int devfreq_remove_device(struct devfreq *devfreq) } EXPORT_SYMBOL(devfreq_remove_device); +/** + * devfreq_suspend_device() - Suspend devfreq of a device. + * @devfreqthe devfreq instance to be suspended + */ +int devfreq_suspend_device(struct devfreq *devfreq) +{ + if (!devfreq) + return -EINVAL; + + return devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_SUSPEND); +} +EXPORT_SYMBOL(devfreq_suspend_device); + +/** + * devfreq_resume_device() - Resume devfreq of a device. + * @devfreqthe devfreq instance to be resumed + */ +int devfreq_resume_device(struct devfreq *devfreq) +{ + if (!devfreq) + return -EINVAL; + + return devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_RESUME); +} +EXPORT_SYMBOL(devfreq_resume_device); + static ssize_t show_governor(struct device *dev, struct device_attribute *attr, char *buf) { diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h index 4a86af7..7dbbdfc 100644 --- a/drivers/devfreq/governor.h +++ b/drivers/devfreq/governor.h @@ -22,6 +22,8 @@ #define DEVFREQ_GOV_START 0x1 #define DEVFREQ_GOV_STOP 0x2 #define DEVFREQ_GOV_INTERVAL 0x3 +#define DEVFREQ_GOV_SUSPEND0x4 +#define DEVFREQ_GOV_RESUME 0x5 /* Caution: devfreq->lock must be locked before calling update_devfreq */ extern int update_devfreq(struct devfreq *devfreq); diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c index 9802bf9..35b8e8e 100644 --- a/drivers/devfreq/governor_simpleondemand.c +++ b/drivers/devfreq/governor_simpleondemand.c @@ -113,6 +113,15 @@ int devfreq_simple_ondemand_handler(struct devfreq *devfreq, else ret = devfreq_monitor_resume(devfreq); break; + + case DEVFREQ_GOV_SUSPEND: + ret = devfreq_monitor_suspend(devfreq); + break; + + case DEVFREQ_GOV_RESUME: + ret = devfreq_monitor_resume(devfreq); + break; + default: break; } diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 7a11c3e..7c7e179 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -155,6 +155,8 @@ extern struct devfreq *devfreq_add_device(struct device *dev, const struct devfreq_governor *governor, void *data); extern int devfreq_remove_device(struct devfreq *devfreq); +extern int devfreq_suspend_device(struct devfreq *devfreq); +extern int devfreq_resume_device(struct devfreq *devfreq); /* Helper functions for devfreq user device driver with OPP. */ extern struct opp *devfreq_recommended_opp(struct device *dev, @@ -208,6 +210,16 @@ static int devfreq_remove_device(struct devfreq *devfreq) return 0; } +static int devfreq_suspend_device(struct devfreq *devfreq) +{ + return 0; +} + +static int devfreq_resume_device(struct devfreq *devfreq) +{ + return 0; +} + static struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, u32 flags) { -- 1.7.11.3 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH 1/3] devfreq: core updates to support devices which can idle
Prepare devfreq core framework to support devices which can idle. When device idleness is detected perhaps through runtime-pm, need some mechanism to suspend devfreq load monitoring and resume back when device is online. Present code continues monitoring unless device is removed from devfreq core. This patch introduces following design changes, - use per device work instead of global work to monitor device load. This enables suspend/resume of device devfreq and reduces monitoring code complexity. - decouple delayed work based load monitoring logic from core by introducing helpers functions to be used by governors. This provides flexibility for governors either to use delayed work based monitoring functions or to implement their own mechanism. - devfreq core interacts with governors via events to perform specific actions. These events include start/stop devfreq. This sets ground for adding suspend/resume events. The devfreq apis are not modified and are kept intact. Signed-off-by: Rajagopal Venkat --- drivers/devfreq/devfreq.c | 376 ++ drivers/devfreq/governor.h| 9 + drivers/devfreq/governor_performance.c| 16 +- drivers/devfreq/governor_powersave.c | 16 +- drivers/devfreq/governor_simpleondemand.c | 33 +++ drivers/devfreq/governor_userspace.c | 23 +- include/linux/devfreq.h | 31 +-- 7 files changed, 220 insertions(+), 284 deletions(-) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index b146d76..be524c7 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -30,17 +30,11 @@ struct class *devfreq_class; /* - * devfreq_work periodically monitors every registered device. - * The minimum polling interval is one jiffy. The polling interval is - * determined by the minimum polling period among all polling devfreq - * devices. The resolution of polling interval is one jiffy. + * devfreq core provides delayed work based load monitoring helper + * functions. Governors can use these or can implement their own + * monitoring mechanism. */ -static bool polling; static struct workqueue_struct *devfreq_wq; -static struct delayed_work devfreq_work; - -/* wait removing if this is to be removed */ -static struct devfreq *wait_remove_device; /* The list of all device-devfreq */ static LIST_HEAD(devfreq_list); @@ -72,6 +66,8 @@ static struct devfreq *find_device_devfreq(struct device *dev) return ERR_PTR(-ENODEV); } +/* Load monitoring helper functions for governors use */ + /** * update_devfreq() - Reevaluate the device and configure frequency. * @devfreq: the devfreq instance. @@ -121,6 +117,90 @@ int update_devfreq(struct devfreq *devfreq) } /** + * devfreq_monitor() - Periodically poll devfreq objects. + * @work: the work struct used to run devfreq_monitor periodically. + * + */ +static void devfreq_monitor(struct work_struct *work) +{ + int err; + struct devfreq *devfreq = container_of(work, + struct devfreq, work.work); + + mutex_lock(&devfreq->lock); + err = update_devfreq(devfreq); + mutex_unlock(&devfreq->lock); + if (err) + dev_err(&devfreq->dev, "dvfs failed with (%d) error\n", err); + + queue_delayed_work(devfreq_wq, &devfreq->work, + msecs_to_jiffies(devfreq->profile->polling_ms)); +} + +/** + * devfreq_monitor_start() - Start load monitoring of devfreq instance + * using default delayed work + * @devfreq: the devfreq instance. + * + * Returns 0 if monitoring started, non-zero otherwise. + * Note: This function is exported for governors. + */ +int devfreq_monitor_start(struct devfreq *devfreq) +{ + INIT_DEFERRABLE_WORK(&devfreq->work, devfreq_monitor); + return !queue_delayed_work(devfreq_wq, &devfreq->work, + msecs_to_jiffies(devfreq->profile->polling_ms)); +} + +/** + * devfreq_monitor_stop() - Stop load monitoring of a devfreq instance + * @devfreq: the devfreq instance. + * + * Note: This function is exported for governors. + */ +void devfreq_monitor_stop(struct devfreq *devfreq) +{ + cancel_delayed_work_sync(&devfreq->work); +} + +/** + * devfreq_monitor_suspend() - Suspend load monitoring of a devfreq instance + * @devfreq:the devfreq instance. + * + * Note: This function is exported for governors. + */ +int devfreq_monitor_suspend(struct devfreq *devfreq) +{ + int ret = -EPERM; + + if (delayed_work_pending(&devfreq->work)) { + cancel_delayed_work_sync(&devfreq->work); + ret = 0; + } + + return ret; +} + +/** + * devfreq_monitor_resume() - Resume load monitoring of a devfreq instance + * @devfreq:the devfreq instance. + * + * Returns 0 if monitoring re-started, non-zero otherwise
[PATCH 3/3] devfreq: Add current freq callback in device profile
Devfreq returns governor predicted frequency as current frequency via sysfs interface. But device may not support all frequencies that governor predicts. Its driver responsibility to maintain current frequency at which device is operating. Add a callback in device profile to fix this. Also add a new sysfs node to expose governor predicted next target frequency. Signed-off-by: Rajagopal Venkat --- Documentation/ABI/testing/sysfs-class-devfreq | 7 +++ drivers/devfreq/devfreq.c | 14 ++ include/linux/devfreq.h | 3 +++ 3 files changed, 24 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq index 23d78b5..9df5205 100644 --- a/Documentation/ABI/testing/sysfs-class-devfreq +++ b/Documentation/ABI/testing/sysfs-class-devfreq @@ -21,6 +21,13 @@ Description: The /sys/class/devfreq/.../cur_freq shows the current frequency of the corresponding devfreq object. +What: /sys/class/devfreq/.../target_freq +Date: September 2012 +Contact: MyungJoo Ham +Description: + The /sys/class/devfreq/.../target_freq shows the next governor + predicted target frequency of the corresponding devfreq object. + What: /sys/class/devfreq/.../central_polling Date: September 2011 Contact: MyungJoo Ham diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 3a5f126..55e9046 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -400,6 +400,19 @@ static ssize_t show_governor(struct device *dev, static ssize_t show_freq(struct device *dev, struct device_attribute *attr, char *buf) { + unsigned long freq; + struct devfreq *devfreq = to_devfreq(dev); + + if (devfreq->profile->get_cur_freq) + if (!devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq)) + return sprintf(buf, "%lu\n", freq); + + return sprintf(buf, ""); +} + +static ssize_t show_target_freq(struct device *dev, + struct device_attribute *attr, char *buf) +{ return sprintf(buf, "%lu\n", to_devfreq(dev)->previous_freq); } @@ -503,6 +516,7 @@ static ssize_t show_max_freq(struct device *dev, struct device_attribute *attr, static struct device_attribute devfreq_attrs[] = { __ATTR(governor, S_IRUGO, show_governor, NULL), __ATTR(cur_freq, S_IRUGO, show_freq, NULL), + __ATTR(target_freq, S_IRUGO, show_target_freq, NULL), __ATTR(polling_interval, S_IRUGO | S_IWUSR, show_polling_interval, store_polling_interval), __ATTR(min_freq, S_IRUGO | S_IWUSR, show_min_freq, store_min_freq), diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 7c7e179..d12ed41 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -66,6 +66,8 @@ struct devfreq_dev_status { * explained above with "DEVFREQ_FLAG_*" macros. * @get_dev_status The device should provide the current performance * status to devfreq, which is used by governors. + * @get_cur_freq The device should provide the current frequency + * at which it is operating. * @exit An optional callback that is called when devfreq * is removing the devfreq object due to error or * from devfreq_remove_device() call. If the user @@ -79,6 +81,7 @@ struct devfreq_dev_profile { int (*target)(struct device *dev, unsigned long *freq, u32 flags); int (*get_dev_status)(struct device *dev, struct devfreq_dev_status *stat); + int (*get_cur_freq)(struct device *dev, unsigned long *freq); void (*exit)(struct device *dev); }; -- 1.7.11.3 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[Powertop][PATCH] Fix timer and work perf events timestamp tracing
Incorrect timer and work perf events timestamp tracing is one of the reason for reporting usage over 100%. This patch will resolve the issue by - rejecting the events for which entry timestamp is not recorded. Currently these events exit timestamp itself is considered as usage period resulting in over 100% usage. - clearing event timestamps from global map at the end of each measurement to avoid collision with earlier recorded timestamps. Signed-off-by: Rajagopal Venkat --- src/process/timer.cpp | 5 - src/process/work.cpp | 5 - 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/process/timer.cpp b/src/process/timer.cpp index 8917490..db074c4 100644 --- a/src/process/timer.cpp +++ b/src/process/timer.cpp @@ -79,7 +79,8 @@ uint64_t timer::done(uint64_t time, uint64_t timer_struct) { int64_t delta; - if (running_since[timer_struct] > time) + if (running_since.find(timer_struct) == running_since.end() || + running_since[timer_struct] > time) return 0; delta = time - running_since[timer_struct]; @@ -147,6 +148,8 @@ void clear_timers(void) all_timers.erase(it); it = all_timers.begin(); } + + running_since.clear(); } bool timer::is_deferred(void) diff --git a/src/process/work.cpp b/src/process/work.cpp index 82f13a2..e436643 100644 --- a/src/process/work.cpp +++ b/src/process/work.cpp @@ -56,7 +56,8 @@ uint64_t work::done(uint64_t time, uint64_t work_struct) { int64_t delta; - if (running_since[work_struct] > time) + if (running_since.find(work_struct) == running_since.end() || + running_since[work_struct] > time) return 0; delta = time - running_since[work_struct]; @@ -102,6 +103,8 @@ void clear_work(void) all_work.erase(it); it = all_work.begin(); } + + running_since.clear(); } -- 1.7.11.3 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [Powertop] [PATCH] Fix timer and work perf events timestamp tracing
On 5 September 2012 18:14, Sergey Senozhatsky wrote: > Hi, > > On (09/05/12 15:52), Rajagopal Venkat wrote: >> Incorrect timer and work perf events timestamp tracing is one >> of the reason for reporting usage over 100%. This patch will >> resolve the issue by >> - rejecting the events for which entry timestamp is not recorded. > > how is that possible? > do you mean erasing between measurements? > > > schematically: > > measure0: > > ev1.start > ev2.start > ev2.end > > processing > clear > > > measure1: > ev3.start > ev1.end <<<<< evX.end <<<<< These events are causing numbers to go wrong. delta = time - running_since[timer_struct]; accumulated_runtime += delta Since running_since[timer_struct] returns zero, event timestamp itself gets added to accumulated_runtime, causing usage to go high something like 2693%. > ev3.end > > processing > clear > > > if so, then we're loosing events, which is no good. reporting less than 100% > is ok, but reporting less than real is not. I did thought of it. Yes, agree that, we are loosing events for which start timestamp is not recorded. I believe correct solution would be to consider these events end timestamp relative to first_stamp(src/process/do_process.cpp). > > > p.s. > I'll try to check emails, but most probably will be off-line most of the day. > > -ss > > >> Currently these events exit timestamp itself is considered as >> usage period resulting in over 100% usage. >> - clearing event timestamps from global map at the end of each >> measurement to avoid collision with earlier recorded timestamps. >> >> Signed-off-by: Rajagopal Venkat >> --- >> src/process/timer.cpp | 5 - >> src/process/work.cpp | 5 - >> 2 files changed, 8 insertions(+), 2 deletions(-) >> >> diff --git a/src/process/timer.cpp b/src/process/timer.cpp >> index 8917490..db074c4 100644 >> --- a/src/process/timer.cpp >> +++ b/src/process/timer.cpp >> @@ -79,7 +79,8 @@ uint64_t timer::done(uint64_t time, uint64_t timer_struct) >> { >> int64_t delta; >> >> - if (running_since[timer_struct] > time) >> + if (running_since.find(timer_struct) == running_since.end() || >> + running_since[timer_struct] > time) >> return 0; >> >> delta = time - running_since[timer_struct]; >> @@ -147,6 +148,8 @@ void clear_timers(void) >> all_timers.erase(it); >> it = all_timers.begin(); >> } >> + >> + running_since.clear(); >> } >> >> bool timer::is_deferred(void) >> diff --git a/src/process/work.cpp b/src/process/work.cpp >> index 82f13a2..e436643 100644 >> --- a/src/process/work.cpp >> +++ b/src/process/work.cpp >> @@ -56,7 +56,8 @@ uint64_t work::done(uint64_t time, uint64_t work_struct) >> { >> int64_t delta; >> >> - if (running_since[work_struct] > time) >> + if (running_since.find(work_struct) == running_since.end() || >> + running_since[work_struct] > time) >> return 0; >> >> delta = time - running_since[work_struct]; >> @@ -102,6 +103,8 @@ void clear_work(void) >> all_work.erase(it); >> it = all_work.begin(); >> } >> + >> + running_since.clear(); >> } >> >> >> -- >> 1.7.11.3 >> >> ___ >> PowerTop mailing list >> power...@lists.01.org >> https://lists.01.org/mailman/listinfo/powertop >> -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [Powertop] [PATCH] Fix timer and work perf events timestamp tracing
On 5 September 2012 22:39, Arjan van de Ven wrote: > On 9/5/2012 9:56 AM, Rajagopal Venkat wrote: >>> measure1: >>> ev3.start >>> ev1.end <<<<< >> >> evX.end <<<<< >> These events are causing numbers to go wrong. > > but out of a 20 second window.. this is a tiny tiny window... > if you see 100.1% I'd buy this reasoning. > but you're seeing much more than that. How about generating a report for 1sec duration? Since timestamp itself is added to accumulated_runtime, the usage percentage is really dependent on event end timestamp value. > > >>> >>> if so, then we're loosing events, which is no good. reporting less than 100% >>> is ok, but reporting less than real is not. >> >> I did thought of it. Yes, agree that, we are loosing events for which >> start timestamp > > we can't lose those! > those are the events that give us the initial CPU frequency in the window > etc > Yes agree. I will submit the next version patch considering those events end timestamp relative to first_stamp(src/process/do_process.cpp). -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [Powertop] [PATCH] Fix timer and work perf events timestamp tracing
On 5 September 2012 22:52, Arjan van de Ven wrote: > On 9/5/2012 10:19 AM, Rajagopal Venkat wrote: >> On 5 September 2012 22:39, Arjan van de Ven wrote: >>> On 9/5/2012 9:56 AM, Rajagopal Venkat wrote: >>>>> measure1: >>>>> ev3.start >>>>> ev1.end <<<<< >>>> >>>> evX.end <<<<< >>>> These events are causing numbers to go wrong. >>> >>> but out of a 20 second window.. this is a tiny tiny window... >>> if you see 100.1% I'd buy this reasoning. >>> but you're seeing much more than that. >> >> How about generating a report for 1sec duration? > > even for 1 second... still it's miniscule compared to this whole 1 second > the amount of setup/teardown time just is not that huge. > Here are some perf timestamps, (3979299431) (3979303554) (4079217947) (4091306943) (4091322535) (4091336882) When 1sec report is generated and if above timestamp gets added to timer accumulated_runtime, no wonder why such huge usage is reported. -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[Powertop][PATCH v1] Fix timer and work perf events timestamp tracing
Fix timer and work perf events timestamp tracing by - considering event exit timestamp relative to measurement first timestamp for events which entry timestamp is not recorded. Currently these events exit timestamp itself is considered as usage period resulting in false usage report. - clearing event timestamps from global map at the end of each measurement to avoid collision with earlier recorded timestamps. Signed-off-by: Rajagopal Venkat --- src/process/do_process.cpp | 12 src/process/timer.cpp | 4 src/process/work.cpp | 4 3 files changed, 20 insertions(+) diff --git a/src/process/do_process.cpp b/src/process/do_process.cpp index cb7c672..eaef7f1 100644 --- a/src/process/do_process.cpp +++ b/src/process/do_process.cpp @@ -490,6 +490,10 @@ void perf_process_bundle::handle_trace_point(void *trace, int cpu, uint64_t time } pop_consumer(cpu); t = timer->done(time, tmr); + if (t == ~0ULL) { + timer->fire(first_stamp, tmr); + t = timer->done(time, tmr); + } consumer_child_time(cpu, t); } else if (strcmp(event->name, "hrtimer_expire_entry") == 0) { @@ -532,6 +536,10 @@ void perf_process_bundle::handle_trace_point(void *trace, int cpu, uint64_t time pop_consumer(cpu); t = timer->done(time, tmr); + if (t == ~0ULL) { + timer->fire(first_stamp, tmr); + t = timer->done(time, tmr); + } consumer_child_time(cpu, t); } else if (strcmp(event->name, "workqueue_execute_start") == 0) { @@ -575,6 +583,10 @@ void perf_process_bundle::handle_trace_point(void *trace, int cpu, uint64_t time } pop_consumer(cpu); t = work->done(time, wk); + if (t == ~0ULL) { + work->fire(first_stamp, wk); + t = work->done(time, wk); + } consumer_child_time(cpu, t); } else if (strcmp(event->name, "cpu_idle") == 0) { diff --git a/src/process/timer.cpp b/src/process/timer.cpp index 8917490..1ca8c25 100644 --- a/src/process/timer.cpp +++ b/src/process/timer.cpp @@ -79,6 +79,9 @@ uint64_t timer::done(uint64_t time, uint64_t timer_struct) { int64_t delta; + if (running_since.find(timer_struct) == running_since.end()) + return ~0ULL; + if (running_since[timer_struct] > time) return 0; @@ -147,6 +150,7 @@ void clear_timers(void) all_timers.erase(it); it = all_timers.begin(); } + running_since.clear(); } bool timer::is_deferred(void) diff --git a/src/process/work.cpp b/src/process/work.cpp index 82f13a2..e62e5d3 100644 --- a/src/process/work.cpp +++ b/src/process/work.cpp @@ -56,6 +56,9 @@ uint64_t work::done(uint64_t time, uint64_t work_struct) { int64_t delta; + if (running_since.find(work_struct) == running_since.end()) + return ~0ULL; + if (running_since[work_struct] > time) return 0; @@ -102,6 +105,7 @@ void clear_work(void) all_work.erase(it); it = all_work.begin(); } + running_since.clear(); } -- 1.7.11.3 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [Powertop] [PATCH] Fix timer and work perf events timestamp tracing
On 5 September 2012 23:36, Arjan van de Ven wrote: > On 9/5/2012 10:45 AM, Rajagopal Venkat wrote: >> On 5 September 2012 22:52, Arjan van de Ven wrote: >>> On 9/5/2012 10:19 AM, Rajagopal Venkat wrote: >>>> On 5 September 2012 22:39, Arjan van de Ven wrote: >>>>> On 9/5/2012 9:56 AM, Rajagopal Venkat wrote: >>>>>>> measure1: >>>>>>> ev3.start >>>>>>> ev1.end <<<<< >>>>>> >>>>>> evX.end <<<<< >>>>>> These events are causing numbers to go wrong. >>>>> >>>>> but out of a 20 second window.. this is a tiny tiny window... >>>>> if you see 100.1% I'd buy this reasoning. >>>>> but you're seeing much more than that. >>>> >>>> How about generating a report for 1sec duration? >>> >>> even for 1 second... still it's miniscule compared to this whole 1 second >>> the amount of setup/teardown time just is not that huge. >>> >> Here are some perf timestamps, >> (3979299431) >> (3979303554) >> (4079217947) >> (4091306943) >> (4091322535) >> (4091336882) >> When 1sec report is generated and if above timestamp gets >> added to timer accumulated_runtime, no wonder why such >> huge usage is reported. > > question is... how did these get here? > is the kernel reporting garbage time > > oops wrong numbers! Here is the data captured for timer::delayed_work_timer_fn events on snowball. Prints are from timer::done() of src/process/timer.cpp. Measurement start time(first_stamp) - (4379576721191) Measurement end time(last_stamp) - (4380607421874) accumulated end_timestampstart_timestamp runtime (61035) (4379586975097) (4379586914062) (122071) (4379607116699) (4379607055663) (152589) (4379607177734) (4379607147216) (183106) (4379627105712) (4379627075195) (244142) (4379647186279) (4379647125243) (274660) (4380506896972) (4380506866454) (274660) (4380506927490) (4380506927490) (305177) (4380506958007) (4380506927490) (305177) (4380506988525) (4380506988525) (4380507324219) (4380507019042) (0)<<<<<<< (4380507354736) (4380596923827) (4380596893310) (4380507415771) (4380606964111) (4380606903076) cpu usage from total_cpu_time() - (425033.990889%) -- As mentioned in my earlier comments, next patch will be submitted to handle these events(for which start time is not recorded) instead of ignoring them. -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [PATCH 1/3] devfreq: core updates to support devices which can idle
On 10 September 2012 03:16, Rafael J. Wysocki wrote: > On Monday, September 03, 2012, Rajagopal Venkat wrote: >> Prepare devfreq core framework to support devices which >> can idle. When device idleness is detected perhaps through >> runtime-pm, need some mechanism to suspend devfreq load >> monitoring and resume back when device is online. Present >> code continues monitoring unless device is removed from >> devfreq core. >> >> This patch introduces following design changes, >> >> - use per device work instead of global work to monitor device >> load. This enables suspend/resume of device devfreq and >> reduces monitoring code complexity. >> - decouple delayed work based load monitoring logic from core >> by introducing helpers functions to be used by governors. This >> provides flexibility for governors either to use delayed work >> based monitoring functions or to implement their own mechanism. >> - devfreq core interacts with governors via events to perform >> specific actions. These events include start/stop devfreq. >> This sets ground for adding suspend/resume events. >> >> The devfreq apis are not modified and are kept intact. >> >> Signed-off-by: Rajagopal Venkat > > This one looks like a nice simplification. I wonder if everyone in the CC > list > is fine with it? > > One remark below. > >> --- >> drivers/devfreq/devfreq.c | 376 >> ++ >> drivers/devfreq/governor.h| 9 + >> drivers/devfreq/governor_performance.c| 16 +- >> drivers/devfreq/governor_powersave.c | 16 +- >> drivers/devfreq/governor_simpleondemand.c | 33 +++ >> drivers/devfreq/governor_userspace.c | 23 +- >> include/linux/devfreq.h | 31 +-- >> 7 files changed, 220 insertions(+), 284 deletions(-) >> >> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c >> index b146d76..be524c7 100644 >> --- a/drivers/devfreq/devfreq.c >> +++ b/drivers/devfreq/devfreq.c >> @@ -30,17 +30,11 @@ >> struct class *devfreq_class; >> >> /* >> - * devfreq_work periodically monitors every registered device. >> - * The minimum polling interval is one jiffy. The polling interval is >> - * determined by the minimum polling period among all polling devfreq >> - * devices. The resolution of polling interval is one jiffy. >> + * devfreq core provides delayed work based load monitoring helper >> + * functions. Governors can use these or can implement their own >> + * monitoring mechanism. >> */ >> -static bool polling; >> static struct workqueue_struct *devfreq_wq; >> -static struct delayed_work devfreq_work; >> - >> -/* wait removing if this is to be removed */ >> -static struct devfreq *wait_remove_device; >> >> /* The list of all device-devfreq */ >> static LIST_HEAD(devfreq_list); >> @@ -72,6 +66,8 @@ static struct devfreq *find_device_devfreq(struct device >> *dev) >> return ERR_PTR(-ENODEV); >> } >> >> +/* Load monitoring helper functions for governors use */ >> + >> /** >> * update_devfreq() - Reevaluate the device and configure frequency. >> * @devfreq: the devfreq instance. >> @@ -121,6 +117,90 @@ int update_devfreq(struct devfreq *devfreq) >> } >> >> /** >> + * devfreq_monitor() - Periodically poll devfreq objects. >> + * @work: the work struct used to run devfreq_monitor periodically. >> + * >> + */ >> +static void devfreq_monitor(struct work_struct *work) >> +{ >> + int err; >> + struct devfreq *devfreq = container_of(work, >> + struct devfreq, work.work); >> + >> + mutex_lock(&devfreq->lock); >> + err = update_devfreq(devfreq); >> + mutex_unlock(&devfreq->lock); >> + if (err) >> + dev_err(&devfreq->dev, "dvfs failed with (%d) error\n", err); >> + >> + queue_delayed_work(devfreq_wq, &devfreq->work, >> + >> msecs_to_jiffies(devfreq->profile->polling_ms)); >> +} >> + >> +/** >> + * devfreq_monitor_start() - Start load monitoring of devfreq instance >> + * using default delayed work >> + * @devfreq: the devfreq instance. >> + * >> + * Returns 0 if monitoring started, non-zero otherwise. >> + * Note: This function is exported for governors. >> + */ >> +int devfreq_monitor_start(struct devfreq *devfreq) &g
Re: [PATCH 2/3] devfreq: Add suspend and resume apis
On 10 September 2012 03:21, Rafael J. Wysocki wrote: > On Monday, September 03, 2012, Rajagopal Venkat wrote: >> Add devfreq suspend/resume apis for devfreq users. This patch >> supports suspend and resume of devfreq load monitoring, required >> for devices which can idle. >> >> Signed-off-by: Rajagopal Venkat > > I'd call the new functions devfreq_dev_suspend() and devfreq_dev_resume(), > respectively, because the names you're using currently suggest that the > device itself is suspended/resumed, which isn't the case. devfreq_add_device() and devfreq_remove_device() are two existing APIs. I did follow same naming pattern to maintain uniformity and introduced devfreq_suspend_device() and devfreq_resume_device() functions. Do you suggest to follow devfreq_dev_xxx pattern even for existing APIs? > > Thanks, > Rafael > > >> --- >> drivers/devfreq/devfreq.c | 26 ++ >> drivers/devfreq/governor.h| 2 ++ >> drivers/devfreq/governor_simpleondemand.c | 9 + >> include/linux/devfreq.h | 12 >> 4 files changed, 49 insertions(+) >> >> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c >> index be524c7..3a5f126 100644 >> --- a/drivers/devfreq/devfreq.c >> +++ b/drivers/devfreq/devfreq.c >> @@ -365,6 +365,32 @@ int devfreq_remove_device(struct devfreq *devfreq) >> } >> EXPORT_SYMBOL(devfreq_remove_device); >> >> +/** >> + * devfreq_suspend_device() - Suspend devfreq of a device. >> + * @devfreq the devfreq instance to be suspended >> + */ >> +int devfreq_suspend_device(struct devfreq *devfreq) >> +{ >> + if (!devfreq) >> + return -EINVAL; >> + >> + return devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_SUSPEND); >> +} >> +EXPORT_SYMBOL(devfreq_suspend_device); >> + >> +/** >> + * devfreq_resume_device() - Resume devfreq of a device. >> + * @devfreq the devfreq instance to be resumed >> + */ >> +int devfreq_resume_device(struct devfreq *devfreq) >> +{ >> + if (!devfreq) >> + return -EINVAL; >> + >> + return devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_RESUME); >> +} >> +EXPORT_SYMBOL(devfreq_resume_device); >> + >> static ssize_t show_governor(struct device *dev, >>struct device_attribute *attr, char *buf) >> { >> diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h >> index 4a86af7..7dbbdfc 100644 >> --- a/drivers/devfreq/governor.h >> +++ b/drivers/devfreq/governor.h >> @@ -22,6 +22,8 @@ >> #define DEVFREQ_GOV_START0x1 >> #define DEVFREQ_GOV_STOP 0x2 >> #define DEVFREQ_GOV_INTERVAL 0x3 >> +#define DEVFREQ_GOV_SUSPEND 0x4 >> +#define DEVFREQ_GOV_RESUME 0x5 >> >> /* Caution: devfreq->lock must be locked before calling update_devfreq */ >> extern int update_devfreq(struct devfreq *devfreq); >> diff --git a/drivers/devfreq/governor_simpleondemand.c >> b/drivers/devfreq/governor_simpleondemand.c >> index 9802bf9..35b8e8e 100644 >> --- a/drivers/devfreq/governor_simpleondemand.c >> +++ b/drivers/devfreq/governor_simpleondemand.c >> @@ -113,6 +113,15 @@ int devfreq_simple_ondemand_handler(struct devfreq >> *devfreq, >> else >> ret = devfreq_monitor_resume(devfreq); >> break; >> + >> + case DEVFREQ_GOV_SUSPEND: >> + ret = devfreq_monitor_suspend(devfreq); >> + break; >> + >> + case DEVFREQ_GOV_RESUME: >> + ret = devfreq_monitor_resume(devfreq); >> + break; >> + >> default: >> break; >> } >> diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h >> index 7a11c3e..7c7e179 100644 >> --- a/include/linux/devfreq.h >> +++ b/include/linux/devfreq.h >> @@ -155,6 +155,8 @@ extern struct devfreq *devfreq_add_device(struct device >> *dev, >> const struct devfreq_governor *governor, >> void *data); >> extern int devfreq_remove_device(struct devfreq *devfreq); >> +extern int devfreq_suspend_device(struct devfreq *devfreq); >> +extern int devfreq_resume_device(struct devfreq *devfreq); >> >> /* Helper functions for devfreq user device driver with OPP. */ >> extern struct opp
Re: [PATCH 3/3] devfreq: Add current freq callback in device profile
On 10 September 2012 03:30, Rafael J. Wysocki wrote: > On Monday, September 03, 2012, Rajagopal Venkat wrote: >> Devfreq returns governor predicted frequency as current >> frequency via sysfs interface. But device may not support >> all frequencies that governor predicts. > > Do you have any examples, even out of the tree? The exynos4_bus.c devfreq driver supports five opps. But the ondemand governor can suggest any frequency between min and max(assuming policy is set). As per design, governors only need to provide recommended frequency and the corresponding driver will interpret it correctly. So, the governor recommended frequency and the frequency at which device is running could be different. This patch attempts to add new sysfs node for exposing device current running frequency. > >> Its driver >> responsibility to maintain current frequency at which device >> is operating. Add a callback in device profile to fix this. > > Obviously, there are no users of this callback in the tree right now, so it > may not be regarded as a fix. I'd rather say it's a new mechanism for > drivers to use if their current frequencies differ from the governor-selected > ones. Ok. It will be updated in next version. > >> Also add a new sysfs node to expose governor predicted next >> target frequency. >> >> Signed-off-by: Rajagopal Venkat >> --- >> Documentation/ABI/testing/sysfs-class-devfreq | 7 +++ >> drivers/devfreq/devfreq.c | 14 ++ >> include/linux/devfreq.h | 3 +++ >> 3 files changed, 24 insertions(+) >> >> diff --git a/Documentation/ABI/testing/sysfs-class-devfreq >> b/Documentation/ABI/testing/sysfs-class-devfreq >> index 23d78b5..9df5205 100644 >> --- a/Documentation/ABI/testing/sysfs-class-devfreq >> +++ b/Documentation/ABI/testing/sysfs-class-devfreq >> @@ -21,6 +21,13 @@ Description: >> The /sys/class/devfreq/.../cur_freq shows the current >> frequency of the corresponding devfreq object. >> >> +What:/sys/class/devfreq/.../target_freq >> +Date:September 2012 >> +Contact: MyungJoo Ham > > It's a bit odd to add someone else as a contact for interfaces that you're > introducing. I'd need MyungJoo Ham's ACK for that. > >> +Description: >> + The /sys/class/devfreq/.../target_freq shows the next governor >> + predicted target frequency of the corresponding devfreq object. >> + >> What:/sys/class/devfreq/.../central_polling >> Date:September 2011 >> Contact: MyungJoo Ham >> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c >> index 3a5f126..55e9046 100644 >> --- a/drivers/devfreq/devfreq.c >> +++ b/drivers/devfreq/devfreq.c >> @@ -400,6 +400,19 @@ static ssize_t show_governor(struct device *dev, >> static ssize_t show_freq(struct device *dev, >>struct device_attribute *attr, char *buf) >> { >> + unsigned long freq; >> + struct devfreq *devfreq = to_devfreq(dev); >> + >> + if (devfreq->profile->get_cur_freq) >> + if (!devfreq->profile->get_cur_freq(devfreq->dev.parent, >> &freq)) > > That should be > > + if (devfreq->profile->get_cur_freq > + && !devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq)) Done. > >> + return sprintf(buf, "%lu\n", freq); >> + > > Moreover, I suppose it should fall back to the current behavior if > .get_cur_freq() is not present. Agree. Done. > >> + return sprintf(buf, ""); >> +} >> + >> +static ssize_t show_target_freq(struct device *dev, >> + struct device_attribute *attr, char *buf) >> +{ >> return sprintf(buf, "%lu\n", to_devfreq(dev)->previous_freq); >> } >> >> @@ -503,6 +516,7 @@ static ssize_t show_max_freq(struct device *dev, struct >> device_attribute *attr, >> static struct device_attribute devfreq_attrs[] = { >> __ATTR(governor, S_IRUGO, show_governor, NULL), >> __ATTR(cur_freq, S_IRUGO, show_freq, NULL), >> + __ATTR(target_freq, S_IRUGO, show_target_freq, NULL), >> __ATTR(polling_interval, S_IRUGO | S_IWUSR, show_polling_interval, >> store_polling_interval), >> __ATTR(min_freq, S_IRUGO | S_IWUSR, show_min_freq, store_min_freq), >> diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h >> index 7c7e179
Re: [PATCH 1/3] devfreq: core updates to support devices which can idle
On 10 September 2012 14:43, 함명주 wrote: >> Prepare devfreq core framework to support devices which >> can idle. When device idleness is detected perhaps through >> runtime-pm, need some mechanism to suspend devfreq load >> monitoring and resume back when device is online. Present >> code continues monitoring unless device is removed from >> devfreq core. >> >> This patch introduces following design changes, >> >> - use per device work instead of global work to monitor device >> load. This enables suspend/resume of device devfreq and >> reduces monitoring code complexity. >> - decouple delayed work based load monitoring logic from core >> by introducing helpers functions to be used by governors. This >> provides flexibility for governors either to use delayed work >> based monitoring functions or to implement their own mechanism. >> - devfreq core interacts with governors via events to perform >> specific actions. These events include start/stop devfreq. >> This sets ground for adding suspend/resume events. >> >> The devfreq apis are not modified and are kept intact. > > Hello, > > Please revise locking mechanism along with event handler. > > It appears that we need to do mutex_lock(&devfreq->lock) before calling > devfreq->governor->event_handler(); I don't think is the case. The governor can make use of devfreq->lock if needed. Anyways, I have revised locking mechanism in v2 set. > Or at least, userspace_init and userspace_exit functions require mutex_lock. The userspace_init function is executed only when device is added to devfreq framework. This function itself is creating sysfs attributes. So this should not be a concern for us. The userspace_exit is executed when device is removed from devfreq framework. sysfs_remove_group() should take care of serving any pending reference to sysfs attributes before removing them. No concern here as well. Am I missing something which demand locking for these functions? > Event_handler callback won't want the properties in devfreq to be changed > externally during its execution. Agree. > > Plus, please edit Documentation/ABI entry (central_polling is being removed) Done. > > Other than that, it looks fine. > > Cheers! > MyungJoo > >> >> Signed-off-by: Rajagopal Venkat >> --- >> drivers/devfreq/devfreq.c | 376 >> ++ >> drivers/devfreq/governor.h| 9 + >> drivers/devfreq/governor_performance.c| 16 +- >> drivers/devfreq/governor_powersave.c | 16 +- >> drivers/devfreq/governor_simpleondemand.c | 33 +++ >> drivers/devfreq/governor_userspace.c | 23 +- >> include/linux/devfreq.h | 31 +-- >> 7 files changed, 220 insertions(+), 284 deletions(-) >> >> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c >> index b146d76..be524c7 100644 >> --- a/drivers/devfreq/devfreq.c >> +++ b/drivers/devfreq/devfreq.c >> @@ -30,17 +30,11 @@ >> struct class *devfreq_class; >> >> /* >> - * devfreq_work periodically monitors every registered device. >> - * The minimum polling interval is one jiffy. The polling interval is >> - * determined by the minimum polling period among all polling devfreq >> - * devices. The resolution of polling interval is one jiffy. >> + * devfreq core provides delayed work based load monitoring helper >> + * functions. Governors can use these or can implement their own >> + * monitoring mechanism. >> */ >> -static bool polling; >> static struct workqueue_struct *devfreq_wq; >> -static struct delayed_work devfreq_work; >> - >> -/* wait removing if this is to be removed */ >> -static struct devfreq *wait_remove_device; >> >> /* The list of all device-devfreq */ >> static LIST_HEAD(devfreq_list); >> @@ -72,6 +66,8 @@ static struct devfreq *find_device_devfreq(struct device >> *dev) >> return ERR_PTR(-ENODEV); >> } >> >> +/* Load monitoring helper functions for governors use */ >> + >> /** >> * update_devfreq() - Reevaluate the device and configure frequency. >> * @devfreq: the devfreq instance. >> @@ -121,6 +117,90 @@ int update_devfreq(struct devfreq *devfreq) >> } >> >> /** >> + * devfreq_monitor() - Periodically poll devfreq objects. >> + * @work: the work struct used to run devfreq_monitor periodically. >> + * >> + */ >> +static void devfreq_monitor(struct work_struct *work) >> +{ >> + int err; >> + struct devfreq *devfreq = container_of(work,
[PATCH v2 2/3] devfreq: Add suspend and resume apis
From: Rajagopal Venkat Add devfreq suspend/resume apis for devfreq users. This patch supports suspend and resume of devfreq load monitoring, required for devices which can idle. Signed-off-by: Rajagopal Venkat --- drivers/devfreq/devfreq.c | 26 ++ drivers/devfreq/governor.h| 2 ++ drivers/devfreq/governor_simpleondemand.c | 9 + include/linux/devfreq.h | 12 4 files changed, 49 insertions(+) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 9bf2b6a..309c46e 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -366,6 +366,32 @@ int devfreq_remove_device(struct devfreq *devfreq) } EXPORT_SYMBOL(devfreq_remove_device); +/** + * devfreq_suspend_device() - Suspend devfreq of a device. + * @devfreqthe devfreq instance to be suspended + */ +int devfreq_suspend_device(struct devfreq *devfreq) +{ + if (!devfreq) + return -EINVAL; + + return devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_SUSPEND); +} +EXPORT_SYMBOL(devfreq_suspend_device); + +/** + * devfreq_resume_device() - Resume devfreq of a device. + * @devfreqthe devfreq instance to be resumed + */ +int devfreq_resume_device(struct devfreq *devfreq) +{ + if (!devfreq) + return -EINVAL; + + return devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_RESUME); +} +EXPORT_SYMBOL(devfreq_resume_device); + static ssize_t show_governor(struct device *dev, struct device_attribute *attr, char *buf) { diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h index fb621f8..4624607 100644 --- a/drivers/devfreq/governor.h +++ b/drivers/devfreq/governor.h @@ -22,6 +22,8 @@ #define DEVFREQ_GOV_START 0x1 #define DEVFREQ_GOV_STOP 0x2 #define DEVFREQ_GOV_INTERVAL 0x3 +#define DEVFREQ_GOV_SUSPEND0x4 +#define DEVFREQ_GOV_RESUME 0x5 /* Caution: devfreq->lock must be locked before calling update_devfreq */ extern int update_devfreq(struct devfreq *devfreq); diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c index 7aed0ef..68ad7d7 100644 --- a/drivers/devfreq/governor_simpleondemand.c +++ b/drivers/devfreq/governor_simpleondemand.c @@ -111,6 +111,15 @@ int devfreq_simple_ondemand_handler(struct devfreq *devfreq, else devfreq_monitor_resume(devfreq); break; + + case DEVFREQ_GOV_SUSPEND: + devfreq_monitor_suspend(devfreq); + break; + + case DEVFREQ_GOV_RESUME: + devfreq_monitor_resume(devfreq); + break; + default: break; } diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 7a11c3e..7c7e179 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -155,6 +155,8 @@ extern struct devfreq *devfreq_add_device(struct device *dev, const struct devfreq_governor *governor, void *data); extern int devfreq_remove_device(struct devfreq *devfreq); +extern int devfreq_suspend_device(struct devfreq *devfreq); +extern int devfreq_resume_device(struct devfreq *devfreq); /* Helper functions for devfreq user device driver with OPP. */ extern struct opp *devfreq_recommended_opp(struct device *dev, @@ -208,6 +210,16 @@ static int devfreq_remove_device(struct devfreq *devfreq) return 0; } +static int devfreq_suspend_device(struct devfreq *devfreq) +{ + return 0; +} + +static int devfreq_resume_device(struct devfreq *devfreq) +{ + return 0; +} + static struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, u32 flags) { -- 1.7.11.3 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH v2 0/3] devfreq: Add support for devices which can idle
From: Rajagopal Venkat This patchset updates devfreq core to add support for devices which can idle. When device idleness is detected perhaps through runtime-pm, need some mechanism to suspend devfreq load monitoring and resume when device is back online. patch 1 introduce core design changes - per device work, decouple delayed work from core and event based interaction. patch 2 add devfreq suspend and resume apis. patch 3 add new sysfs attribute for governor predicted next target frequency and callback for current device frequency. The existing devfreq apis are kept intact. Two new apis devfreq_suspend_device() and devfreq_resume_device() are added to support suspend/resume of device devfreq. Changes since v1: - revised locking mechanism - added kerneldoc comments for load monitoring helper functions - Fixed minor review comments -- Rajagopal Venkat (3): devfreq: Core updates to support devices which can idle devfreq: Add suspend and resume apis devfreq: Add current freq callback in device profile Documentation/ABI/testing/sysfs-class-devfreq | 15 +- drivers/devfreq/devfreq.c | 413 +++--- drivers/devfreq/governor.h| 11 + drivers/devfreq/governor_performance.c| 16 +- drivers/devfreq/governor_powersave.c | 16 +- drivers/devfreq/governor_simpleondemand.c | 40 +++ drivers/devfreq/governor_userspace.c | 23 +- include/linux/devfreq.h | 46 ++- 8 files changed, 291 insertions(+), 289 deletions(-) -- 1.7.11.3 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH v2 1/3] devfreq: Core updates to support devices which can idle
From: Rajagopal Venkat Prepare devfreq core framework to support devices which can idle. When device idleness is detected perhaps through runtime-pm, need some mechanism to suspend devfreq load monitoring and resume back when device is online. Present code continues monitoring unless device is removed from devfreq core. This patch introduces following design changes, - use per device work instead of global work to monitor device load. This enables suspend/resume of device devfreq and reduces monitoring code complexity. - decouple delayed work based load monitoring logic from core by introducing helpers functions to be used by governors. This provides flexibility for governors either to use delayed work based monitoring functions or to implement their own mechanism. - devfreq core interacts with governors via events to perform specific actions. These events include start/stop devfreq. This sets ground for adding suspend/resume events. The devfreq apis are not modified and are kept intact. Signed-off-by: Rajagopal Venkat --- Documentation/ABI/testing/sysfs-class-devfreq | 8 - drivers/devfreq/devfreq.c | 377 +- drivers/devfreq/governor.h| 9 + drivers/devfreq/governor_performance.c| 16 +- drivers/devfreq/governor_powersave.c | 16 +- drivers/devfreq/governor_simpleondemand.c | 31 +++ drivers/devfreq/governor_userspace.c | 23 +- include/linux/devfreq.h | 31 +-- 8 files changed, 219 insertions(+), 292 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq index 23d78b5..89283b1 100644 --- a/Documentation/ABI/testing/sysfs-class-devfreq +++ b/Documentation/ABI/testing/sysfs-class-devfreq @@ -21,14 +21,6 @@ Description: The /sys/class/devfreq/.../cur_freq shows the current frequency of the corresponding devfreq object. -What: /sys/class/devfreq/.../central_polling -Date: September 2011 -Contact: MyungJoo Ham -Description: - The /sys/class/devfreq/.../central_polling shows whether - the devfreq ojbect is using devfreq-provided central - polling mechanism or not. - What: /sys/class/devfreq/.../polling_interval Date: September 2011 Contact: MyungJoo Ham diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index b146d76..9bf2b6a 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -30,17 +30,11 @@ struct class *devfreq_class; /* - * devfreq_work periodically monitors every registered device. - * The minimum polling interval is one jiffy. The polling interval is - * determined by the minimum polling period among all polling devfreq - * devices. The resolution of polling interval is one jiffy. + * devfreq core provides delayed work based load monitoring helper + * functions. Governors can use these or can implement their own + * monitoring mechanism. */ -static bool polling; static struct workqueue_struct *devfreq_wq; -static struct delayed_work devfreq_work; - -/* wait removing if this is to be removed */ -static struct devfreq *wait_remove_device; /* The list of all device-devfreq */ static LIST_HEAD(devfreq_list); @@ -72,6 +66,8 @@ static struct devfreq *find_device_devfreq(struct device *dev) return ERR_PTR(-ENODEV); } +/* Load monitoring helper functions for governors use */ + /** * update_devfreq() - Reevaluate the device and configure frequency. * @devfreq: the devfreq instance. @@ -121,6 +117,91 @@ int update_devfreq(struct devfreq *devfreq) } /** + * devfreq_monitor() - Periodically poll devfreq objects. + * @work: the work struct used to run devfreq_monitor periodically. + * + */ +static void devfreq_monitor(struct work_struct *work) +{ + int err; + struct devfreq *devfreq = container_of(work, + struct devfreq, work.work); + + mutex_lock(&devfreq->lock); + err = update_devfreq(devfreq); + if (err) + dev_err(&devfreq->dev, "dvfs failed with (%d) error\n", err); + + queue_delayed_work(devfreq_wq, &devfreq->work, + msecs_to_jiffies(devfreq->profile->polling_ms)); + mutex_unlock(&devfreq->lock); +} + +/** + * devfreq_monitor_start() - Start load monitoring of devfreq instance + * @devfreq: the devfreq instance. + * + * Helper function for starting devfreq device load monitoing. By + * default delayed work based monitoring is supported. Function + * to be called from governor in response to DEVFREQ_GOV_START + * event when device is added to devfreq framework. + */ +void devfreq_monitor_start(struct devfreq *devfreq) +{ + INIT_DEFERRABLE_WORK(&devfreq->work, devfreq_monitor); + queue_delayed_work(devfreq_wq, &
[PATCH v2 3/3] devfreq: Add current freq callback in device profile
From: Rajagopal Venkat Devfreq returns governor predicted frequency as current frequency via sysfs interface. But device may not support all frequencies that governor predicts. So add a callback in device profile to get current freq from driver. Also add a new sysfs node to expose governor predicted next target frequency. Signed-off-by: Rajagopal Venkat --- Documentation/ABI/testing/sysfs-class-devfreq | 11 ++- drivers/devfreq/devfreq.c | 14 ++ include/linux/devfreq.h | 3 +++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq index 89283b1..e6cf08e 100644 --- a/Documentation/ABI/testing/sysfs-class-devfreq +++ b/Documentation/ABI/testing/sysfs-class-devfreq @@ -19,7 +19,16 @@ Date:September 2011 Contact: MyungJoo Ham Description: The /sys/class/devfreq/.../cur_freq shows the current - frequency of the corresponding devfreq object. + frequency of the corresponding devfreq object. Same as + target_freq when get_cur_freq() is not implemented by + devfreq driver. + +What: /sys/class/devfreq/.../target_freq +Date: September 2012 +Contact: Rajagopal Venkat +Description: + The /sys/class/devfreq/.../target_freq shows the next governor + predicted target frequency of the corresponding devfreq object. What: /sys/class/devfreq/.../polling_interval Date: September 2011 diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 309c46e..049e273 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -401,6 +401,19 @@ static ssize_t show_governor(struct device *dev, static ssize_t show_freq(struct device *dev, struct device_attribute *attr, char *buf) { + unsigned long freq; + struct devfreq *devfreq = to_devfreq(dev); + + if (devfreq->profile->get_cur_freq && + !devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq)) + return sprintf(buf, "%lu\n", freq); + + return sprintf(buf, "%lu\n", devfreq->previous_freq); +} + +static ssize_t show_target_freq(struct device *dev, + struct device_attribute *attr, char *buf) +{ return sprintf(buf, "%lu\n", to_devfreq(dev)->previous_freq); } @@ -504,6 +517,7 @@ static ssize_t show_max_freq(struct device *dev, struct device_attribute *attr, static struct device_attribute devfreq_attrs[] = { __ATTR(governor, S_IRUGO, show_governor, NULL), __ATTR(cur_freq, S_IRUGO, show_freq, NULL), + __ATTR(target_freq, S_IRUGO, show_target_freq, NULL), __ATTR(polling_interval, S_IRUGO | S_IWUSR, show_polling_interval, store_polling_interval), __ATTR(min_freq, S_IRUGO | S_IWUSR, show_min_freq, store_min_freq), diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 7c7e179..d12ed41 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -66,6 +66,8 @@ struct devfreq_dev_status { * explained above with "DEVFREQ_FLAG_*" macros. * @get_dev_status The device should provide the current performance * status to devfreq, which is used by governors. + * @get_cur_freq The device should provide the current frequency + * at which it is operating. * @exit An optional callback that is called when devfreq * is removing the devfreq object due to error or * from devfreq_remove_device() call. If the user @@ -79,6 +81,7 @@ struct devfreq_dev_profile { int (*target)(struct device *dev, unsigned long *freq, u32 flags); int (*get_dev_status)(struct device *dev, struct devfreq_dev_status *stat); + int (*get_cur_freq)(struct device *dev, unsigned long *freq); void (*exit)(struct device *dev); }; -- 1.7.11.3 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[Powertop][PATCH 2/2] Add stubs to support Android platform
This patch adds stubs for features that are not supported by Andriod. An header file which defines all stubs is included only for Android builds. Signed-off-by: Rajagopal Venkat --- Android.mk | 33 +++-- src/android_stubs.h | 47 +++ src/lib.h |4 3 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 src/android_stubs.h diff --git a/Android.mk b/Android.mk index a52ecfd..081f470 100644 --- a/Android.mk +++ b/Android.mk @@ -1,17 +1,36 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) +LOCAL_MODULE := powertop + LOCAL_MODULE_TAGS := debug LOCAL_SHARED_LIBRARIES := libstlport \ libnl \ libpci \ - libtraceevnet \ -LOCAL_MODULE := powertop + +LOCAL_STATIC_LIBRARIES := libncurses + +CSSTOH_SOURCE := $(LOCAL_PATH)/src/csstoh.c +POWERTOP_CSS_SOURCE := $(LOCAL_PATH)/src/powertop.css +GEN_CSSTOH := $(LOCAL_PATH)/src/csstoh +GEN_CSS_H := $(LOCAL_PATH)/src/css.h +$(GEN_CSS_H): + $(CC) -o $(GEN_CSSTOH) $(CSSTOH_SOURCE) + ./$(GEN_CSSTOH) $(POWERTOP_CSS_SOURCE) $@ + +LOCAL_GENERATED_SOURCES += $(GEN_CSS_H) #LOCAL_CFLAGS += -Wall -O2 -g -fno-omit-frame-pointer -fstack-protector -Wshadow -Wformat -D_FORTIFY_SOURCE=2 #LOCAL_CPPFLAGS += -Wall -O2 -g -fno-omit-frame-pointer -LOCAL_C_INCLUDES += external/stlport/stlport/ external/stlport/stlport/stl external/stlport/stlport/using/h/ bionic external/libnl/include/ +LOCAL_C_INCLUDES += external/stlport/stlport/ \ + external/stlport/stlport/stl \ + external/stlport/stlport/using/h/ \ + bionic \ + external/libnl/include/ \ + external/ncurses/include \ + external/elfutils/bionic-fixup \ + $(LOCAL_PATH)/src LOCAL_SRC_FILES += \ src/parameters/parameters.cpp \ @@ -21,10 +40,11 @@ LOCAL_SRC_FILES += \ src/process/work.cpp \ src/process/process.cpp \ src/process/timer.cpp \ - src/process/device.cpp \ + src/process/processdevice.cpp \ src/process/interrupt.cpp \ src/process/do_process.cpp \ src/cpu/intel_cpus.cpp \ + src/cpu/intel_gpu.cpp \ src/cpu/cpu.cpp \ src/cpu/cpu_linux.cpp \ src/cpu/cpudevice.cpp \ @@ -33,20 +53,21 @@ LOCAL_SRC_FILES += \ src/cpu/abstract_cpu.cpp \ src/measurement/measurement.cpp \ src/measurement/acpi.cpp \ + src/measurement/sysfs.cpp \ src/measurement/extech.cpp \ src/measurement/power_supply.cpp \ src/display.cpp \ src/report.cpp \ src/main.cpp \ src/tuning/tuning.cpp \ - src/tuning/usb.cpp \ + src/tuning/tuningusb.cpp \ src/tuning/bluetooth.cpp \ src/tuning/ethernet.cpp \ src/tuning/runtime.cpp \ src/tuning/iw.c \ src/tuning/iw.h \ src/tuning/tunable.cpp \ - src/tuning/sysfs.cpp \ + src/tuning/tuningsysfs.cpp \ src/tuning/cpufreq.cpp \ src/tuning/wifi.cpp \ src/perf/perf_bundle.cpp \ diff --git a/src/android_stubs.h b/src/android_stubs.h new file mode 100644 index 000..60b1e29 --- /dev/null +++ b/src/android_stubs.h @@ -0,0 +1,47 @@ +#include +#include + +/* Android doesn't provide locale support int its C and C++ + * runtime. Handled at higher level in application stack. + * So define stubs for gettext funtions used. + */ +#define PACKAGE0 +#define LOCALEDIR 0 +#define bindtextdomain(x, y) +#define textdomain(x) +#define gettext(x) (x) + +/* Android C++ new operator does not throw exception on failure */ +#define set_new_handler(x) + +/* define stubs for C++ exception handling */ +#define tryif (true) +#define catch(x) if (false) + +/* Define __NR_perf_event_open if not already defined */ +#if __arm__ +#ifndef __NR_perf_event_open +#define __NR_perf_event_open364 +#endif +#endif + +/* Implement missing functions */ +static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep, + __u32 speed) +{ + + ep->speed = (__u16)speed; + ep->speed_hi = (__u16)(speed >> 16); +} + +static inline __u32 ethtool_cmd_speed(struct ethtool_cmd *ep) +{ + return (ep->speed_hi << 16) | ep->speed; +} + +static inline char *strchrnul(const char *s, int c) +{ + while (*s && (*s != c)) + s++; + return (char *)s; +} diff --git a/src/lib.h b/src/lib.h index 8cf4632..6772904 100644 --- a/src/lib.h +++ b/src/lib.h @@ -33,6 +33,10 @@ #include "config.h" #endif +#ifdef __ANDROID__ +#include "android_stubs.h" +#endif + #define _(STRING)gettext(STRING) #define POWERTOP_VERSION "v2.1" -- 1.7.9.5 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[Powertop][PATCH 1/2] Updates to support Android platform
This patch adds following minor changes to prepare powertop to support Android platform. - add missing HAVE_CONFIG_H conditional check. - remove un-used ethtool_cmd_speed_set and ethtool_cmd_speed functions. - minimize dependency on exception handling in catch blocks. These changes will not affect powertop functionality. Signed-off-by: Rajagopal Venkat --- src/devices/ahci.cpp |4 ++-- src/devices/alsa.cpp |4 ++-- src/devices/network.cpp| 16 src/lib.cpp|2 +- src/main.cpp |2 ++ src/process/do_process.cpp |4 ++-- 6 files changed, 9 insertions(+), 23 deletions(-) diff --git a/src/devices/ahci.cpp b/src/devices/ahci.cpp index 1fe39c7..67ce06e 100644 --- a/src/devices/ahci.cpp +++ b/src/devices/ahci.cpp @@ -170,7 +170,7 @@ void ahci::start_measurement(void) file.close(); } catch (std::ios_base::failure &c) { - fprintf(stderr, "%s\n", c.what()); + fprintf(stderr, "Failed to start measurement for ahci device\n"); } } @@ -203,7 +203,7 @@ void ahci::end_measurement(void) file.close(); } catch (std::ios_base::failure &c) { - fprintf(stderr, "%s\n", c.what()); + fprintf(stderr, "Failed to end measurement for ahci device\n"); } if (end_active < start_active) end_active = start_active; diff --git a/src/devices/alsa.cpp b/src/devices/alsa.cpp index 4f5d3f9..a67780c 100644 --- a/src/devices/alsa.cpp +++ b/src/devices/alsa.cpp @@ -104,7 +104,7 @@ void alsa::start_measurement(void) file.close(); } catch (std::ios_base::failure &c) { - fprintf(stderr, "%s\n", c.what()); + fprintf(stderr, "Failed to start measurement for alsa device\n"); } } @@ -130,7 +130,7 @@ void alsa::end_measurement(void) file.close(); } catch (std::ios_base::failure &c) { - fprintf(stderr, "%s\n", c.what()); + fprintf(stderr, "Failed to end measurement for alsa device\n"); } p = (end_active - start_active) / (0.001 + end_active + end_inactive - start_active - start_inactive) * 100.0; diff --git a/src/devices/network.cpp b/src/devices/network.cpp index b8a5c9c..ed9d7aa 100644 --- a/src/devices/network.cpp +++ b/src/devices/network.cpp @@ -55,22 +55,6 @@ extern "C" { static map nics; -#ifdef DISABLE_TRYCATCH - -static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep, - __u32 speed) -{ - - ep->speed = (__u16)speed; - ep->speed_hi = (__u16)(speed >> 16); -} - -static inline __u32 ethtool_cmd_speed(struct ethtool_cmd *ep) -{ - return (ep->speed_hi << 16) | ep->speed; -} - -#endif static void do_proc_net_dev(void) { diff --git a/src/lib.cpp b/src/lib.cpp index 9838c0b..776a67b 100644 --- a/src/lib.cpp +++ b/src/lib.cpp @@ -259,7 +259,7 @@ void format_watts(double W, char *buffer, unsigned int len) if (W < 0.0001) sprintf(buffer, _("0 mW")); - while (mbstowcs(NULL,buffer,0) < len) + while (mbstowcs(NULL,buffer,len) < len) strcat(buffer, " "); } diff --git a/src/main.cpp b/src/main.cpp index 1815075..dc49dba 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -42,7 +42,9 @@ #include "perf/perf.h" #include "perf/perf_bundle.h" #include "lib.h" +#ifdef HAVE_CONFIG_H #include "../config.h" +#endif #include "devices/device.h" diff --git a/src/process/do_process.cpp b/src/process/do_process.cpp index eaef7f1..c9d6b0b 100644 --- a/src/process/do_process.cpp +++ b/src/process/do_process.cpp @@ -869,7 +869,7 @@ void process_update_display(void) if (!show_power) strcpy(power, " "); sprintf(name, "%s", all_power[i]->type()); - while (mbstowcs(NULL,name,0) < 14) strcat(name, " "); + while (mbstowcs(NULL,name,20) < 14) strcat(name, " "); if (all_power[i]->events() == 0 && all_power[i]->usage() == 0 && all_power[i]->Witts() == 0) @@ -882,7 +882,7 @@ void process_update_display(void) else sprintf(usage, "%5i%s", (int)all_power[i]->usage(), all_power[i]->usage_units()); } - while (mbstowcs(NULL,usage,0) < 14) strcat(usage, " "); + while (mbstowcs(NULL,usage,20) < 14) strcat(usage, " "); sprintf(events, "%5.1f", all_power[i]->events()); if (!all_power[i]->show_events()) events[0] = 0; -- 1.7.9.5 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: Re: [PATCH 1/3] devfreq: core updates to support devices which can idle
On 17 September 2012 17:46, MyungJoo Ham wrote: >> On 10 September 2012 14:43, 함명주 wrote: >> >> Prepare devfreq core framework to support devices which >> >> can idle. When device idleness is detected perhaps through >> >> runtime-pm, need some mechanism to suspend devfreq load >> >> monitoring and resume back when device is online. Present >> >> code continues monitoring unless device is removed from >> >> devfreq core. >> >> >> >> This patch introduces following design changes, >> >> >> >> - use per device work instead of global work to monitor device >> >> load. This enables suspend/resume of device devfreq and >> >> reduces monitoring code complexity. >> >> - decouple delayed work based load monitoring logic from core >> >> by introducing helpers functions to be used by governors. This >> >> provides flexibility for governors either to use delayed work >> >> based monitoring functions or to implement their own mechanism. >> >> - devfreq core interacts with governors via events to perform >> >> specific actions. These events include start/stop devfreq. >> >> This sets ground for adding suspend/resume events. >> >> >> >> The devfreq apis are not modified and are kept intact. >> > >> > Hello, >> > >> > Please revise locking mechanism along with event handler. >> > >> > It appears that we need to do mutex_lock(&devfreq->lock) before calling >> > devfreq->governor->event_handler(); >> >> I don't think is the case. The governor can make use of devfreq->lock if >> needed. >> Anyways, I have revised locking mechanism in v2 set. >> >> > Or at least, userspace_init and userspace_exit functions require >> > mutex_lock. >> >> The userspace_init function is executed only when device is added to devfreq >> framework. This function itself is creating sysfs attributes. So this should >> not >> be a concern for us. >> >> The userspace_exit is executed when device is removed from devfreq >> framework. sysfs_remove_group() should take care of serving any pending >> reference to sysfs attributes before removing them. No concern here as well. >> Am I missing something which demand locking for these functions? >> >> > Event_handler callback won't want the properties in devfreq to be changed >> > externally during its execution. >> >> Agree. > > If so, the GOV_INTERVAL handler of ondemand requires mutex_lock. > (and probably, nested mutex lock for monitor_resume) > I don't think so. The polling_ms value update and the GOV_INTERVAL event are handled in store_polling_interval() i.e same caller's context. So no reason for concern here. Also polling_ms value update and queuing the work(using polling_ms) are synchronized. > It determins next action based on the value protected by the > devfreq lock. It won't crash the kernel and it won't happen > often. However, it may behave incorrectly. > > Why don't we simply let the all the struct devfreq protected > when the external code (governors) is probably reading/writing the > protected values? > > This also guarantees that the event handler gets the exact status > modified by the event caller. Otherwise, the event handler may > get status different from the event caller's intention. > > > Cheers! > MyungJoo > > >> >> > >> > Plus, please edit Documentation/ABI entry (central_polling is being >> > removed) >> Done. >> > >> > Other than that, it looks fine. >> > >> > Cheers! >> > MyungJoo >> > >> >> >> >> Signed-off-by: Rajagopal Venkat >> >> --- >> >> drivers/devfreq/devfreq.c | 376 >> >> ++ >> >> drivers/devfreq/governor.h| 9 + >> >> drivers/devfreq/governor_performance.c| 16 +- >> >> drivers/devfreq/governor_powersave.c | 16 +- >> >> drivers/devfreq/governor_simpleondemand.c | 33 +++ >> >> drivers/devfreq/governor_userspace.c | 23 +- >> >> include/linux/devfreq.h | 31 +-- >> >> 7 files changed, 220 insertions(+), 284 deletions(-) >> >> >> >> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c >> >> index b146d76..be524c7 100644 >> >> --- a/drivers/devfreq/devfreq.c >> &g
[PATCH v3 3/3] devfreq: Add current freq callback in device profile
Devfreq returns governor predicted frequency as current frequency via sysfs interface. But device may not support all frequencies that governor predicts. So add a callback in device profile to get current freq from driver. Also add a new sysfs node to expose governor predicted next target frequency. Signed-off-by: Rajagopal Venkat Signed-off-by: MyungJoo Ham --- Documentation/ABI/testing/sysfs-class-devfreq | 11 ++- drivers/devfreq/devfreq.c | 14 ++ include/linux/devfreq.h | 3 +++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq index 89283b1..e6cf08e 100644 --- a/Documentation/ABI/testing/sysfs-class-devfreq +++ b/Documentation/ABI/testing/sysfs-class-devfreq @@ -19,7 +19,16 @@ Date:September 2011 Contact: MyungJoo Ham Description: The /sys/class/devfreq/.../cur_freq shows the current - frequency of the corresponding devfreq object. + frequency of the corresponding devfreq object. Same as + target_freq when get_cur_freq() is not implemented by + devfreq driver. + +What: /sys/class/devfreq/.../target_freq +Date: September 2012 +Contact: Rajagopal Venkat +Description: + The /sys/class/devfreq/.../target_freq shows the next governor + predicted target frequency of the corresponding devfreq object. What: /sys/class/devfreq/.../polling_interval Date: September 2011 diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index edddb9e..33b0a33 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -453,6 +453,19 @@ static ssize_t show_governor(struct device *dev, static ssize_t show_freq(struct device *dev, struct device_attribute *attr, char *buf) { + unsigned long freq; + struct devfreq *devfreq = to_devfreq(dev); + + if (devfreq->profile->get_cur_freq && + !devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq)) + return sprintf(buf, "%lu\n", freq); + + return sprintf(buf, "%lu\n", devfreq->previous_freq); +} + +static ssize_t show_target_freq(struct device *dev, + struct device_attribute *attr, char *buf) +{ return sprintf(buf, "%lu\n", to_devfreq(dev)->previous_freq); } @@ -552,6 +565,7 @@ static ssize_t show_max_freq(struct device *dev, struct device_attribute *attr, static struct device_attribute devfreq_attrs[] = { __ATTR(governor, S_IRUGO, show_governor, NULL), __ATTR(cur_freq, S_IRUGO, show_freq, NULL), + __ATTR(target_freq, S_IRUGO, show_target_freq, NULL), __ATTR(polling_interval, S_IRUGO | S_IWUSR, show_polling_interval, store_polling_interval), __ATTR(min_freq, S_IRUGO | S_IWUSR, show_min_freq, store_min_freq), diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 18bd3b7..f49c5d3 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -66,6 +66,8 @@ struct devfreq_dev_status { * explained above with "DEVFREQ_FLAG_*" macros. * @get_dev_status The device should provide the current performance * status to devfreq, which is used by governors. + * @get_cur_freq The device should provide the current frequency + * at which it is operating. * @exit An optional callback that is called when devfreq * is removing the devfreq object due to error or * from devfreq_remove_device() call. If the user @@ -79,6 +81,7 @@ struct devfreq_dev_profile { int (*target)(struct device *dev, unsigned long *freq, u32 flags); int (*get_dev_status)(struct device *dev, struct devfreq_dev_status *stat); + int (*get_cur_freq)(struct device *dev, unsigned long *freq); void (*exit)(struct device *dev); }; -- 1.7.11.3 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH v3 2/3] devfreq: Add suspend and resume apis
Add devfreq suspend/resume apis for devfreq users. This patch supports suspend and resume of devfreq load monitoring, required for devices which can idle. Signed-off-by: Rajagopal Venkat --- drivers/devfreq/devfreq.c | 28 drivers/devfreq/governor.h| 2 ++ drivers/devfreq/governor_simpleondemand.c | 9 + include/linux/devfreq.h | 12 4 files changed, 51 insertions(+) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 8e9b5aa..edddb9e 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -416,6 +416,34 @@ int devfreq_remove_device(struct devfreq *devfreq) } EXPORT_SYMBOL(devfreq_remove_device); +/** + * devfreq_suspend_device() - Suspend devfreq of a device. + * @devfreqthe devfreq instance to be suspended + */ +int devfreq_suspend_device(struct devfreq *devfreq) +{ + if (!devfreq) + return -EINVAL; + + return devfreq->governor->event_handler(devfreq, + DEVFREQ_GOV_SUSPEND, NULL); +} +EXPORT_SYMBOL(devfreq_suspend_device); + +/** + * devfreq_resume_device() - Resume devfreq of a device. + * @devfreqthe devfreq instance to be resumed + */ +int devfreq_resume_device(struct devfreq *devfreq) +{ + if (!devfreq) + return -EINVAL; + + return devfreq->governor->event_handler(devfreq, + DEVFREQ_GOV_RESUME, NULL); +} +EXPORT_SYMBOL(devfreq_resume_device); + static ssize_t show_governor(struct device *dev, struct device_attribute *attr, char *buf) { diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h index bb3aff3..26432ac 100644 --- a/drivers/devfreq/governor.h +++ b/drivers/devfreq/governor.h @@ -22,6 +22,8 @@ #define DEVFREQ_GOV_START 0x1 #define DEVFREQ_GOV_STOP 0x2 #define DEVFREQ_GOV_INTERVAL 0x3 +#define DEVFREQ_GOV_SUSPEND0x4 +#define DEVFREQ_GOV_RESUME 0x5 /* Caution: devfreq->lock must be locked before calling update_devfreq */ extern int update_devfreq(struct devfreq *devfreq); diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c index cf94218..a8ba78c 100644 --- a/drivers/devfreq/governor_simpleondemand.c +++ b/drivers/devfreq/governor_simpleondemand.c @@ -104,6 +104,15 @@ int devfreq_simple_ondemand_handler(struct devfreq *devfreq, case DEVFREQ_GOV_INTERVAL: devfreq_interval_update(devfreq, (unsigned int *)data); break; + + case DEVFREQ_GOV_SUSPEND: + devfreq_monitor_suspend(devfreq); + break; + + case DEVFREQ_GOV_RESUME: + devfreq_monitor_resume(devfreq); + break; + default: break; } diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 2ab70e3..18bd3b7 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -158,6 +158,8 @@ extern struct devfreq *devfreq_add_device(struct device *dev, const struct devfreq_governor *governor, void *data); extern int devfreq_remove_device(struct devfreq *devfreq); +extern int devfreq_suspend_device(struct devfreq *devfreq); +extern int devfreq_resume_device(struct devfreq *devfreq); /* Helper functions for devfreq user device driver with OPP. */ extern struct opp *devfreq_recommended_opp(struct device *dev, @@ -211,6 +213,16 @@ static int devfreq_remove_device(struct devfreq *devfreq) return 0; } +static int devfreq_suspend_device(struct devfreq *devfreq) +{ + return 0; +} + +static int devfreq_resume_device(struct devfreq *devfreq) +{ + return 0; +} + static struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, u32 flags) { -- 1.7.11.3 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH v3 0/3] devfreq: Add support for devices which can idle
This patchset updates devfreq core to add support for devices which can idle. When device idleness is detected perhaps through runtime-pm, need some mechanism to suspend devfreq load monitoring and resume when device is back online. patch 1 introduce core design changes - per device work, decouple delayed work from core and event based interaction. patch 2 add devfreq suspend and resume apis. patch 3 add new sysfs attribute for governor predicted next target frequency and callback for current device frequency. The existing devfreq apis are kept intact. Two new apis devfreq_suspend_device() and devfreq_resume_device() are added to support suspend/resume of device devfreq. Changes since v1: - revised locking mechanism - added kerneldoc comments for load monitoring helper functions - Fixed minor review comments Changes since v2: - added new helper function for polling interval update - Handled work suspend/resume contention between devfreq driver and sysfs -- Rajagopal Venkat (3): devfreq: Core updates to support devices which can idle devfreq: Add suspend and resume apis devfreq: Add current freq callback in device profile Documentation/ABI/testing/sysfs-class-devfreq | 15 +- drivers/devfreq/devfreq.c | 469 -- drivers/devfreq/governor.h| 13 + drivers/devfreq/governor_performance.c| 16 +- drivers/devfreq/governor_powersave.c | 16 +- drivers/devfreq/governor_simpleondemand.c | 33 ++ drivers/devfreq/governor_userspace.c | 23 +- include/linux/devfreq.h | 49 +-- 8 files changed, 341 insertions(+), 293 deletions(-) -- 1.7.11.3 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH v3 1/3] devfreq: Core updates to support devices which can idle
Prepare devfreq core framework to support devices which can idle. When device idleness is detected perhaps through runtime-pm, need some mechanism to suspend devfreq load monitoring and resume back when device is online. Present code continues monitoring unless device is removed from devfreq core. This patch introduces following design changes, - use per device work instead of global work to monitor device load. This enables suspend/resume of device devfreq and reduces monitoring code complexity. - decouple delayed work based load monitoring logic from core by introducing helpers functions to be used by governors. This provides flexibility for governors either to use delayed work based monitoring functions or to implement their own mechanism. - devfreq core interacts with governors via events to perform specific actions. These events include start/stop devfreq. This sets ground for adding suspend/resume events. The devfreq apis are not modified and are kept intact. Signed-off-by: Rajagopal Venkat --- Documentation/ABI/testing/sysfs-class-devfreq | 8 - drivers/devfreq/devfreq.c | 431 +++--- drivers/devfreq/governor.h| 11 + drivers/devfreq/governor_performance.c| 16 +- drivers/devfreq/governor_powersave.c | 16 +- drivers/devfreq/governor_simpleondemand.c | 24 ++ drivers/devfreq/governor_userspace.c | 23 +- include/linux/devfreq.h | 34 +- 8 files changed, 267 insertions(+), 296 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq index 23d78b5..89283b1 100644 --- a/Documentation/ABI/testing/sysfs-class-devfreq +++ b/Documentation/ABI/testing/sysfs-class-devfreq @@ -21,14 +21,6 @@ Description: The /sys/class/devfreq/.../cur_freq shows the current frequency of the corresponding devfreq object. -What: /sys/class/devfreq/.../central_polling -Date: September 2011 -Contact: MyungJoo Ham -Description: - The /sys/class/devfreq/.../central_polling shows whether - the devfreq ojbect is using devfreq-provided central - polling mechanism or not. - What: /sys/class/devfreq/.../polling_interval Date: September 2011 Contact: MyungJoo Ham diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index b146d76..8e9b5aa 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -30,17 +30,11 @@ struct class *devfreq_class; /* - * devfreq_work periodically monitors every registered device. - * The minimum polling interval is one jiffy. The polling interval is - * determined by the minimum polling period among all polling devfreq - * devices. The resolution of polling interval is one jiffy. + * devfreq core provides delayed work based load monitoring helper + * functions. Governors can use these or can implement their own + * monitoring mechanism. */ -static bool polling; static struct workqueue_struct *devfreq_wq; -static struct delayed_work devfreq_work; - -/* wait removing if this is to be removed */ -static struct devfreq *wait_remove_device; /* The list of all device-devfreq */ static LIST_HEAD(devfreq_list); @@ -72,6 +66,8 @@ static struct devfreq *find_device_devfreq(struct device *dev) return ERR_PTR(-ENODEV); } +/* Load monitoring helper functions for governors use */ + /** * update_devfreq() - Reevaluate the device and configure frequency. * @devfreq: the devfreq instance. @@ -121,6 +117,140 @@ int update_devfreq(struct devfreq *devfreq) } /** + * devfreq_monitor() - Periodically poll devfreq objects. + * @work: the work struct used to run devfreq_monitor periodically. + * + */ +static void devfreq_monitor(struct work_struct *work) +{ + int err; + struct devfreq *devfreq = container_of(work, + struct devfreq, work.work); + + mutex_lock(&devfreq->lock); + err = update_devfreq(devfreq); + if (err) + dev_err(&devfreq->dev, "dvfs failed with (%d) error\n", err); + + queue_delayed_work(devfreq_wq, &devfreq->work, + msecs_to_jiffies(devfreq->profile->polling_ms)); + mutex_unlock(&devfreq->lock); +} + +/** + * devfreq_monitor_start() - Start load monitoring of devfreq instance + * @devfreq: the devfreq instance. + * + * Helper function for starting devfreq device load monitoing. By + * default delayed work based monitoring is supported. Function + * to be called from governor in response to DEVFREQ_GOV_START + * event when device is added to devfreq framework. + */ +void devfreq_monitor_start(struct devfreq *devfreq) +{ + INIT_DEFERRABLE_WORK(&devfreq->work, devfreq_monitor); + queue_delayed_work(devfreq_wq, &devfreq->work, +
[Powertop][PATCH v2 1/2] Updates to support Android platform
This patch adds following minor changes to prepare powertop to support Android platform. - Add missing HAVE_CONFIG_H conditional check. - remove un-used ethtool_cmd_speed_set and ethtool_cmd_speed functions. - Minimize dependency on exception handling in catch blocks. These changes will not affect powertop functionality. Signed-off-by: Rajagopal Venkat --- src/devices/ahci.cpp| 4 ++-- src/devices/alsa.cpp| 4 ++-- src/devices/network.cpp | 16 src/main.cpp| 2 ++ 4 files changed, 6 insertions(+), 20 deletions(-) diff --git a/src/devices/ahci.cpp b/src/devices/ahci.cpp index 1fe39c7..67ce06e 100644 --- a/src/devices/ahci.cpp +++ b/src/devices/ahci.cpp @@ -170,7 +170,7 @@ void ahci::start_measurement(void) file.close(); } catch (std::ios_base::failure &c) { - fprintf(stderr, "%s\n", c.what()); + fprintf(stderr, "Failed to start measurement for ahci device\n"); } } @@ -203,7 +203,7 @@ void ahci::end_measurement(void) file.close(); } catch (std::ios_base::failure &c) { - fprintf(stderr, "%s\n", c.what()); + fprintf(stderr, "Failed to end measurement for ahci device\n"); } if (end_active < start_active) end_active = start_active; diff --git a/src/devices/alsa.cpp b/src/devices/alsa.cpp index 4f5d3f9..a67780c 100644 --- a/src/devices/alsa.cpp +++ b/src/devices/alsa.cpp @@ -104,7 +104,7 @@ void alsa::start_measurement(void) file.close(); } catch (std::ios_base::failure &c) { - fprintf(stderr, "%s\n", c.what()); + fprintf(stderr, "Failed to start measurement for alsa device\n"); } } @@ -130,7 +130,7 @@ void alsa::end_measurement(void) file.close(); } catch (std::ios_base::failure &c) { - fprintf(stderr, "%s\n", c.what()); + fprintf(stderr, "Failed to end measurement for alsa device\n"); } p = (end_active - start_active) / (0.001 + end_active + end_inactive - start_active - start_inactive) * 100.0; diff --git a/src/devices/network.cpp b/src/devices/network.cpp index b8a5c9c..ed9d7aa 100644 --- a/src/devices/network.cpp +++ b/src/devices/network.cpp @@ -55,22 +55,6 @@ extern "C" { static map nics; -#ifdef DISABLE_TRYCATCH - -static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep, - __u32 speed) -{ - - ep->speed = (__u16)speed; - ep->speed_hi = (__u16)(speed >> 16); -} - -static inline __u32 ethtool_cmd_speed(struct ethtool_cmd *ep) -{ - return (ep->speed_hi << 16) | ep->speed; -} - -#endif static void do_proc_net_dev(void) { diff --git a/src/main.cpp b/src/main.cpp index 1815075..dc49dba 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -42,7 +42,9 @@ #include "perf/perf.h" #include "perf/perf_bundle.h" #include "lib.h" +#ifdef HAVE_CONFIG_H #include "../config.h" +#endif #include "devices/device.h" -- 1.7.11.3 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[Powertop][PATCH v2 2/2] Add stubs to support Android platform
This patch adds stubs for features that are not supported by Andriod. An header file which defines all stubs is included only for Android builds. Signed-off-by: Rajagopal Venkat --- Android.mk | 33 ++- src/android_stubs.h | 65 + src/lib.h | 4 3 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 src/android_stubs.h diff --git a/Android.mk b/Android.mk index a52ecfd..081f470 100644 --- a/Android.mk +++ b/Android.mk @@ -1,17 +1,36 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) +LOCAL_MODULE := powertop + LOCAL_MODULE_TAGS := debug LOCAL_SHARED_LIBRARIES := libstlport \ libnl \ libpci \ - libtraceevnet \ -LOCAL_MODULE := powertop + +LOCAL_STATIC_LIBRARIES := libncurses + +CSSTOH_SOURCE := $(LOCAL_PATH)/src/csstoh.c +POWERTOP_CSS_SOURCE := $(LOCAL_PATH)/src/powertop.css +GEN_CSSTOH := $(LOCAL_PATH)/src/csstoh +GEN_CSS_H := $(LOCAL_PATH)/src/css.h +$(GEN_CSS_H): + $(CC) -o $(GEN_CSSTOH) $(CSSTOH_SOURCE) + ./$(GEN_CSSTOH) $(POWERTOP_CSS_SOURCE) $@ + +LOCAL_GENERATED_SOURCES += $(GEN_CSS_H) #LOCAL_CFLAGS += -Wall -O2 -g -fno-omit-frame-pointer -fstack-protector -Wshadow -Wformat -D_FORTIFY_SOURCE=2 #LOCAL_CPPFLAGS += -Wall -O2 -g -fno-omit-frame-pointer -LOCAL_C_INCLUDES += external/stlport/stlport/ external/stlport/stlport/stl external/stlport/stlport/using/h/ bionic external/libnl/include/ +LOCAL_C_INCLUDES += external/stlport/stlport/ \ + external/stlport/stlport/stl \ + external/stlport/stlport/using/h/ \ + bionic \ + external/libnl/include/ \ + external/ncurses/include \ + external/elfutils/bionic-fixup \ + $(LOCAL_PATH)/src LOCAL_SRC_FILES += \ src/parameters/parameters.cpp \ @@ -21,10 +40,11 @@ LOCAL_SRC_FILES += \ src/process/work.cpp \ src/process/process.cpp \ src/process/timer.cpp \ - src/process/device.cpp \ + src/process/processdevice.cpp \ src/process/interrupt.cpp \ src/process/do_process.cpp \ src/cpu/intel_cpus.cpp \ + src/cpu/intel_gpu.cpp \ src/cpu/cpu.cpp \ src/cpu/cpu_linux.cpp \ src/cpu/cpudevice.cpp \ @@ -33,20 +53,21 @@ LOCAL_SRC_FILES += \ src/cpu/abstract_cpu.cpp \ src/measurement/measurement.cpp \ src/measurement/acpi.cpp \ + src/measurement/sysfs.cpp \ src/measurement/extech.cpp \ src/measurement/power_supply.cpp \ src/display.cpp \ src/report.cpp \ src/main.cpp \ src/tuning/tuning.cpp \ - src/tuning/usb.cpp \ + src/tuning/tuningusb.cpp \ src/tuning/bluetooth.cpp \ src/tuning/ethernet.cpp \ src/tuning/runtime.cpp \ src/tuning/iw.c \ src/tuning/iw.h \ src/tuning/tunable.cpp \ - src/tuning/sysfs.cpp \ + src/tuning/tuningsysfs.cpp \ src/tuning/cpufreq.cpp \ src/tuning/wifi.cpp \ src/perf/perf_bundle.cpp \ diff --git a/src/android_stubs.h b/src/android_stubs.h new file mode 100644 index 000..ed37c0e --- /dev/null +++ b/src/android_stubs.h @@ -0,0 +1,65 @@ +#include +#include +#include +#include + + +/* Android doesn't provide locale support in its C and C++ + * runtime. Handled at higher level in application stack. + * So define stubs for gettext funtions used. + */ +#define PACKAGE0 +#define LOCALEDIR 0 +#define bindtextdomain(x, y) +#define textdomain(x) +#define gettext(x) (x) + +/* Android C++ new operator does not throw exception on failure */ +#define set_new_handler(x) + +/* define stubs for C++ exception handling */ +#define tryif (true) +#define catch(x) if (false) + +/* Define __NR_perf_event_open if not already defined */ +#if __arm__ +#ifndef __NR_perf_event_open +#define __NR_perf_event_open364 +#endif +#endif + +/* + * bionic libc mbstowcs version returns zero when max parameter + * is zero, resulting infinite loops in powertop source. Add + * mbstowcs wrapper to fix it. + */ +namespace pandroid { + extern "C" inline size_t mbstowcs(wchar_t *dst, + const char *src, size_t len) + { + return ::mbstowcs(dst, src, ::strlen(src)); + } +} + +#define mbstowcs(dst, src, len)pandroid::mbstowcs(dst, src, len) + +/* Implement missing functions */ +static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep, + __u32 speed) +{ + + ep->speed = (__u16)speed; + ep->speed_hi = (__u16)(speed >> 16); +} + +static inline __u32 ethtool_cmd_speed(struct ethtool_cmd *ep) +{ + return (ep->speed_hi << 16) | ep->speed; +} + +static inline char *strchrnul(const char *s, int c) +{ + wh
Re: [Powertop] [PATCH v2 1/2] Updates to support Android platform
On 24 September 2012 21:27, Chris Ferron wrote: > On 09/24/2012 06:28 AM, Rajagopal Venkat wrote: >> >> This patch adds following minor changes to prepare powertop >> to support Android platform. >> >> - Add missing HAVE_CONFIG_H conditional check. >> - remove un-used ethtool_cmd_speed_set and ethtool_cmd_speed >> functions. >> - Minimize dependency on exception handling in catch blocks. >> >> These changes will not affect powertop functionality. >> >> Signed-off-by: Rajagopal Venkat >> --- >> src/devices/ahci.cpp| 4 ++-- >> src/devices/alsa.cpp| 4 ++-- >> src/devices/network.cpp | 16 >> src/main.cpp| 2 ++ >> 4 files changed, 6 insertions(+), 20 deletions(-) >> >> diff --git a/src/devices/ahci.cpp b/src/devices/ahci.cpp >> index 1fe39c7..67ce06e 100644 >> --- a/src/devices/ahci.cpp >> +++ b/src/devices/ahci.cpp >> @@ -170,7 +170,7 @@ void ahci::start_measurement(void) >> file.close(); >> } >> catch (std::ios_base::failure &c) { >> - fprintf(stderr, "%s\n", c.what()); >> + fprintf(stderr, "Failed to start measurement for ahci >> device\n"); > > adding addition message here is acceptable, but eliminating the information > from the catches error is not. > As discussed in first patch set, android doesn't support exception handling. This is the reason powertop had DISABLE_TRYCATCH conditional macro which is removed in recent commit. The patch 2/2 adds stubs for exception handling #define try if (true) #define catch(x) if (false) With this, fprintf(stderr, "%s\n", c.what()); in catch block throws undefined reference to c. So added message instead of c.what(). Any better ways of adding stubs are welcome. > >> } >> } >> @@ -203,7 +203,7 @@ void ahci::end_measurement(void) >> file.close(); >> } >> catch (std::ios_base::failure &c) { >> - fprintf(stderr, "%s\n", c.what()); >> + fprintf(stderr, "Failed to end measurement for ahci >> device\n"); >> } >> if (end_active < start_active) >> end_active = start_active; >> diff --git a/src/devices/alsa.cpp b/src/devices/alsa.cpp >> index 4f5d3f9..a67780c 100644 >> --- a/src/devices/alsa.cpp >> +++ b/src/devices/alsa.cpp >> @@ -104,7 +104,7 @@ void alsa::start_measurement(void) >> file.close(); >> } >> catch (std::ios_base::failure &c) { >> - fprintf(stderr, "%s\n", c.what()); >> + fprintf(stderr, "Failed to start measurement for alsa >> device\n"); >> } >> } >> @@ -130,7 +130,7 @@ void alsa::end_measurement(void) >> file.close(); >> } >> catch (std::ios_base::failure &c) { >> - fprintf(stderr, "%s\n", c.what()); >> + fprintf(stderr, "Failed to end measurement for alsa >> device\n"); >> } >> p = (end_active - start_active) / (0.001 + end_active + >> end_inactive - start_active - start_inactive) * 100.0; >> diff --git a/src/devices/network.cpp b/src/devices/network.cpp >> index b8a5c9c..ed9d7aa 100644 >> --- a/src/devices/network.cpp >> +++ b/src/devices/network.cpp >> @@ -55,22 +55,6 @@ extern "C" { >> static map nics; >> -#ifdef DISABLE_TRYCATCH >> - >> -static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep, >> - __u32 speed) >> -{ >> - >> - ep->speed = (__u16)speed; >> - ep->speed_hi = (__u16)(speed >> 16); >> -} >> - >> -static inline __u32 ethtool_cmd_speed(struct ethtool_cmd *ep) >> -{ >> - return (ep->speed_hi << 16) | ep->speed; >> -} >> - >> -#endif >> static void do_proc_net_dev(void) >> { >> diff --git a/src/main.cpp b/src/main.cpp >> index 1815075..dc49dba 100644 >> --- a/src/main.cpp >> +++ b/src/main.cpp >> @@ -42,7 +42,9 @@ >> #include "perf/perf.h" >> #include "perf/perf_bundle.h" >> #include "lib.h" >> +#ifdef HAVE_CONFIG_H >> #include "../config.h" >> +#endif >> #include "devices/device.h" > > -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [PATCH v3 1/3] devfreq: Core updates to support devices which can idle
On 27 September 2012 13:50, MyungJoo Ham wrote: >> Prepare devfreq core framework to support devices which >> can idle. When device idleness is detected perhaps through >> runtime-pm, need some mechanism to suspend devfreq load >> monitoring and resume back when device is online. Present >> code continues monitoring unless device is removed from >> devfreq core. >> >> This patch introduces following design changes, >> >> - use per device work instead of global work to monitor device >> load. This enables suspend/resume of device devfreq and >> reduces monitoring code complexity. >> - decouple delayed work based load monitoring logic from core >> by introducing helpers functions to be used by governors. This >> provides flexibility for governors either to use delayed work >> based monitoring functions or to implement their own mechanism. >> - devfreq core interacts with governors via events to perform >> specific actions. These events include start/stop devfreq. >> This sets ground for adding suspend/resume events. >> >> The devfreq apis are not modified and are kept intact. >> >> Signed-off-by: Rajagopal Venkat > > Hello, > > > I'll do more through review tomorrow (sorry, I was occuppied by > something other than Linux tasks for a while again); however, > there are two concerns in this patch. > > 1. (minor but may bothersome in some rare but not-ignorable cases) > Serialization issue between suspend/resume > functions; this may happen with some failure or interrupts while entering STR > or > unexpected usage of the API at drivers. Regarding the invalid usage of suspend/resume apis, we can have additional checks something like, void devfreq_monitor_suspend(struct devfreq *devfreq) { . if (devfreq->stop_polling) return; .. } void devfreq_monitor_resume(struct devfreq *devfreq) { . if (!devfreq->stop_polling) return; .. } > > For example, if devfreq_monitor_suspend() and devfreq_montir_resume() are > called > almost simultaneously, we may execute 1) locked part of suspend, 2) locked > part of > resume, 3) cancel_delayed_work_sync of suspend. > > Then, we may have stop_polling = false w/ cancel_delayed_work_sync() in > effect. > > Let's not assume that suspend() and resume() may called almost > simultaneously, > especially in subsystem core code. > These devfreq_monitor_suspend() and devfreq_monitor_resume() functions are executed when device idleness is detected. Perhaps, - using runtime-pm: the runtime_suspend() and runtime_resume() are mutually exclusive and is guaranteed not to run in parallel. - driver may have its own mechanism: in my opinion, driver should ensure suspend/resume are sequential even for it to know its devfreq status. Assuming even if above sequence occurs, I don't see any problem having stop_polling = false w/ cancel_delayed_work_sync() in effect. Since the suspend is the last one to complete, monitoring will not continue. > > 2. What if polling_ms = 0 w/ active governors (such as ondemand)? > > Users may declare the initial polling_ms = 0 w/ simple-ondemand in order to > pause sampling at boot-time and start sampling at run-time some time later. > > It appears that this patch will start forcibly at boot-time in such a case. Yes. This is a valid case which can be handled by void devfreq_monitor_start(struct devfreq *devfreq) { INIT_DELAYED_WORK_DEFERRABLE(&devfreq->work, devfreq_monitor); + if (devfreq->profile->polling_ms) queue_delayed_work(devfreq_wq, &devfreq->work, msecs_to_jiffies(devfreq->profile->polling_ms)); } I wait for your thorough review before sending next version with this change. > > >> --- >> Documentation/ABI/testing/sysfs-class-devfreq | 8 - >> drivers/devfreq/devfreq.c | 431 >> +++--- >> drivers/devfreq/governor.h| 11 + >> drivers/devfreq/governor_performance.c| 16 +- >> drivers/devfreq/governor_powersave.c | 16 +- >> drivers/devfreq/governor_simpleondemand.c | 24 ++ >> drivers/devfreq/governor_userspace.c | 23 +- >> include/linux/devfreq.h | 34 +- >> 8 files changed, 267 insertions(+), 296 deletions(-) >> >> diff --git a/Documentation/ABI/testing/sysfs-class-devfreq >> b/Documentation/ABI/testing/sysfs-class-devfreq >> index 23d78b5..89283b1 100644 >> --- a/Documentation/ABI/testing/sysfs-class-devfreq >> +++ b/Documentation/ABI/testing/sysfs-class-devfreq >
Re: Re: [PATCH v3 1/3] devfreq: Core updates to support devices which can idle
On 2 October 2012 11:11, MyungJoo Ham wrote: >> On 27 September 2012 13:50, MyungJoo Ham wrote: >> >> Prepare devfreq core framework to support devices which >> >> can idle. When device idleness is detected perhaps through >> >> runtime-pm, need some mechanism to suspend devfreq load >> >> monitoring and resume back when device is online. Present >> >> code continues monitoring unless device is removed from >> >> devfreq core. >> >> >> >> This patch introduces following design changes, >> >> >> >> - use per device work instead of global work to monitor device >> >> load. This enables suspend/resume of device devfreq and >> >> reduces monitoring code complexity. >> >> - decouple delayed work based load monitoring logic from core >> >> by introducing helpers functions to be used by governors. This >> >> provides flexibility for governors either to use delayed work >> >> based monitoring functions or to implement their own mechanism. >> >> - devfreq core interacts with governors via events to perform >> >> specific actions. These events include start/stop devfreq. >> >> This sets ground for adding suspend/resume events. >> >> >> >> The devfreq apis are not modified and are kept intact. >> >> >> >> Signed-off-by: Rajagopal Venkat >> > >> > Hello, >> > >> > >> > I'll do more through review tomorrow (sorry, I was occuppied by >> > something other than Linux tasks for a while again); however, >> > there are two concerns in this patch. >> > >> > 1. (minor but may bothersome in some rare but not-ignorable cases) >> > Serialization issue between suspend/resume >> > functions; this may happen with some failure or interrupts while entering >> > STR or >> > unexpected usage of the API at drivers. >> >> Regarding the invalid usage of suspend/resume apis, we can have >> additional checks >> something like, >> >> void devfreq_monitor_suspend(struct devfreq *devfreq) >> { >> . >> if (devfreq->stop_polling) >> return; >> .. >> } >> >> void devfreq_monitor_resume(struct devfreq *devfreq) >> { >> . >> if (!devfreq->stop_polling) >> return; >> .. >> } >> >> > >> > For example, if devfreq_monitor_suspend() and devfreq_montir_resume() >> > are called >> > almost simultaneously, we may execute 1) locked part of suspend, 2) locked >> > part of >> > resume, 3) cancel_delayed_work_sync of suspend. >> > >> > Then, we may have stop_polling = false w/ cancel_delayed_work_sync() in >> > effect. >> > >> > Let's not assume that suspend() and resume() may called almost >> > simultaneously, >> > especially in subsystem core code. > > (sorry, I missed "not be" between "may" and "called" here) > >> > >> >> These devfreq_monitor_suspend() and devfreq_monitor_resume() functions are >> executed when device idleness is detected. Perhaps, >> - using runtime-pm: the runtime_suspend() and runtime_resume() are mutually >> exclusive and is guaranteed not to run in parallel. >> - driver may have its own mechanism: in my opinion, driver should ensure >> suspend/resume are sequential even for it to know its devfreq status. >> >> Assuming even if above sequence occurs, I don't see any problem having >> stop_polling = false w/ cancel_delayed_work_sync() in effect. Since the >> suspend >> is the last one to complete, monitoring will not continue. > > Why don't you simply extend the mutex-locked context? > > I.e., > + mutex_lock(&devfreq->lock); > + devfreq->stop_polling = true; > + mutex_unlock(&devfreq->lock); > + cancel_delayed_work_sync(&devfreq->work); > --> > + mutex_lock(&devfreq->lock); > + devfreq->stop_polling = true; > + cancel_delayed_work_sync(&devfreq->work); > + mutex_unlock(&devfreq->lock); > Extending the mutex-locked context would cause deadlock. Since scheduled work callback also needs mutex lock, calling cancel_delayed_work_sync with lock held, would cause deadlock. > This serializes data-update and the execution based on the data-update, > resolving any inconsistency issues w
[PATCH v4 2/3] devfreq: Add suspend and resume apis
Add devfreq suspend/resume apis for devfreq users. This patch supports suspend and resume of devfreq load monitoring, required for devices which can idle. Signed-off-by: Rajagopal Venkat Acked-by: MyungJoo Ham --- drivers/devfreq/devfreq.c | 28 drivers/devfreq/governor.h| 2 ++ drivers/devfreq/governor_simpleondemand.c | 9 + include/linux/devfreq.h | 12 4 files changed, 51 insertions(+) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 41a4099..63e075e 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -428,6 +428,34 @@ int devfreq_remove_device(struct devfreq *devfreq) } EXPORT_SYMBOL(devfreq_remove_device); +/** + * devfreq_suspend_device() - Suspend devfreq of a device. + * @devfreqthe devfreq instance to be suspended + */ +int devfreq_suspend_device(struct devfreq *devfreq) +{ + if (!devfreq) + return -EINVAL; + + return devfreq->governor->event_handler(devfreq, + DEVFREQ_GOV_SUSPEND, NULL); +} +EXPORT_SYMBOL(devfreq_suspend_device); + +/** + * devfreq_resume_device() - Resume devfreq of a device. + * @devfreqthe devfreq instance to be resumed + */ +int devfreq_resume_device(struct devfreq *devfreq) +{ + if (!devfreq) + return -EINVAL; + + return devfreq->governor->event_handler(devfreq, + DEVFREQ_GOV_RESUME, NULL); +} +EXPORT_SYMBOL(devfreq_resume_device); + static ssize_t show_governor(struct device *dev, struct device_attribute *attr, char *buf) { diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h index bb3aff3..26432ac 100644 --- a/drivers/devfreq/governor.h +++ b/drivers/devfreq/governor.h @@ -22,6 +22,8 @@ #define DEVFREQ_GOV_START 0x1 #define DEVFREQ_GOV_STOP 0x2 #define DEVFREQ_GOV_INTERVAL 0x3 +#define DEVFREQ_GOV_SUSPEND0x4 +#define DEVFREQ_GOV_RESUME 0x5 /* Caution: devfreq->lock must be locked before calling update_devfreq */ extern int update_devfreq(struct devfreq *devfreq); diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c index cf94218..a8ba78c 100644 --- a/drivers/devfreq/governor_simpleondemand.c +++ b/drivers/devfreq/governor_simpleondemand.c @@ -104,6 +104,15 @@ int devfreq_simple_ondemand_handler(struct devfreq *devfreq, case DEVFREQ_GOV_INTERVAL: devfreq_interval_update(devfreq, (unsigned int *)data); break; + + case DEVFREQ_GOV_SUSPEND: + devfreq_monitor_suspend(devfreq); + break; + + case DEVFREQ_GOV_RESUME: + devfreq_monitor_resume(devfreq); + break; + default: break; } diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 9cdffde..ee243a3 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -158,6 +158,8 @@ extern struct devfreq *devfreq_add_device(struct device *dev, const struct devfreq_governor *governor, void *data); extern int devfreq_remove_device(struct devfreq *devfreq); +extern int devfreq_suspend_device(struct devfreq *devfreq); +extern int devfreq_resume_device(struct devfreq *devfreq); /* Helper functions for devfreq user device driver with OPP. */ extern struct opp *devfreq_recommended_opp(struct device *dev, @@ -211,6 +213,16 @@ static int devfreq_remove_device(struct devfreq *devfreq) return 0; } +static int devfreq_suspend_device(struct devfreq *devfreq) +{ + return 0; +} + +static int devfreq_resume_device(struct devfreq *devfreq) +{ + return 0; +} + static struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, u32 flags) { -- 1.7.11.3 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH v4 3/3] devfreq: Add current freq callback in device profile
Devfreq returns governor predicted frequency as current frequency via sysfs interface. But device may not support all frequencies that governor predicts. So add a callback in device profile to get current freq from driver. Also add a new sysfs node to expose governor predicted next target frequency. Signed-off-by: Rajagopal Venkat Acked-by: MyungJoo Ham --- Documentation/ABI/testing/sysfs-class-devfreq | 11 ++- drivers/devfreq/devfreq.c | 14 ++ include/linux/devfreq.h | 3 +++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq index 89283b1..e6cf08e 100644 --- a/Documentation/ABI/testing/sysfs-class-devfreq +++ b/Documentation/ABI/testing/sysfs-class-devfreq @@ -19,7 +19,16 @@ Date:September 2011 Contact: MyungJoo Ham Description: The /sys/class/devfreq/.../cur_freq shows the current - frequency of the corresponding devfreq object. + frequency of the corresponding devfreq object. Same as + target_freq when get_cur_freq() is not implemented by + devfreq driver. + +What: /sys/class/devfreq/.../target_freq +Date: September 2012 +Contact: Rajagopal Venkat +Description: + The /sys/class/devfreq/.../target_freq shows the next governor + predicted target frequency of the corresponding devfreq object. What: /sys/class/devfreq/.../polling_interval Date: September 2011 diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 63e075e..9fdcb5d 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -465,6 +465,19 @@ static ssize_t show_governor(struct device *dev, static ssize_t show_freq(struct device *dev, struct device_attribute *attr, char *buf) { + unsigned long freq; + struct devfreq *devfreq = to_devfreq(dev); + + if (devfreq->profile->get_cur_freq && + !devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq)) + return sprintf(buf, "%lu\n", freq); + + return sprintf(buf, "%lu\n", devfreq->previous_freq); +} + +static ssize_t show_target_freq(struct device *dev, + struct device_attribute *attr, char *buf) +{ return sprintf(buf, "%lu\n", to_devfreq(dev)->previous_freq); } @@ -564,6 +577,7 @@ static ssize_t show_max_freq(struct device *dev, struct device_attribute *attr, static struct device_attribute devfreq_attrs[] = { __ATTR(governor, S_IRUGO, show_governor, NULL), __ATTR(cur_freq, S_IRUGO, show_freq, NULL), + __ATTR(target_freq, S_IRUGO, show_target_freq, NULL), __ATTR(polling_interval, S_IRUGO | S_IWUSR, show_polling_interval, store_polling_interval), __ATTR(min_freq, S_IRUGO | S_IWUSR, show_min_freq, store_min_freq), diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index ee243a3..7e2e2ea 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -66,6 +66,8 @@ struct devfreq_dev_status { * explained above with "DEVFREQ_FLAG_*" macros. * @get_dev_status The device should provide the current performance * status to devfreq, which is used by governors. + * @get_cur_freq The device should provide the current frequency + * at which it is operating. * @exit An optional callback that is called when devfreq * is removing the devfreq object due to error or * from devfreq_remove_device() call. If the user @@ -79,6 +81,7 @@ struct devfreq_dev_profile { int (*target)(struct device *dev, unsigned long *freq, u32 flags); int (*get_dev_status)(struct device *dev, struct devfreq_dev_status *stat); + int (*get_cur_freq)(struct device *dev, unsigned long *freq); void (*exit)(struct device *dev); }; -- 1.7.11.3 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH v4 0/3] devfreq: Add support for devices which can idle
This patchset updates devfreq core to add support for devices which can idle. When device idleness is detected perhaps through runtime-pm, need some mechanism to suspend devfreq load monitoring and resume when device is back online. patch 1 introduce core design changes - per device work, decouple delayed work from core and event based interaction. patch 2 add devfreq suspend and resume apis. patch 3 add new sysfs attribute for governor predicted next target frequency and callback for current device frequency. The existing devfreq apis are kept intact. Two new apis devfreq_suspend_device() and devfreq_resume_device() are added to support suspend/resume of device devfreq. Changes since v1: - revised locking mechanism - added kerneldoc comments for load monitoring helper functions - fixed minor review comments Changes since v2: - added new helper function for polling interval update - handled work suspend/resume contention between devfreq driver and sysfs Changes since v3: - added additonal checks in suspend/resume to avoid invalid usage of apis - added check in devfreq_monitor_start, not to start monitoring when polling_ms is set to zero. -- Rajagopal Venkat (3): devfreq: Core updates to support devices which can idle devfreq: Add suspend and resume apis devfreq: Add current freq callback in device profile Documentation/ABI/testing/sysfs-class-devfreq | 15 +- drivers/devfreq/devfreq.c | 481 -- drivers/devfreq/governor.h| 13 + drivers/devfreq/governor_performance.c| 16 +- drivers/devfreq/governor_powersave.c | 16 +- drivers/devfreq/governor_simpleondemand.c | 33 ++ drivers/devfreq/governor_userspace.c | 23 +- include/linux/devfreq.h | 49 +-- 8 files changed, 353 insertions(+), 293 deletions(-) -- 1.7.11.3 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH v4 1/3] devfreq: Core updates to support devices which can idle
Prepare devfreq core framework to support devices which can idle. When device idleness is detected perhaps through runtime-pm, need some mechanism to suspend devfreq load monitoring and resume back when device is online. Present code continues monitoring unless device is removed from devfreq core. This patch introduces following design changes, - use per device work instead of global work to monitor device load. This enables suspend/resume of device devfreq and reduces monitoring code complexity. - decouple delayed work based load monitoring logic from core by introducing helpers functions to be used by governors. This provides flexibility for governors either to use delayed work based monitoring functions or to implement their own mechanism. - devfreq core interacts with governors via events to perform specific actions. These events include start/stop devfreq. This sets ground for adding suspend/resume events. The devfreq apis are not modified and are kept intact. Signed-off-by: Rajagopal Venkat --- Documentation/ABI/testing/sysfs-class-devfreq | 8 - drivers/devfreq/devfreq.c | 443 +++--- drivers/devfreq/governor.h| 11 + drivers/devfreq/governor_performance.c| 16 +- drivers/devfreq/governor_powersave.c | 16 +- drivers/devfreq/governor_simpleondemand.c | 24 ++ drivers/devfreq/governor_userspace.c | 23 +- include/linux/devfreq.h | 34 +- 8 files changed, 279 insertions(+), 296 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq index 23d78b5..89283b1 100644 --- a/Documentation/ABI/testing/sysfs-class-devfreq +++ b/Documentation/ABI/testing/sysfs-class-devfreq @@ -21,14 +21,6 @@ Description: The /sys/class/devfreq/.../cur_freq shows the current frequency of the corresponding devfreq object. -What: /sys/class/devfreq/.../central_polling -Date: September 2011 -Contact: MyungJoo Ham -Description: - The /sys/class/devfreq/.../central_polling shows whether - the devfreq ojbect is using devfreq-provided central - polling mechanism or not. - What: /sys/class/devfreq/.../polling_interval Date: September 2011 Contact: MyungJoo Ham diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index b146d76..41a4099 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -30,17 +30,11 @@ struct class *devfreq_class; /* - * devfreq_work periodically monitors every registered device. - * The minimum polling interval is one jiffy. The polling interval is - * determined by the minimum polling period among all polling devfreq - * devices. The resolution of polling interval is one jiffy. + * devfreq core provides delayed work based load monitoring helper + * functions. Governors can use these or can implement their own + * monitoring mechanism. */ -static bool polling; static struct workqueue_struct *devfreq_wq; -static struct delayed_work devfreq_work; - -/* wait removing if this is to be removed */ -static struct devfreq *wait_remove_device; /* The list of all device-devfreq */ static LIST_HEAD(devfreq_list); @@ -72,6 +66,8 @@ static struct devfreq *find_device_devfreq(struct device *dev) return ERR_PTR(-ENODEV); } +/* Load monitoring helper functions for governors use */ + /** * update_devfreq() - Reevaluate the device and configure frequency. * @devfreq: the devfreq instance. @@ -121,6 +117,152 @@ int update_devfreq(struct devfreq *devfreq) } /** + * devfreq_monitor() - Periodically poll devfreq objects. + * @work: the work struct used to run devfreq_monitor periodically. + * + */ +static void devfreq_monitor(struct work_struct *work) +{ + int err; + struct devfreq *devfreq = container_of(work, + struct devfreq, work.work); + + mutex_lock(&devfreq->lock); + err = update_devfreq(devfreq); + if (err) + dev_err(&devfreq->dev, "dvfs failed with (%d) error\n", err); + + queue_delayed_work(devfreq_wq, &devfreq->work, + msecs_to_jiffies(devfreq->profile->polling_ms)); + mutex_unlock(&devfreq->lock); +} + +/** + * devfreq_monitor_start() - Start load monitoring of devfreq instance + * @devfreq: the devfreq instance. + * + * Helper function for starting devfreq device load monitoing. By + * default delayed work based monitoring is supported. Function + * to be called from governor in response to DEVFREQ_GOV_START + * event when device is added to devfreq framework. + */ +void devfreq_monitor_start(struct devfreq *devfreq) +{ + INIT_DEFERRABLE_WORK(&devfreq->work, devfreq_monitor); + if (devfreq->profile->polling_ms) +
Re: [PATCH v4 0/3] devfreq: Add support for devices which can idle
On 4 October 2012 18:06, MyungJoo Ham wrote: >> This patchset updates devfreq core to add support for devices >> which can idle. When device idleness is detected perhaps >> through runtime-pm, need some mechanism to suspend devfreq >> load monitoring and resume when device is back online. >> >> patch 1 introduce core design changes - per device work, decouple >> delayed work from core and event based interaction. >> patch 2 add devfreq suspend and resume apis. >> patch 3 add new sysfs attribute for governor predicted next target >> frequency and callback for current device frequency. >> >> The existing devfreq apis are kept intact. Two new apis >> devfreq_suspend_device() and devfreq_resume_device() are >> added to support suspend/resume of device devfreq. > > Could you please tell me which version you have rebased? > > It seems that the patchset has issues on applying over 3.6. > (tried at a0d271cbfed1dd50278c6b06bead3d00ba0a88f9) These patches are rebased against Linus tree. The 203b42f7317494ae5e5efc7be6fb7f29c927f102 commit, which renames INIT_DELAYED_WORK_DEFERRABLE to INIT_DEFERRABLE_WORK could be the reason for patchset not applying over 3.6. > > >> >> Changes since v1: >> - revised locking mechanism >> - added kerneldoc comments for load monitoring helper functions >> - fixed minor review comments >> >> Changes since v2: >> - added new helper function for polling interval update >> - handled work suspend/resume contention between devfreq driver >> and sysfs >> >> Changes since v3: >> - added additonal checks in suspend/resume to avoid invalid usage of apis >> - added check in devfreq_monitor_start, not to start monitoring when >> polling_ms is set to zero. >> >> -- >> Rajagopal Venkat (3): >> devfreq: Core updates to support devices which can idle >> devfreq: Add suspend and resume apis >> devfreq: Add current freq callback in device profile >> >> Documentation/ABI/testing/sysfs-class-devfreq | 15 +- >> drivers/devfreq/devfreq.c | 481 >> -- >> drivers/devfreq/governor.h| 13 + >> drivers/devfreq/governor_performance.c| 16 +- >> drivers/devfreq/governor_powersave.c | 16 +- >> drivers/devfreq/governor_simpleondemand.c | 33 ++ >> drivers/devfreq/governor_userspace.c | 23 +- >> include/linux/devfreq.h | 49 +-- >> 8 files changed, 353 insertions(+), 293 deletions(-) >> >> -- >> 1.7.11.3 >> >> >> >> >> >> >> >> -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [PATCH v4 1/3] devfreq: Core updates to support devices which can idle
On 8 October 2012 13:44, MyungJoo Ham wrote: >> Prepare devfreq core framework to support devices which >> can idle. When device idleness is detected perhaps through >> runtime-pm, need some mechanism to suspend devfreq load >> monitoring and resume back when device is online. Present >> code continues monitoring unless device is removed from >> devfreq core. >> >> This patch introduces following design changes, >> >> - use per device work instead of global work to monitor device >> load. This enables suspend/resume of device devfreq and >> reduces monitoring code complexity. >> - decouple delayed work based load monitoring logic from core >> by introducing helpers functions to be used by governors. This >> provides flexibility for governors either to use delayed work >> based monitoring functions or to implement their own mechanism. >> - devfreq core interacts with governors via events to perform >> specific actions. These events include start/stop devfreq. >> This sets ground for adding suspend/resume events. >> >> The devfreq apis are not modified and are kept intact. >> >> Signed-off-by: Rajagopal Venkat > > Thank you! > > > Reviewed and Tested (at Exynos4210-Nuri). > > Acked-by: MyungJoo Ham > Hi MyungJoo, Thanks for reviewing and testing this patchset. >> --- >> Documentation/ABI/testing/sysfs-class-devfreq | 8 - >> drivers/devfreq/devfreq.c | 443 >> +++--- >> drivers/devfreq/governor.h| 11 + >> drivers/devfreq/governor_performance.c| 16 +- >> drivers/devfreq/governor_powersave.c | 16 +- >> drivers/devfreq/governor_simpleondemand.c | 24 ++ >> drivers/devfreq/governor_userspace.c | 23 +- >> include/linux/devfreq.h | 34 +- >> 8 files changed, 279 insertions(+), 296 deletions(-) >> >> diff --git a/Documentation/ABI/testing/sysfs-class-devfreq >> b/Documentation/ABI/testing/sysfs-class-devfreq >> index 23d78b5..89283b1 100644 >> --- a/Documentation/ABI/testing/sysfs-class-devfreq >> +++ b/Documentation/ABI/testing/sysfs-class-devfreq >> @@ -21,14 +21,6 @@ Description: >> The /sys/class/devfreq/.../cur_freq shows the current >> frequency of the corresponding devfreq object. >> >> -What:/sys/class/devfreq/.../central_polling >> -Date:September 2011 >> -Contact: MyungJoo Ham >> -Description: >> - The /sys/class/devfreq/.../central_polling shows whether >> - the devfreq ojbect is using devfreq-provided central >> - polling mechanism or not. >> - >> What:/sys/class/devfreq/.../polling_interval >> Date:September 2011 >> Contact: MyungJoo Ham >> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c >> index b146d76..41a4099 100644 >> --- a/drivers/devfreq/devfreq.c >> +++ b/drivers/devfreq/devfreq.c >> @@ -30,17 +30,11 @@ >> struct class *devfreq_class; >> >> /* >> - * devfreq_work periodically monitors every registered device. >> - * The minimum polling interval is one jiffy. The polling interval is >> - * determined by the minimum polling period among all polling devfreq >> - * devices. The resolution of polling interval is one jiffy. >> + * devfreq core provides delayed work based load monitoring helper >> + * functions. Governors can use these or can implement their own >> + * monitoring mechanism. >> */ >> -static bool polling; >> static struct workqueue_struct *devfreq_wq; >> -static struct delayed_work devfreq_work; >> - >> -/* wait removing if this is to be removed */ >> -static struct devfreq *wait_remove_device; >> >> /* The list of all device-devfreq */ >> static LIST_HEAD(devfreq_list); >> @@ -72,6 +66,8 @@ static struct devfreq *find_device_devfreq(struct device >> *dev) >> return ERR_PTR(-ENODEV); >> } >> >> +/* Load monitoring helper functions for governors use */ >> + >> /** >> * update_devfreq() - Reevaluate the device and configure frequency. >> * @devfreq: the devfreq instance. >> @@ -121,6 +117,152 @@ int update_devfreq(struct devfreq *devfreq) >> } >> >> /** >> + * devfreq_monitor() - Periodically poll devfreq objects. >> + * @work:the work struct used to run devfreq_monitor periodically. >> + * >> + */ >> +static void devfreq_monitor(struct work_s
Re: [PATCH v4 2/3] devfreq: Add suspend and resume apis
On 8 October 2012 03:31, Rafael J. Wysocki wrote: > On Thursday 04 of October 2012 14:58:33 Rajagopal Venkat wrote: >> Add devfreq suspend/resume apis for devfreq users. This patch >> supports suspend and resume of devfreq load monitoring, required >> for devices which can idle. >> >> Signed-off-by: Rajagopal Venkat >> Acked-by: MyungJoo Ham > > Well, I wonder if this may be tied in to the runtime PM framework, so that, > for example, pm_runtime_suspend() will automatically suspend devfreq on > success (and the runtime resume of the device will resume devfreq)? That's a good idea. If you agree, we can handle this as separate patch on top this patchset. > > Rafael > > >> --- >> drivers/devfreq/devfreq.c | 28 >> drivers/devfreq/governor.h| 2 ++ >> drivers/devfreq/governor_simpleondemand.c | 9 + >> include/linux/devfreq.h | 12 >> 4 files changed, 51 insertions(+) >> >> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c >> index 41a4099..63e075e 100644 >> --- a/drivers/devfreq/devfreq.c >> +++ b/drivers/devfreq/devfreq.c >> @@ -428,6 +428,34 @@ int devfreq_remove_device(struct devfreq *devfreq) >> } >> EXPORT_SYMBOL(devfreq_remove_device); >> >> +/** >> + * devfreq_suspend_device() - Suspend devfreq of a device. >> + * @devfreq the devfreq instance to be suspended >> + */ >> +int devfreq_suspend_device(struct devfreq *devfreq) >> +{ >> + if (!devfreq) >> + return -EINVAL; >> + >> + return devfreq->governor->event_handler(devfreq, >> + DEVFREQ_GOV_SUSPEND, NULL); >> +} >> +EXPORT_SYMBOL(devfreq_suspend_device); >> + >> +/** >> + * devfreq_resume_device() - Resume devfreq of a device. >> + * @devfreq the devfreq instance to be resumed >> + */ >> +int devfreq_resume_device(struct devfreq *devfreq) >> +{ >> + if (!devfreq) >> + return -EINVAL; >> + >> + return devfreq->governor->event_handler(devfreq, >> + DEVFREQ_GOV_RESUME, NULL); >> +} >> +EXPORT_SYMBOL(devfreq_resume_device); >> + >> static ssize_t show_governor(struct device *dev, >>struct device_attribute *attr, char *buf) >> { >> diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h >> index bb3aff3..26432ac 100644 >> --- a/drivers/devfreq/governor.h >> +++ b/drivers/devfreq/governor.h >> @@ -22,6 +22,8 @@ >> #define DEVFREQ_GOV_START0x1 >> #define DEVFREQ_GOV_STOP 0x2 >> #define DEVFREQ_GOV_INTERVAL 0x3 >> +#define DEVFREQ_GOV_SUSPEND 0x4 >> +#define DEVFREQ_GOV_RESUME 0x5 >> >> /* Caution: devfreq->lock must be locked before calling update_devfreq */ >> extern int update_devfreq(struct devfreq *devfreq); >> diff --git a/drivers/devfreq/governor_simpleondemand.c >> b/drivers/devfreq/governor_simpleondemand.c >> index cf94218..a8ba78c 100644 >> --- a/drivers/devfreq/governor_simpleondemand.c >> +++ b/drivers/devfreq/governor_simpleondemand.c >> @@ -104,6 +104,15 @@ int devfreq_simple_ondemand_handler(struct devfreq >> *devfreq, >> case DEVFREQ_GOV_INTERVAL: >> devfreq_interval_update(devfreq, (unsigned int *)data); >> break; >> + >> + case DEVFREQ_GOV_SUSPEND: >> + devfreq_monitor_suspend(devfreq); >> + break; >> + >> + case DEVFREQ_GOV_RESUME: >> + devfreq_monitor_resume(devfreq); >> + break; >> + >> default: >> break; >> } >> diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h >> index 9cdffde..ee243a3 100644 >> --- a/include/linux/devfreq.h >> +++ b/include/linux/devfreq.h >> @@ -158,6 +158,8 @@ extern struct devfreq *devfreq_add_device(struct device >> *dev, >> const struct devfreq_governor *governor, >> void *data); >> extern int devfreq_remove_device(struct devfreq *devfreq); >> +extern int devfreq_suspend_device(struct devfreq *devfreq); >> +extern int devfreq_resume_device(struct devfreq *devfreq); >> >> /* Helper functions for devfreq user device driver with OPP. */ >> extern struct opp *devfreq_recommended_opp(struct device *dev, >>
Re: [PATCH v4 1/3] devfreq: Core updates to support devices which can idle
On 8 October 2012 13:44, MyungJoo Ham wrote: >> Prepare devfreq core framework to support devices which >> can idle. When device idleness is detected perhaps through >> runtime-pm, need some mechanism to suspend devfreq load >> monitoring and resume back when device is online. Present >> code continues monitoring unless device is removed from >> devfreq core. >> >> This patch introduces following design changes, >> >> - use per device work instead of global work to monitor device >> load. This enables suspend/resume of device devfreq and >> reduces monitoring code complexity. >> - decouple delayed work based load monitoring logic from core >> by introducing helpers functions to be used by governors. This >> provides flexibility for governors either to use delayed work >> based monitoring functions or to implement their own mechanism. >> - devfreq core interacts with governors via events to perform >> specific actions. These events include start/stop devfreq. >> This sets ground for adding suspend/resume events. >> >> The devfreq apis are not modified and are kept intact. >> >> Signed-off-by: Rajagopal Venkat > > Thank you! > > > Reviewed and Tested (at Exynos4210-Nuri). > > Acked-by: MyungJoo Ham > Rafael, Can this patchset be queued for v3.7? Thanks. >> --- >> Documentation/ABI/testing/sysfs-class-devfreq | 8 - >> drivers/devfreq/devfreq.c | 443 >> +++--- >> drivers/devfreq/governor.h| 11 + >> drivers/devfreq/governor_performance.c| 16 +- >> drivers/devfreq/governor_powersave.c | 16 +- >> drivers/devfreq/governor_simpleondemand.c | 24 ++ >> drivers/devfreq/governor_userspace.c | 23 +- >> include/linux/devfreq.h | 34 +- >> 8 files changed, 279 insertions(+), 296 deletions(-) >> -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH][RFC] Mali: Add devfreq support
This patch adds devfreq support for Mali driver. Though mali driver has its own mechanism for load monitoring, this patch makes use of devfreq framework to achieve same functionality. The goal is to export gpu dvfs information to user space. Depends on devfreq patchset - https://lkml.org/lkml/2012/10/4/95 Patch is based on git://git.linaro.org/people/chunsangjeong/mali-dev.git tree. Signed-off-by: Rajagopal Venkat --- drivers/gpu/arm/mali/Kconfig | 7 + drivers/gpu/arm/mali/Makefile | 11 ++ drivers/gpu/arm/mali/linux/mali_kernel_devfreq.c | 188 + drivers/gpu/arm/mali/linux/mali_kernel_devfreq.h | 51 ++ drivers/gpu/arm/mali/linux/mali_kernel_pm.c| 10 ++ .../gpu/arm/mali/platform/default/mali_platform.c | 5 +- drivers/gpu/arm/mali/platform/mali_platform.h | 8 + 7 files changed, 279 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/arm/mali/linux/mali_kernel_devfreq.c create mode 100644 drivers/gpu/arm/mali/linux/mali_kernel_devfreq.h diff --git a/drivers/gpu/arm/mali/Kconfig b/drivers/gpu/arm/mali/Kconfig index 416c231..41634f9 100644 --- a/drivers/gpu/arm/mali/Kconfig +++ b/drivers/gpu/arm/mali/Kconfig @@ -39,6 +39,13 @@ config USING_GPU_UTILIZATION ---help--- This enables GPU utilization information. +config USING_GPU_DEVFREQ + bool "GPU devfreq" +depends on MALI400MP && USING_GPU_UTILIZATION +default n +---help--- +This enables GPU devfreq. + config USING_MALI_RUN_TIME_PM bool "Using Run time Power Management" depends on MALI400MP diff --git a/drivers/gpu/arm/mali/Makefile b/drivers/gpu/arm/mali/Makefile index 525a23e..6c854b1 100755 --- a/drivers/gpu/arm/mali/Makefile +++ b/drivers/gpu/arm/mali/Makefile @@ -45,6 +45,10 @@ ifeq ($(CONFIG_USING_GPU_UTILIZATION),y) USING_GPU_UTILIZATION =1 endif +ifeq ($(CONFIG_USING_GPU_DEVFREQ),y) +USING_GPU_DEVFREQ =1 +endif + ifeq ($(CONFIG_USING_MALI_RUN_TIME_PM),y) USING_MALI_RUN_TIME_PM =1 endif @@ -64,6 +68,7 @@ USING_UMP ?= 0 USING_OS_MEMORY ?= 0 USING_PMM ?= 0 USING_GPU_UTILIZATION ?= 0 +USING_GPU_DEVFREQ ?= 0 USING_MALI_RUN_TIME_PM ?= 0 USING_MALI_PMM_TESTSUITE ?= 0 OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 6 @@ -105,6 +110,7 @@ endif DEFINES += -DUSING_MALI_PMM=$(USING_PMM) DEFINES += -DMALI_GPU_UTILIZATION=$(USING_GPU_UTILIZATION) +DEFINES += -DMALI_GPU_DEVFREQ=$(USING_GPU_DEVFREQ) ifeq ($(CONFIG_DEBUG_BUILD),y) DEFINES += -DDEBUG @@ -201,9 +207,14 @@ mali-y += \ endif ifeq ($(USING_GPU_UTILIZATION),1) +ifeq ($(USING_GPU_DEVFREQ),1) +mali-y += \ + linux/mali_kernel_devfreq.o +else mali-y += \ common/mali_kernel_utilization.o endif +endif ifneq ($(call submodule_enabled, $M, MALI400PP),0) # Mali-400 PP in use diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_devfreq.c b/drivers/gpu/arm/mali/linux/mali_kernel_devfreq.c new file mode 100644 index 000..1213e7b --- /dev/null +++ b/drivers/gpu/arm/mali/linux/mali_kernel_devfreq.c @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include "mali_kernel_devfreq.h" +#include "mali_osk.h" +#include "mali_platform.h" +#include "mali_linux_pm.h" + +#define MALI_GPU_UTILIZATION_PERIOD500 + +static _mali_osk_lock_t *time_data_lock; + +static _mali_osk_atomic_t num_running_cores; + +static u64 period_start_time = 0; +static u64 work_start_time = 0; +static u64 accumulated_work_time = 0; +static mali_bool timer_running = MALI_FALSE; + +static struct devfreq *mali_devfreq; + +static int mali_get_dev_status(struct device *dev, + struct devfreq_dev_status *stat) +{ + u64 time_now; + u64 time_period; + + _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW); + + if (accumulated_work_time == 0 && work_start_time == 0) + { + /* No work done for this period, report zero usage */ + stat->total_time = 0; + stat->busy_time = 0; + stat->current_frequency = get_mali_platform_cur_freq(); + + _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW); + + return 0; + } + + time_now = _mali_osk_time_get_ns(); + time_period = time_now - period_start_time; + + /* If we are currently busy, update working period up to now
Re: [PATCH][RFC] Mali: Add devfreq support
On 15 October 2012 14:20, Amit Kucheria wrote: > On Mon, Oct 15, 2012 at 1:51 PM, Rajagopal Venkat > wrote: >> This patch adds devfreq support for Mali driver. Though mali driver >> has its own mechanism for load monitoring, this patch makes use of >> devfreq framework to achieve same functionality. The goal is to >> export gpu dvfs information to user space. >> >> Depends on devfreq patchset - https://lkml.org/lkml/2012/10/4/95 >> >> Patch is based on git://git.linaro.org/people/chunsangjeong/mali-dev.git >> tree. > > Adding Jesse and Andrey to cc. > > Let's make sure that we coordinate this patch integration into the > mali driver with the integration of your devfreq patches to LLCT. In > fact, I suggest that Andrey pull in your devfreq patchset into LLCT > now since it won't break anything. The devfreq patches have dependency on workqueue related patches available in 3.7-rc1. I suggest we wait till linux-linaro tree is rebased to 3.7-rc1. Then pulling the devfreq and mali changes is straight forward. > > /Amit > >> Signed-off-by: Rajagopal Venkat >> --- >> drivers/gpu/arm/mali/Kconfig | 7 + >> drivers/gpu/arm/mali/Makefile | 11 ++ >> drivers/gpu/arm/mali/linux/mali_kernel_devfreq.c | 188 >> + >> drivers/gpu/arm/mali/linux/mali_kernel_devfreq.h | 51 ++ >> drivers/gpu/arm/mali/linux/mali_kernel_pm.c| 10 ++ >> .../gpu/arm/mali/platform/default/mali_platform.c | 5 +- >> drivers/gpu/arm/mali/platform/mali_platform.h | 8 + >> 7 files changed, 279 insertions(+), 1 deletion(-) >> create mode 100644 drivers/gpu/arm/mali/linux/mali_kernel_devfreq.c >> create mode 100644 drivers/gpu/arm/mali/linux/mali_kernel_devfreq.h >> >> diff --git a/drivers/gpu/arm/mali/Kconfig b/drivers/gpu/arm/mali/Kconfig >> index 416c231..41634f9 100644 >> --- a/drivers/gpu/arm/mali/Kconfig >> +++ b/drivers/gpu/arm/mali/Kconfig >> @@ -39,6 +39,13 @@ config USING_GPU_UTILIZATION >> ---help--- >> This enables GPU utilization information. >> >> +config USING_GPU_DEVFREQ >> + bool "GPU devfreq" >> +depends on MALI400MP && USING_GPU_UTILIZATION >> +default n >> +---help--- >> +This enables GPU devfreq. >> + >> config USING_MALI_RUN_TIME_PM >> bool "Using Run time Power Management" >> depends on MALI400MP >> diff --git a/drivers/gpu/arm/mali/Makefile b/drivers/gpu/arm/mali/Makefile >> index 525a23e..6c854b1 100755 >> --- a/drivers/gpu/arm/mali/Makefile >> +++ b/drivers/gpu/arm/mali/Makefile >> @@ -45,6 +45,10 @@ ifeq ($(CONFIG_USING_GPU_UTILIZATION),y) >> USING_GPU_UTILIZATION =1 >> endif >> >> +ifeq ($(CONFIG_USING_GPU_DEVFREQ),y) >> +USING_GPU_DEVFREQ =1 >> +endif >> + >> ifeq ($(CONFIG_USING_MALI_RUN_TIME_PM),y) >> USING_MALI_RUN_TIME_PM =1 >> endif >> @@ -64,6 +68,7 @@ USING_UMP ?= 0 >> USING_OS_MEMORY ?= 0 >> USING_PMM ?= 0 >> USING_GPU_UTILIZATION ?= 0 >> +USING_GPU_DEVFREQ ?= 0 >> USING_MALI_RUN_TIME_PM ?= 0 >> USING_MALI_PMM_TESTSUITE ?= 0 >> OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 6 >> @@ -105,6 +110,7 @@ endif >> >> DEFINES += -DUSING_MALI_PMM=$(USING_PMM) >> DEFINES += -DMALI_GPU_UTILIZATION=$(USING_GPU_UTILIZATION) >> +DEFINES += -DMALI_GPU_DEVFREQ=$(USING_GPU_DEVFREQ) >> >> ifeq ($(CONFIG_DEBUG_BUILD),y) >> DEFINES += -DDEBUG >> @@ -201,9 +207,14 @@ mali-y += \ >> endif >> >> ifeq ($(USING_GPU_UTILIZATION),1) >> +ifeq ($(USING_GPU_DEVFREQ),1) >> +mali-y += \ >> + linux/mali_kernel_devfreq.o >> +else >> mali-y += \ >> common/mali_kernel_utilization.o >> endif >> +endif >> >> ifneq ($(call submodule_enabled, $M, MALI400PP),0) >> # Mali-400 PP in use >> diff --git a/drivers/gpu/arm/mali/linux/mali_kernel_devfreq.c >> b/drivers/gpu/arm/mali/linux/mali_kernel_devfreq.c >> new file mode 100644 >> index 000..1213e7b >> --- /dev/null >> +++ b/drivers/gpu/arm/mali/linux/mali_kernel_devfreq.c >> @@ -0,0 +1,188 @@ >> +/* >> + * Copyright (C) 2010-2011 ARM Limited. All rights reserved. >> + * >> + * This program is free software and is provided to you under the terms of >> the GNU General Public License version 2 >> + * as published by the Free Software Foundation, and any use by you of this >> program is subject to the terms
[RFC PATCH] PM / devfreq: Add runtime-pm support
Instead of devfreq device driver explicitly calling devfreq suspend and resume apis perhaps from runtime-pm suspend and resume callbacks, let devfreq core handle it automatically. Attach devfreq core to runtime-pm framework so that, devfreq device driver pm_runtime_suspend() will automatically suspend the devfreq and pm_runtime_resume() will resume the devfreq. Signed-off-by: Rajagopal Venkat --- drivers/devfreq/devfreq.c | 145 -- include/linux/devfreq.h | 12 2 files changed, 102 insertions(+), 55 deletions(-) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 45e053e..190e414 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -25,10 +25,9 @@ #include #include #include +#include #include "governor.h" -static struct class *devfreq_class; - /* * devfreq core provides delayed work based load monitoring helper * functions. Governors can use these or can implement their own @@ -414,6 +413,93 @@ static void devfreq_dev_release(struct device *dev) } /** + * devfreq_suspend_device() - Suspend devfreq of a device. + * @devfreq: the devfreq instance to be suspended + */ +static int devfreq_suspend_device(struct devfreq *devfreq) +{ + if (!devfreq) + return -EINVAL; + + if (!devfreq->governor) + return 0; + + return devfreq->governor->event_handler(devfreq, + DEVFREQ_GOV_SUSPEND, NULL); +} + +/** + * devfreq_resume_device() - Resume devfreq of a device. + * @devfreq: the devfreq instance to be resumed + */ +static int devfreq_resume_device(struct devfreq *devfreq) +{ + if (!devfreq) + return -EINVAL; + + if (!devfreq->governor) + return 0; + + return devfreq->governor->event_handler(devfreq, + DEVFREQ_GOV_RESUME, NULL); +} + +static int devfreq_runtime_suspend(struct device *dev) +{ + int ret; + struct devfreq *devfreq; + + mutex_lock(&devfreq_list_lock); + devfreq = find_device_devfreq(dev); + mutex_unlock(&devfreq_list_lock); + + ret = devfreq_suspend_device(devfreq); + if (ret < 0) + goto out; + + ret = pm_generic_runtime_suspend(dev); +out: + return ret; +} + +static int devfreq_runtime_resume(struct device *dev) +{ + int ret; + struct devfreq *devfreq; + + mutex_lock(&devfreq_list_lock); + devfreq = find_device_devfreq(dev); + mutex_unlock(&devfreq_list_lock); + + ret = devfreq_resume_device(devfreq); + if (ret < 0) + goto out; + + ret = pm_generic_runtime_resume(dev); +out: + return ret; +} + +static int devfreq_runtime_idle(struct device *dev) +{ + return pm_generic_runtime_idle(dev); +} + +static const struct dev_pm_ops devfreq_pm_ops = { + SET_RUNTIME_PM_OPS( + devfreq_runtime_suspend, + devfreq_runtime_resume, + devfreq_runtime_idle + ) +}; + +static struct class devfreq_class = { + .name = "devfreq", + .owner = THIS_MODULE, + .pm = &devfreq_pm_ops, +}; + +/** * devfreq_add_device() - Add devfreq feature to the device * @dev: the device to add devfreq feature. * @profile: device-specific profile to run devfreq. @@ -454,8 +540,9 @@ struct devfreq *devfreq_add_device(struct device *dev, mutex_init(&devfreq->lock); mutex_lock(&devfreq->lock); + dev->class = &devfreq_class; devfreq->dev.parent = dev; - devfreq->dev.class = devfreq_class; + devfreq->dev.class = &devfreq_class; devfreq->dev.release = devfreq_dev_release; devfreq->profile = profile; strncpy(devfreq->governor_name, governor_name, DEVFREQ_NAME_LEN); @@ -498,6 +585,9 @@ struct devfreq *devfreq_add_device(struct device *dev, goto err_init; } + pm_runtime_get_noresume(dev); + pm_runtime_set_active(dev); + return devfreq; err_init: @@ -526,40 +616,6 @@ int devfreq_remove_device(struct devfreq *devfreq) EXPORT_SYMBOL(devfreq_remove_device); /** - * devfreq_suspend_device() - Suspend devfreq of a device. - * @devfreq: the devfreq instance to be suspended - */ -int devfreq_suspend_device(struct devfreq *devfreq) -{ - if (!devfreq) - return -EINVAL; - - if (!devfreq->governor) - return 0; - - return devfreq->governor->event_handler(devfreq, - DEVFREQ_GOV_SUSPEND, NULL); -} -EXPORT_SYMBOL(devfreq_suspend_device); - -/** - * devfreq_resume_device() - Resume devfreq of a device. - * @devfreq: the devfreq instance to be resumed - */ -int devfreq_resume_device(struct devfreq *devfreq) -{ - if (!devfreq) - return -EINVAL; -
[Powertop][PATCH v1] Allow frequency stats when cpuidle is not enabled
Powertop fails to display frequency stats when cpuidle subsystem is not enabled. Fix it. Signed-off-by: Rajagopal Venkat --- src/cpu/cpu.h | 7 ++- src/cpu/cpu_linux.cpp | 36 +++- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 4480b11..781e33c 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -159,7 +159,12 @@ extern vector all_cpus; class cpu_linux: public abstract_cpu { - voidaccount_freq(uint64_t frequency, uint64_t duration); + voidaccount_freq(uint64_t frequency, uint64_t duration); + voidparse_pstates_start(void); + voidparse_cstates_start(void); + voidparse_pstates_end(void); + voidparse_cstates_end(void); + public: virtual voidmeasurement_start(void); virtual voidmeasurement_end(void); diff --git a/src/cpu/cpu_linux.cpp b/src/cpu/cpu_linux.cpp index d6caf45..e7a3d37 100644 --- a/src/cpu/cpu_linux.cpp +++ b/src/cpu/cpu_linux.cpp @@ -47,17 +47,13 @@ static int is_turbo(uint64_t freq, uint64_t max, uint64_t maxmo) return 1; } -void cpu_linux::measurement_start(void) +void cpu_linux::parse_cstates_start(void) { ifstream file; - DIR *dir; struct dirent *entry; char filename[256]; int len; - unsigned int i; - - abstract_cpu::measurement_start(); len = sprintf(filename, "/sys/devices/system/cpu/cpu%i/cpuidle", number); @@ -111,9 +107,16 @@ void cpu_linux::measurement_start(void) } closedir(dir); +} - last_stamp = 0; +void cpu_linux::parse_pstates_start(void) +{ + ifstream file; + char filename[256]; + unsigned int i; + + last_stamp = 0; for (i = 0; i < children.size(); i++) if (children[i]) children[i]->wiggle(); @@ -136,8 +139,14 @@ void cpu_linux::measurement_start(void) account_freq(0, 0); } +void cpu_linux::measurement_start(void) +{ + abstract_cpu::measurement_start(); + parse_cstates_start(); + parse_pstates_start(); +} -void cpu_linux::measurement_end(void) +void cpu_linux::parse_cstates_end(void) { DIR *dir; struct dirent *entry; @@ -187,6 +196,12 @@ void cpu_linux::measurement_end(void) } closedir(dir); +} + +void cpu_linux::parse_pstates_end(void) +{ + char filename[256]; + ifstream file; sprintf(filename, "/sys/devices/system/cpu/cpu%i/cpufreq/stats/time_in_state", number); @@ -216,12 +231,15 @@ void cpu_linux::measurement_end(void) } file.close(); } +} - +void cpu_linux::measurement_end(void) +{ + parse_cstates_end(); + parse_pstates_end(); abstract_cpu::measurement_end(); } - char * cpu_linux::fill_cstate_line(int line_nr, char *buffer, const char *separator) { unsigned int i; -- 1.7.11.3 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Powertop Linaro-2012.12 release
Hi, The Powertop Linaro-2012.12 release is available[1] based on upstream v2.2 version. The upstream v2.2 minor release mainly includes bug fixes and new report generator facility. Detailed notes available at [2]. Powertop Linaro-2012.12 release highlights - Bug fix to display freq stats when cpuidle is not enabled - Devfreq support to display devfreq device freq stats [1] http://git.linaro.org/gitweb?p=tools/powertop-2.0.git [2] http://lists.01.org/pipermail/powertop/2012-November/000619.html -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH 3/3] PM / devfreq: account suspend/resume for stats
devfreq stats is not taking device suspend and resume into account. Fix it. Signed-off-by: Rajagopal Venkat --- drivers/devfreq/devfreq.c | 15 --- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 2843a22..4c50235 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -297,6 +297,7 @@ void devfreq_monitor_suspend(struct devfreq *devfreq) return; } + devfreq_update_status(devfreq, devfreq->previous_freq); devfreq->stop_polling = true; mutex_unlock(&devfreq->lock); cancel_delayed_work_sync(&devfreq->work); @@ -313,6 +314,8 @@ EXPORT_SYMBOL(devfreq_monitor_suspend); */ void devfreq_monitor_resume(struct devfreq *devfreq) { + unsigned long freq; + mutex_lock(&devfreq->lock); if (!devfreq->stop_polling) goto out; @@ -321,8 +324,14 @@ void devfreq_monitor_resume(struct devfreq *devfreq) devfreq->profile->polling_ms) queue_delayed_work(devfreq_wq, &devfreq->work, msecs_to_jiffies(devfreq->profile->polling_ms)); + + devfreq->last_stat_updated = jiffies; devfreq->stop_polling = false; + if (devfreq->profile->get_cur_freq && + !devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq)) + devfreq->previous_freq = freq; + out: mutex_unlock(&devfreq->lock); } @@ -931,11 +940,11 @@ static ssize_t show_trans_table(struct device *dev, struct device_attribute *att { struct devfreq *devfreq = to_devfreq(dev); ssize_t len; - int i, j, err; + int i, j; unsigned int max_state = devfreq->profile->max_state; - err = devfreq_update_status(devfreq, devfreq->previous_freq); - if (err) + if (!devfreq->stop_polling && + devfreq_update_status(devfreq, devfreq->previous_freq)) return 0; len = sprintf(buf, " From : To\n"); -- 1.7.10.4 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH 1/3] PM / devfreq: set min/max freq limit from freq table
Set devfreq device min and max frequency limits when device is added to devfreq, provided frequency table is supplied. This helps governors to suggest target frequency with in limits. Signed-off-by: Rajagopal Venkat --- drivers/devfreq/devfreq.c | 24 1 file changed, 24 insertions(+) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index a8f0173..5782c9b 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -69,6 +69,29 @@ static struct devfreq *find_device_devfreq(struct device *dev) } /** + * devfreq_set_freq_limits() - Set min and max frequency from freq_table + * @devfreq: the devfreq instance + */ +static void devfreq_set_freq_limits(struct devfreq *devfreq) +{ + int idx; + unsigned long min = ~0, max = 0; + + if (!devfreq->profile->freq_table) + return; + + for (idx = 0; idx < devfreq->profile->max_state; idx++) { + if (min > devfreq->profile->freq_table[idx]) + min = devfreq->profile->freq_table[idx]; + if (max < devfreq->profile->freq_table[idx]) + max = devfreq->profile->freq_table[idx]; + } + + devfreq->min_freq = min; + devfreq->max_freq = max; +} + +/** * devfreq_get_freq_level() - Lookup freq_table for the frequency * @devfreq: the devfreq instance * @freq: the target frequency @@ -476,6 +499,7 @@ struct devfreq *devfreq_add_device(struct device *dev, devfreq->profile->max_state, GFP_KERNEL); devfreq->last_stat_updated = jiffies; + devfreq_set_freq_limits(devfreq); dev_set_name(&devfreq->dev, dev_name(dev)); err = device_register(&devfreq->dev); -- 1.7.10.4 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH 2/3] PM / devfreq: fix stats start time stamp
Mark the stats start time stamp when actual load monitoring is started for accuracy. Signed-off-by: Rajagopal Venkat --- drivers/devfreq/devfreq.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 5782c9b..2843a22 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -254,9 +254,12 @@ static void devfreq_monitor(struct work_struct *work) void devfreq_monitor_start(struct devfreq *devfreq) { INIT_DEFERRABLE_WORK(&devfreq->work, devfreq_monitor); - if (devfreq->profile->polling_ms) + if (devfreq->profile->polling_ms) { queue_delayed_work(devfreq_wq, &devfreq->work, msecs_to_jiffies(devfreq->profile->polling_ms)); + + devfreq->last_stat_updated = jiffies; + } } EXPORT_SYMBOL(devfreq_monitor_start); @@ -498,7 +501,6 @@ struct devfreq *devfreq_add_device(struct device *dev, devfreq->time_in_state = devm_kzalloc(dev, sizeof(unsigned int) * devfreq->profile->max_state, GFP_KERNEL); - devfreq->last_stat_updated = jiffies; devfreq_set_freq_limits(devfreq); dev_set_name(&devfreq->dev, dev_name(dev)); -- 1.7.10.4 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[RFC PATCH] PM / devfreq: Add runtime-pm support
Instead of devfreq device driver explicitly calling devfreq suspend and resume apis perhaps from runtime-pm suspend and resume callbacks, let devfreq core handle it automatically. Attach devfreq core to runtime-pm framework so that, devfreq device driver pm_runtime_suspend() will automatically suspend the devfreq and pm_runtime_resume() will resume the devfreq. Signed-off-by: Rajagopal Venkat --- drivers/devfreq/devfreq.c | 89 ++--- include/linux/devfreq.h | 12 -- 2 files changed, 76 insertions(+), 25 deletions(-) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 4c50235..781ea47 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -25,10 +25,9 @@ #include #include #include +#include #include "governor.h" -static struct class *devfreq_class; - /* * devfreq core provides delayed work based load monitoring helper * functions. Governors can use these or can implement their own @@ -42,6 +41,9 @@ static LIST_HEAD(devfreq_governor_list); static LIST_HEAD(devfreq_list); static DEFINE_MUTEX(devfreq_list_lock); +static int devfreq_suspend_device(struct devfreq *devfreq); +static int devfreq_resume_device(struct devfreq *devfreq); + /** * find_device_devfreq() - find devfreq struct using device pointer * @dev: device pointer used to lookup device devfreq. @@ -453,6 +455,61 @@ static void devfreq_dev_release(struct device *dev) _remove_devfreq(devfreq, true); } +static int devfreq_runtime_suspend(struct device *dev) +{ + int ret; + struct devfreq *devfreq; + + mutex_lock(&devfreq_list_lock); + devfreq = find_device_devfreq(dev); + mutex_unlock(&devfreq_list_lock); + + ret = devfreq_suspend_device(devfreq); + if (ret < 0) + goto out; + + ret = pm_generic_runtime_suspend(dev); +out: + return ret; +} + +static int devfreq_runtime_resume(struct device *dev) +{ + int ret; + struct devfreq *devfreq; + + mutex_lock(&devfreq_list_lock); + devfreq = find_device_devfreq(dev); + mutex_unlock(&devfreq_list_lock); + + ret = devfreq_resume_device(devfreq); + if (ret < 0) + goto out; + + ret = pm_generic_runtime_resume(dev); +out: + return ret; +} + +static int devfreq_runtime_idle(struct device *dev) +{ + return pm_generic_runtime_idle(dev); +} + +static const struct dev_pm_ops devfreq_pm_ops = { + SET_RUNTIME_PM_OPS( + devfreq_runtime_suspend, + devfreq_runtime_resume, + devfreq_runtime_idle + ) +}; + +static struct class devfreq_class = { + .name = "devfreq", + .owner = THIS_MODULE, + .pm = &devfreq_pm_ops, +}; + /** * devfreq_add_device() - Add devfreq feature to the device * @dev: the device to add devfreq feature. @@ -494,8 +551,9 @@ struct devfreq *devfreq_add_device(struct device *dev, mutex_init(&devfreq->lock); mutex_lock(&devfreq->lock); + dev->class = &devfreq_class; devfreq->dev.parent = dev; - devfreq->dev.class = devfreq_class; + devfreq->dev.class = &devfreq_class; devfreq->dev.release = devfreq_dev_release; devfreq->profile = profile; strncpy(devfreq->governor_name, governor_name, DEVFREQ_NAME_LEN); @@ -538,6 +596,9 @@ struct devfreq *devfreq_add_device(struct device *dev, goto err_init; } + pm_runtime_get_noresume(dev); + pm_runtime_set_active(dev); + return devfreq; err_init: @@ -569,7 +630,7 @@ EXPORT_SYMBOL(devfreq_remove_device); * devfreq_suspend_device() - Suspend devfreq of a device. * @devfreq: the devfreq instance to be suspended */ -int devfreq_suspend_device(struct devfreq *devfreq) +static int devfreq_suspend_device(struct devfreq *devfreq) { if (!devfreq) return -EINVAL; @@ -580,13 +641,12 @@ int devfreq_suspend_device(struct devfreq *devfreq) return devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_SUSPEND, NULL); } -EXPORT_SYMBOL(devfreq_suspend_device); /** * devfreq_resume_device() - Resume devfreq of a device. * @devfreq: the devfreq instance to be resumed */ -int devfreq_resume_device(struct devfreq *devfreq) +static int devfreq_resume_device(struct devfreq *devfreq) { if (!devfreq) return -EINVAL; @@ -597,12 +657,12 @@ int devfreq_resume_device(struct devfreq *devfreq) return devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_RESUME, NULL); } -EXPORT_SYMBOL(devfreq_resume_device); /** * devfreq_add_governor() - Add devfreq governor * @governor: the devfreq governor to be added */ + int devfreq_add_governor(struct devfreq_governor *governor) {
[PATCH] clk: remove unreachable code
while reparenting a clock, NULL check is done for clock in consideration and its new parent. So re-check is not required. If done, else part becomes unreachable. Signed-off-by: Rajagopal Venkat --- drivers/clk/clk.c |5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 251e45d..f896584 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1048,10 +1048,7 @@ void __clk_reparent(struct clk *clk, struct clk *new_parent) hlist_del(&clk->child_node); - if (new_parent) - hlist_add_head(&clk->child_node, &new_parent->children); - else - hlist_add_head(&clk->child_node, &clk_orphan_list); + hlist_add_head(&clk->child_node, &new_parent->children); #ifdef CONFIG_COMMON_CLK_DEBUG if (!inited) -- 1.7.10.4 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [PATCH] clk: remove unreachable code
On 9 January 2013 11:20, Tushar Behera wrote: > On 01/08/2013 06:33 PM, Rajagopal Venkat wrote: >> while reparenting a clock, NULL check is done for clock in >> consideration and its new parent. So re-check is not required. >> If done, else part becomes unreachable. >> >> Signed-off-by: Rajagopal Venkat >> --- >> drivers/clk/clk.c |5 + >> 1 file changed, 1 insertion(+), 4 deletions(-) >> >> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c >> index 251e45d..f896584 100644 >> --- a/drivers/clk/clk.c >> +++ b/drivers/clk/clk.c >> @@ -1048,10 +1048,7 @@ void __clk_reparent(struct clk *clk, struct clk >> *new_parent) >> >> hlist_del(&clk->child_node); >> >> - if (new_parent) >> - hlist_add_head(&clk->child_node, &new_parent->children); >> - else >> - hlist_add_head(&clk->child_node, &clk_orphan_list); >> + hlist_add_head(&clk->child_node, &new_parent->children); >> >> #ifdef CONFIG_COMMON_CLK_DEBUG >> if (!inited) >> > > The same logic holds good for following piece of code too. > > 1060 |---if (new_parent) > 1061 |---|---new_parent_d = new_parent->dentry; > 1062 |---else > 1063 |---|---new_parent_d = orphandir; Yes. Thanks for pointing out. > > > -- > Tushar Behera -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH] clk: remove unreachable code
while reparenting a clock, NULL check is done for clock in consideration and its new parent. So re-check is not required. If done, else part becomes unreachable. Signed-off-by: Rajagopal Venkat --- drivers/clk/clk.c | 13 ++--- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 251e45d..1c4097c 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1040,7 +1040,6 @@ void __clk_reparent(struct clk *clk, struct clk *new_parent) { #ifdef CONFIG_COMMON_CLK_DEBUG struct dentry *d; - struct dentry *new_parent_d; #endif if (!clk || !new_parent) @@ -1048,22 +1047,14 @@ void __clk_reparent(struct clk *clk, struct clk *new_parent) hlist_del(&clk->child_node); - if (new_parent) - hlist_add_head(&clk->child_node, &new_parent->children); - else - hlist_add_head(&clk->child_node, &clk_orphan_list); + hlist_add_head(&clk->child_node, &new_parent->children); #ifdef CONFIG_COMMON_CLK_DEBUG if (!inited) goto out; - if (new_parent) - new_parent_d = new_parent->dentry; - else - new_parent_d = orphandir; - d = debugfs_rename(clk->dentry->d_parent, clk->dentry, - new_parent_d, clk->name); + new_parent->dentry, clk->name); if (d) clk->dentry = d; else -- 1.7.10.4 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [PATCH 1/3] PM / devfreq: set min/max freq limit from freq table
On 14 January 2013 20:06, MyungJoo Ham wrote: > On Tue, Jan 8, 2013 at 2:50 PM, Rajagopal Venkat > wrote: >> Set devfreq device min and max frequency limits when device >> is added to devfreq, provided frequency table is supplied. >> This helps governors to suggest target frequency with in >> limits. >> >> Signed-off-by: Rajagopal Venkat > > Could you please elaborate the benefit of the patch? > When freq table is supplied, it's unreasonable to suggest the target frequency which is - target_freq < min_freq and target_freq > max_freq. It avoids unnecessary checks at devfreq drivers. > The devfreq device drivers are required to choose proper frequencies > anyway regardless which values the governors may give (hopefully by > choosing the closest value that can support the required performance). > Yes. but then each driver needs to have conditional checks for choosing closet value even though freq table is provided. > Besides, the min/max values are to be set by userspace. Users may > enter 0 in order to express that they do not want to limit the > behaviors of governors. > > > Cheers, > MyungJoo. > >> --- >> drivers/devfreq/devfreq.c | 24 >> 1 file changed, 24 insertions(+) >> >> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c >> index a8f0173..5782c9b 100644 >> --- a/drivers/devfreq/devfreq.c >> +++ b/drivers/devfreq/devfreq.c >> @@ -69,6 +69,29 @@ static struct devfreq *find_device_devfreq(struct device >> *dev) >> } >> >> /** >> + * devfreq_set_freq_limits() - Set min and max frequency from freq_table >> + * @devfreq: the devfreq instance >> + */ >> +static void devfreq_set_freq_limits(struct devfreq *devfreq) >> +{ >> + int idx; >> + unsigned long min = ~0, max = 0; >> + >> + if (!devfreq->profile->freq_table) >> + return; >> + >> + for (idx = 0; idx < devfreq->profile->max_state; idx++) { >> + if (min > devfreq->profile->freq_table[idx]) >> + min = devfreq->profile->freq_table[idx]; >> + if (max < devfreq->profile->freq_table[idx]) >> + max = devfreq->profile->freq_table[idx]; >> + } >> + >> + devfreq->min_freq = min; >> + devfreq->max_freq = max; >> +} >> + >> +/** >> * devfreq_get_freq_level() - Lookup freq_table for the frequency >> * @devfreq: the devfreq instance >> * @freq: the target frequency >> @@ -476,6 +499,7 @@ struct devfreq *devfreq_add_device(struct device *dev, >> devfreq->profile->max_state, >> GFP_KERNEL); >> devfreq->last_stat_updated = jiffies; >> + devfreq_set_freq_limits(devfreq); >> >> dev_set_name(&devfreq->dev, dev_name(dev)); >> err = device_register(&devfreq->dev); >> -- >> 1.7.10.4 >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-pm" in >> the body of a message to majord...@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html > > > > -- > MyungJoo Ham, Ph.D. > Mobile Software Platform Lab, DMC Business, Samsung Electronics -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [PATCH 2/3] PM / devfreq: fix stats start time stamp
On 14 January 2013 20:12, MyungJoo Ham wrote: > On Tue, Jan 8, 2013 at 2:50 PM, Rajagopal Venkat > wrote: >> Mark the stats start time stamp when actual load monitoring is >> started for accuracy. >> > > It appears that you are changing the semantics of the information here. > > > For example, in the case: > - devfreq started at 0 w/ 100MHz > - at 10, devfreq monitor starts w/ 100MHz > - at 20, devfreq updates the freq to 200MHz > - at 30, devfreq is requested to show the stat > > The conventional: > 20 @ 100MHz / 10 @ 200MHz > > You proposed: > 10 @ 100MHz / 10 @ 200MHz > > > Could you please give some reasons why the latter is "more accurate"? > To me, the former seems appropriate. Yes. I agree. Please ignore this change. > > > > Cheers, > MyungJoo > > >> Signed-off-by: Rajagopal Venkat >> --- >> drivers/devfreq/devfreq.c |6 -- >> 1 file changed, 4 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c >> index 5782c9b..2843a22 100644 >> --- a/drivers/devfreq/devfreq.c >> +++ b/drivers/devfreq/devfreq.c >> @@ -254,9 +254,12 @@ static void devfreq_monitor(struct work_struct *work) >> void devfreq_monitor_start(struct devfreq *devfreq) >> { >> INIT_DEFERRABLE_WORK(&devfreq->work, devfreq_monitor); >> - if (devfreq->profile->polling_ms) >> + if (devfreq->profile->polling_ms) { >> queue_delayed_work(devfreq_wq, &devfreq->work, >> msecs_to_jiffies(devfreq->profile->polling_ms)); >> + >> + devfreq->last_stat_updated = jiffies; >> + } >> } >> EXPORT_SYMBOL(devfreq_monitor_start); >> >> @@ -498,7 +501,6 @@ struct devfreq *devfreq_add_device(struct device *dev, >> devfreq->time_in_state = devm_kzalloc(dev, sizeof(unsigned int) * >> devfreq->profile->max_state, >> GFP_KERNEL); >> - devfreq->last_stat_updated = jiffies; >> devfreq_set_freq_limits(devfreq); >> >> dev_set_name(&devfreq->dev, dev_name(dev)); >> -- >> 1.7.10.4 >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-pm" in >> the body of a message to majord...@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html > > > > -- > MyungJoo Ham, Ph.D. > Mobile Software Platform Lab, DMC Business, Samsung Electronics -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [PATCH 3/3] PM / devfreq: account suspend/resume for stats
On 14 January 2013 20:18, MyungJoo Ham wrote: > On Tue, Jan 8, 2013 at 2:50 PM, Rajagopal Venkat > wrote: >> devfreq stats is not taking device suspend and resume into >> account. Fix it. >> >> Signed-off-by: Rajagopal Venkat > > With monitor_suspend(), we are suspending the DVFS mechanism of a > device, not the device itself. > > Thus, the device may keep its frequency running and we may assume that > the frequency is constant as the DVFS mechanism is in suspend. > > Why do you want to stop the statistics as well? > There seems to be misunderstanding of devfreq_monitor_suspend() and devfreq_monitor_resume() apis usage. Typically devfreq_monitor_suspend() would be called to suspend the device devfreq when device is entering idle state by powering off(clocks and voltage). When device itself is off, it's incorrect to allow stats to continue. > > > Again, as in the other patch, this is about the semantics of the > "devfreq statistics". > > It does not seem to be a problem of which is correct and which is not, > but it seems to be a problem of which is more convenient. > > Could you please give me some cases where your semantics is more helpful? When gpu is powered off, gpu devfreq should be suspended and hence the stats. > > > > I've been using the stat feature like this: > > # cat stat; run benchmark; cat stat > and look at the differences with any ops done during "run benchmark". > > > > Cheers, > MyungJoo. > >> --- >> drivers/devfreq/devfreq.c | 15 --- >> 1 file changed, 12 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c >> index 2843a22..4c50235 100644 >> --- a/drivers/devfreq/devfreq.c >> +++ b/drivers/devfreq/devfreq.c >> @@ -297,6 +297,7 @@ void devfreq_monitor_suspend(struct devfreq *devfreq) >> return; >> } >> >> + devfreq_update_status(devfreq, devfreq->previous_freq); >> devfreq->stop_polling = true; >> mutex_unlock(&devfreq->lock); >> cancel_delayed_work_sync(&devfreq->work); >> @@ -313,6 +314,8 @@ EXPORT_SYMBOL(devfreq_monitor_suspend); >> */ >> void devfreq_monitor_resume(struct devfreq *devfreq) >> { >> + unsigned long freq; >> + >> mutex_lock(&devfreq->lock); >> if (!devfreq->stop_polling) >> goto out; >> @@ -321,8 +324,14 @@ void devfreq_monitor_resume(struct devfreq *devfreq) >> devfreq->profile->polling_ms) >> queue_delayed_work(devfreq_wq, &devfreq->work, >> msecs_to_jiffies(devfreq->profile->polling_ms)); >> + >> + devfreq->last_stat_updated = jiffies; >> devfreq->stop_polling = false; >> >> + if (devfreq->profile->get_cur_freq && >> + !devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq)) >> + devfreq->previous_freq = freq; >> + >> out: >> mutex_unlock(&devfreq->lock); >> } >> @@ -931,11 +940,11 @@ static ssize_t show_trans_table(struct device *dev, >> struct device_attribute *att >> { >> struct devfreq *devfreq = to_devfreq(dev); >> ssize_t len; >> - int i, j, err; >> + int i, j; >> unsigned int max_state = devfreq->profile->max_state; >> >> - err = devfreq_update_status(devfreq, devfreq->previous_freq); >> - if (err) >> + if (!devfreq->stop_polling && >> + devfreq_update_status(devfreq, >> devfreq->previous_freq)) >> return 0; >> >> len = sprintf(buf, " From : To\n"); >> -- >> 1.7.10.4 >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-pm" in >> the body of a message to majord...@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html > > > > -- > MyungJoo Ham, Ph.D. > Mobile Software Platform Lab, DMC Business, Samsung Electronics -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [PATCH] clk: remove unreachable code
On 16 January 2013 04:15, Mike Turquette wrote: > Quoting Rajagopal Venkat (2013-01-08 22:29:48) >> while reparenting a clock, NULL check is done for clock in >> consideration and its new parent. So re-check is not required. >> If done, else part becomes unreachable. >> >> Signed-off-by: Rajagopal Venkat >> --- >> drivers/clk/clk.c | 13 ++--- >> 1 file changed, 2 insertions(+), 11 deletions(-) >> >> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c >> index 251e45d..1c4097c 100644 >> --- a/drivers/clk/clk.c >> +++ b/drivers/clk/clk.c >> @@ -1040,7 +1040,6 @@ void __clk_reparent(struct clk *clk, struct clk >> *new_parent) >> { >> #ifdef CONFIG_COMMON_CLK_DEBUG >> struct dentry *d; >> - struct dentry *new_parent_d; >> #endif >> >> if (!clk || !new_parent) >> @@ -1048,22 +1047,14 @@ void __clk_reparent(struct clk *clk, struct clk >> *new_parent) >> >> hlist_del(&clk->child_node); >> >> - if (new_parent) >> - hlist_add_head(&clk->child_node, &new_parent->children); >> - else >> - hlist_add_head(&clk->child_node, &clk_orphan_list); >> + hlist_add_head(&clk->child_node, &new_parent->children); > > Rajagopal, > > You found a bug, but not the right one :) > > This change would result in never moving a clock into the orphan list if > the parent is missing. The right thing to do is to allow the operation > to succeed and migrate this clock into the orphan list. In keeping > with the clk.h api we need to treat struct clk new_parent as an opaque > cookie and not care whether or not it is NULL. > Mike, The only path where __clk_reparent() can get new parent as NULL is from clk_set_parent() api. Tracing this path, here are the reasons why I submitted this patch. 1. The clk_set_parent() function takes new parent for granted and tries to access new_parent->rate when notifiers are registered, 2. For clocks with multiple parents, the __clk_set_parent() function also takes new parent for granted and tries to access parent name while finding the index of new parent from cached parent pointers. But if the design decision is to allow clock to be re-parented to orphan list when new parent is missing, I can provide the new working patch. > Untested patch below fixes the real bug: > > > > From a4d56e3ee51452366365749873710e16631e9de7 Mon Sep 17 00:00:00 2001 > From: Mike Turquette > Date: Tue, 15 Jan 2013 14:39:06 -0800 > Subject: [PATCH] clk: allow re-parenting to NULL clks > > __clk_reparent presently bails early if the new parent of a clk is NULL. > This is wrong and prevents dynamically migrating clocks into the orphan > list. The fix is to remove the NULL pointer check for new_parent in > __clk_parent. > > Signed-off-by: Mike Turquette > --- > drivers/clk/clk.c |2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c > index 593a2e4..f056230 100644 > --- a/drivers/clk/clk.c > +++ b/drivers/clk/clk.c > @@ -1186,7 +1186,7 @@ void __clk_reparent(struct clk *clk, struct clk > *new_parent) > struct dentry *new_parent_d; > #endif > > - if (!clk || !new_parent) > + if (!clk) > return; > > hlist_del(&clk->child_node); > -- > 1.7.10.4 > -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
[PATCH] clk: allow reparenting of a clock to the orphan list
Allow reparenting of a clock(multiple and single parent) to the orphan list when new parent clock is NULL. Signed-off-by: Rajagopal Venkat --- drivers/clk/clk.c | 18 -- 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index e964994..5c9277a 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1102,7 +1102,7 @@ void __clk_reparent(struct clk *clk, struct clk *new_parent) struct dentry *new_parent_d; #endif - if (!clk || !new_parent) + if (!clk) return; hlist_del(&clk->child_node); @@ -1140,11 +1140,14 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent) { struct clk *old_parent; unsigned long flags; - int ret = -EINVAL; - u8 i; + int ret = 0; + u8 i = 0; old_parent = clk->parent; + if (clk->num_parents == 1 || !parent) + goto migrate; + if (!clk->parents) clk->parents = kzalloc((sizeof(struct clk*) * clk->num_parents), GFP_KERNEL); @@ -1165,11 +1168,13 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent) } if (i == clk->num_parents) { + ret = -EINVAL; pr_debug("%s: clock %s is not a possible parent of clock %s\n", __func__, parent->name, clk->name); goto out; } +migrate: /* migrate prepare and enable */ if (clk->prepare_count) __clk_prepare(parent); @@ -1181,7 +1186,8 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent) spin_unlock_irqrestore(&enable_lock, flags); /* change clock input source */ - ret = clk->ops->set_parent(clk->hw, i); + if (clk->ops->set_parent) + ret = clk->ops->set_parent(clk->hw, i); /* clean up old prepare and enable */ spin_lock_irqsave(&enable_lock, flags); @@ -1215,7 +1221,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent) if (!clk || !clk->ops) return -EINVAL; - if (!clk->ops->set_parent) + if (clk->num_parents > 1 && !clk->ops->set_parent) return -ENOSYS; /* prevent racing with updates to the clock topology */ @@ -1226,7 +1232,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent) /* propagate PRE_RATE_CHANGE notifications */ if (clk->notifier_count) - ret = __clk_speculate_rates(clk, parent->rate); + ret = __clk_speculate_rates(clk, parent ? parent->rate : 0); /* abort if a driver objects */ if (ret == NOTIFY_STOP) -- 1.7.10.4 ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [PATCH 1/3] PM / devfreq: set min/max freq limit from freq table
MyungJoo, Ping. On 15 January 2013 16:51, Rajagopal Venkat wrote: > On 14 January 2013 20:06, MyungJoo Ham wrote: >> On Tue, Jan 8, 2013 at 2:50 PM, Rajagopal Venkat >> wrote: >>> Set devfreq device min and max frequency limits when device >>> is added to devfreq, provided frequency table is supplied. >>> This helps governors to suggest target frequency with in >>> limits. >>> >>> Signed-off-by: Rajagopal Venkat >> >> Could you please elaborate the benefit of the patch? >> > > When freq table is supplied, it's unreasonable to suggest the target frequency > which is - target_freq < min_freq and target_freq > max_freq. It avoids > unnecessary checks at devfreq drivers. > >> The devfreq device drivers are required to choose proper frequencies >> anyway regardless which values the governors may give (hopefully by >> choosing the closest value that can support the required performance). >> > > Yes. but then each driver needs to have conditional checks for choosing > closet value even though freq table is provided. > >> Besides, the min/max values are to be set by userspace. Users may >> enter 0 in order to express that they do not want to limit the >> behaviors of governors. >> >> >> Cheers, >> MyungJoo. >> >>> --- >>> drivers/devfreq/devfreq.c | 24 >>> 1 file changed, 24 insertions(+) >>> >>> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c >>> index a8f0173..5782c9b 100644 >>> --- a/drivers/devfreq/devfreq.c >>> +++ b/drivers/devfreq/devfreq.c >>> @@ -69,6 +69,29 @@ static struct devfreq *find_device_devfreq(struct device >>> *dev) >>> } >>> >>> /** >>> + * devfreq_set_freq_limits() - Set min and max frequency from freq_table >>> + * @devfreq: the devfreq instance >>> + */ >>> +static void devfreq_set_freq_limits(struct devfreq *devfreq) >>> +{ >>> + int idx; >>> + unsigned long min = ~0, max = 0; >>> + >>> + if (!devfreq->profile->freq_table) >>> + return; >>> + >>> + for (idx = 0; idx < devfreq->profile->max_state; idx++) { >>> + if (min > devfreq->profile->freq_table[idx]) >>> + min = devfreq->profile->freq_table[idx]; >>> + if (max < devfreq->profile->freq_table[idx]) >>> + max = devfreq->profile->freq_table[idx]; >>> + } >>> + >>> + devfreq->min_freq = min; >>> + devfreq->max_freq = max; >>> +} >>> + >>> +/** >>> * devfreq_get_freq_level() - Lookup freq_table for the frequency >>> * @devfreq: the devfreq instance >>> * @freq: the target frequency >>> @@ -476,6 +499,7 @@ struct devfreq *devfreq_add_device(struct device *dev, >>> devfreq->profile->max_state, >>> GFP_KERNEL); >>> devfreq->last_stat_updated = jiffies; >>> + devfreq_set_freq_limits(devfreq); >>> >>> dev_set_name(&devfreq->dev, dev_name(dev)); >>> err = device_register(&devfreq->dev); >>> -- >>> 1.7.10.4 >>> >>> -- >>> To unsubscribe from this list: send the line "unsubscribe linux-pm" in >>> the body of a message to majord...@vger.kernel.org >>> More majordomo info at http://vger.kernel.org/majordomo-info.html >> >> >> >> -- >> MyungJoo Ham, Ph.D. >> Mobile Software Platform Lab, DMC Business, Samsung Electronics > > > > -- > Regards, > Rajagopal -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [PATCH 3/3] PM / devfreq: account suspend/resume for stats
MyungJoo, Ping. On 15 January 2013 17:16, Rajagopal Venkat wrote: > On 14 January 2013 20:18, MyungJoo Ham wrote: >> On Tue, Jan 8, 2013 at 2:50 PM, Rajagopal Venkat >> wrote: >>> devfreq stats is not taking device suspend and resume into >>> account. Fix it. >>> >>> Signed-off-by: Rajagopal Venkat >> >> With monitor_suspend(), we are suspending the DVFS mechanism of a >> device, not the device itself. >> >> Thus, the device may keep its frequency running and we may assume that >> the frequency is constant as the DVFS mechanism is in suspend. >> >> Why do you want to stop the statistics as well? >> > > There seems to be misunderstanding of devfreq_monitor_suspend() and > devfreq_monitor_resume() apis usage. > > Typically devfreq_monitor_suspend() would be called to suspend the device > devfreq when device is entering idle state by powering off(clocks and > voltage). > When device itself is off, it's incorrect to allow stats to continue. > >> >> >> Again, as in the other patch, this is about the semantics of the >> "devfreq statistics". >> >> It does not seem to be a problem of which is correct and which is not, >> but it seems to be a problem of which is more convenient. >> >> Could you please give me some cases where your semantics is more helpful? > > When gpu is powered off, gpu devfreq should be suspended and hence the stats. > >> >> >> >> I've been using the stat feature like this: >> >> # cat stat; run benchmark; cat stat >> and look at the differences with any ops done during "run benchmark". >> >> >> >> Cheers, >> MyungJoo. >> >>> --- >>> drivers/devfreq/devfreq.c | 15 --- >>> 1 file changed, 12 insertions(+), 3 deletions(-) >>> >>> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c >>> index 2843a22..4c50235 100644 >>> --- a/drivers/devfreq/devfreq.c >>> +++ b/drivers/devfreq/devfreq.c >>> @@ -297,6 +297,7 @@ void devfreq_monitor_suspend(struct devfreq *devfreq) >>> return; >>> } >>> >>> + devfreq_update_status(devfreq, devfreq->previous_freq); >>> devfreq->stop_polling = true; >>> mutex_unlock(&devfreq->lock); >>> cancel_delayed_work_sync(&devfreq->work); >>> @@ -313,6 +314,8 @@ EXPORT_SYMBOL(devfreq_monitor_suspend); >>> */ >>> void devfreq_monitor_resume(struct devfreq *devfreq) >>> { >>> + unsigned long freq; >>> + >>> mutex_lock(&devfreq->lock); >>> if (!devfreq->stop_polling) >>> goto out; >>> @@ -321,8 +324,14 @@ void devfreq_monitor_resume(struct devfreq *devfreq) >>> devfreq->profile->polling_ms) >>> queue_delayed_work(devfreq_wq, &devfreq->work, >>> msecs_to_jiffies(devfreq->profile->polling_ms)); >>> + >>> + devfreq->last_stat_updated = jiffies; >>> devfreq->stop_polling = false; >>> >>> + if (devfreq->profile->get_cur_freq && >>> + !devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq)) >>> + devfreq->previous_freq = freq; >>> + >>> out: >>> mutex_unlock(&devfreq->lock); >>> } >>> @@ -931,11 +940,11 @@ static ssize_t show_trans_table(struct device *dev, >>> struct device_attribute *att >>> { >>> struct devfreq *devfreq = to_devfreq(dev); >>> ssize_t len; >>> - int i, j, err; >>> + int i, j; >>> unsigned int max_state = devfreq->profile->max_state; >>> >>> - err = devfreq_update_status(devfreq, devfreq->previous_freq); >>> - if (err) >>> + if (!devfreq->stop_polling && >>> + devfreq_update_status(devfreq, >>> devfreq->previous_freq)) >>> return 0; >>> >>> len = sprintf(buf, " From : To\n"); >>> -- >>> 1.7.10.4 >>> >>> -- >>> To unsubscribe from this list: send the line "unsubscribe linux-pm" in >>> the body of a message to majord...@vger.kernel.org >>> More majordomo info at http://vger.kernel.org/majordomo-info.html >> >> >> >> -- >> MyungJoo Ham, Ph.D. >> Mobile Software Platform Lab, DMC Business, Samsung Electronics > > > > -- > Regards, > Rajagopal -- Regards, Rajagopal ___ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
Re: [PATCH 1/3] PM / devfreq: set min/max freq limit from freq table
On 5 February 2013 12:21, MyungJoo Ham wrote: > On Tue, Jan 15, 2013 at 8:21 PM, Rajagopal Venkat > wrote: >> On 14 January 2013 20:06, MyungJoo Ham wrote: >>> On Tue, Jan 8, 2013 at 2:50 PM, Rajagopal Venkat >>> wrote: >>>> Set devfreq device min and max frequency limits when device >>>> is added to devfreq, provided frequency table is supplied. >>>> This helps governors to suggest target frequency with in >>>> limits. >>>> >>>> Signed-off-by: Rajagopal Venkat >>> >>> Could you please elaborate the benefit of the patch? >>> >> >> When freq table is supplied, it's unreasonable to suggest the target >> frequency >> which is - target_freq < min_freq and target_freq > max_freq. It avoids >> unnecessary checks at devfreq drivers. > > Is it a safety barrier against userspace processes or devfreq governors? > Users are allowed to enter min_freq and max_freq via sysfs interfaces anyway. > Also, as mentioned earlier, users are allowed to enter 0 in order to > "disengage" the min/max_freq. It doesn't interfere with userspace updates to min_freq/max_freq. The min/max limits from freq table are assigned only during the device devfreq init, which can be overwritten by userspace. > If we need "hardware-specific" min/max value, we'd need another sysfs > interfaces and values (i.e., scaling_min/max_freq vs > cpuinfo_min/max_freq). In my opinion, min_freq and max_freq itself represents the devfreq device freq limits. Additional sysfs interfaces may not be required. > > Besides, if you are able to provide "freq_table", it means that you > are able to provide OPP for the device. > Then, you can use OPP APIs to avoid unnecessary checks at devfreq > driver (even you can use the devfreq helper functions) That's my intention as well. If driver is able to provide freq_table, based on the load, let devfreq core suggest only the supported opps (not just the limits, but for all intermediate opps). In which case, devfreq core must mandate drivers to add OPP table(instead of passing freq array) before registering with devfreq. > >> >>> The devfreq device drivers are required to choose proper frequencies >>> anyway regardless which values the governors may give (hopefully by >>> choosing the closest value that can support the required performance). >>> >> >> Yes. but then each driver needs to have conditional checks for choosing >> closet value even though freq table is provided. > > Even with this min/max-freq, when governors suggests some values > between min/max, each driver needs to have checks unless it uses OPP. With above proposal, devfreq should suggest only supported opps. > >> >>> Besides, the min/max values are to be set by userspace. Users may >>> enter 0 in order to express that they do not want to limit the >>> behaviors of governors. > > Because of this, this patch will create discrepency from/to userspace > interfaces. As said above, there is no conflict of interest between userspace and this patch. In summary, I propose making OPP table mandatory for all devfreq drivers, to enable devfreq core to suggest only supported opps. Any thoughts? > > > > > Cheers, > MyungJoo. > >>> >>> >>> Cheers, >>> MyungJoo. >>> >>>> --- >>>> drivers/devfreq/devfreq.c | 24 >>>> 1 file changed, 24 insertions(+) >>>> >>>> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c >>>> index a8f0173..5782c9b 100644 >>>> --- a/drivers/devfreq/devfreq.c >>>> +++ b/drivers/devfreq/devfreq.c >>>> @@ -69,6 +69,29 @@ static struct devfreq *find_device_devfreq(struct >>>> device *dev) >>>> } >>>> >>>> /** >>>> + * devfreq_set_freq_limits() - Set min and max frequency from freq_table >>>> + * @devfreq: the devfreq instance >>>> + */ >>>> +static void devfreq_set_freq_limits(struct devfreq *devfreq) >>>> +{ >>>> + int idx; >>>> + unsigned long min = ~0, max = 0; >>>> + >>>> + if (!devfreq->profile->freq_table) >>>> + return; >>>> + >>>> + for (idx = 0; idx < devfreq->profile->max_state; idx++) { >>>> + if (min > devfreq->profile->freq_table[idx]) >>>> + min = devfreq->profile->freq_table[idx]; >>>> + i
Re: [PATCH powertop] thermal: add window for thermal related infromation
On 12 March 2013 17:15, Sanjay Singh Rawat wrote: > add a window to display the stats of thermal, cooling zones and also > information given by the hwmon sensor. Nice window displaying thermal/hwmon sysfs information. Good enough to start with. Any plans to process sysfs information and display more useful stats like done in cpufreq and cpuidle stats? for instance how long a cooling device was active and temperature drop as a result. > > Signed-off-by: Sanjay Singh Rawat > --- > src/Makefile.am |2 +- > src/display.cpp |1 + > src/main.cpp|3 +- > src/measurement/thermal.cpp | 148 > +++ > src/measurement/thermal.h |1 + > 5 files changed, 153 insertions(+), 2 deletions(-) > create mode 100644 src/measurement/thermal.cpp > create mode 100644 src/measurement/thermal.h > > diff --git a/src/Makefile.am b/src/Makefile.am > index f60426a..335fb6c 100644 > --- a/src/Makefile.am > +++ b/src/Makefile.am > @@ -34,7 +34,7 @@ powertop_SOURCES = parameters/persistent.cpp > parameters/learn.cpp parameters/par > report/report-formatter-base.cpp > report/report-formatter-base.h \ > report/report-formatter-csv.cpp report/report-formatter-csv.h > \ > report/report-formatter-html.cpp > report/report-formatter-html.h \ > - main.cpp css.h powertop.css cpu/intel_gpu.cpp > + main.cpp css.h powertop.css cpu/intel_gpu.cpp > measurement/thermal.h measurement/thermal.cpp > > > powertop_CXXFLAGS = -fno-omit-frame-pointer -fstack-protector -Wall -Wshadow > -Wformat $(NCURSES_CFLAGS) $(PCIUTILS_CFLAGS) $(LIBNL_CFLAGS) $(GLIB2_CFLAGS) > diff --git a/src/display.cpp b/src/display.cpp > index c76ba27..adcf80d 100644 > --- a/src/display.cpp > +++ b/src/display.cpp > @@ -71,6 +71,7 @@ void init_display(void) > create_tab("Idle stats", _("Idle stats")); > create_tab("Frequency stats", _("Frequency stats")); > create_tab("Device stats", _("Device stats")); > + create_tab("Thermal stats", _("Thermal stats")); > > display = 1; > } > diff --git a/src/main.cpp b/src/main.cpp > index e6036ae..e649919 100644 > --- a/src/main.cpp > +++ b/src/main.cpp > @@ -51,7 +51,7 @@ > #include "parameters/parameters.h" > #include "calibrate/calibrate.h" > > - > +#include "measurement/thermal.h" > #include "tuning/tuning.h" > > #include "display.h" > @@ -214,6 +214,7 @@ void one_measurement(int seconds, char *workload) > report_display_cpu_pstates(); > report_process_update_display(); > > + thermal_update_display(); > tuning_update_display(); > > end_process_data(); > diff --git a/src/measurement/thermal.cpp b/src/measurement/thermal.cpp > new file mode 100644 > index 000..c2c4c11 > --- /dev/null > +++ b/src/measurement/thermal.cpp > @@ -0,0 +1,148 @@ > +/* > + * This is part of PowerTOP > + * > + * This program file is free software; you can redistribute it and/or modify > it > + * under the terms of the GNU General Public License as published by the > + * Free Software Foundation; version 2 of the License. > + * > + * This program is distributed in the hope that it will be useful, but > WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > + * for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program in a file named COPYING; if not, write to the > + * Free Software Foundation, Inc, > + * 51 Franklin Street, Fifth Floor, > + * Boston, MA 02110-1301 USA > + * or just google for it. > + * > + * getopt code is taken from "The GNU C Library" reference manual, > + * section 24.2 "Parsing program options using getopt" > + * http://www.gnu.org/s/libc/manual/html_node/Getopt-Long-Option-Example.html > + * Manual published under the terms of the Free Documentation License. > + */ > + > +#include > +#include > +#include "../display.h" > +#include "../lib.h" Patch fails to compile for me. Need to include unistd.h for R_OK? > + > +enum attr_length { > + SHORTT, > + LONGT > +}; > + > +static int get_thermal_attr(WINDOW *win, char *zone, const char *attr, int > wide) > +{ > +char buf[512]; > +int val; > +string line; > + > + if(!wide) What happens when more enumerations are added? > + wprintw(win,"%17s : ",attr); > + else > + wprintw(win,"%s : ",attr); > +for(val=0 ; val<255 ; val++) { Instead of using magic number here, why not dynamically detect available thermal zones and cooling devices? > +sprintf(buf,"%s%d/%s",zone,val,attr); > + if (access(buf, R_OK) !=0) { Please follow powertop existing code for coding standards. > + wprintw(win," *\n"); > +