With the new mechanism that is used to describe a scenario, it becomes more
complex to estimate how many logs will be generated during the execution of a
use case. As a result, the record of the logs in temporary buffer had been
disable and the logs were saved directly in files. The potential side effect
of such mecanism is to block threads on io access, which disturbs the use case
behavior.
A new parameter is added to define the saving policy of the logs. You can
now disable the logs, save them directly in a file like previously,
define the size of a temporary buffer but with the risk to lost some logs if
the buffer overflow. You can also ask rt-app to evaluate how many logs will be
generated and allocate the temporary buffer accordingly. This last mode is not
yet implemented and it will be part of a dedicated patch.
Full details of the new parameter is available in the update of the
documentation
Signed-off-by: Vincent Guittot <vincent.guittot(a)linaro.org>
---
doc/tutorial.txt | 15 ++++++++++++++
src/rt-app.c | 34 +++++++++++++++++++++++--------
src/rt-app_parse_config.c | 51 ++++++++++++++++++++++++++++++++++++++---------
src/rt-app_types.h | 1 +
4 files changed, 84 insertions(+), 17 deletions(-)
diff --git a/doc/tutorial.txt b/doc/tutorial.txt
index 12aba47..8341b2e 100644
--- a/doc/tutorial.txt
+++ b/doc/tutorial.txt
@@ -61,6 +61,20 @@ the current directory (./).
* log_basename : Text. Prefix used for all log files of the use case.
"rt-app-" is used by default.
+* log_size : String or Integer. A Integer defines a fix size in MB of the
+temporary buffer (size per thread) that will be used to store the log data
+before saving them in a file. This temporary buffer is used as a cicular
+buffer so the oldest data will be lost in case of overflow. A string is used
+to set a predifined behavior:
+ - "file" will be used to store the log data directly in the file without
+ using a temporary buffer.
+ - "Disable" will disable the log mecahnism.
+ - "Auto" will let rt-app compute the buffer size to not overflow the latter
+ during the use case.
+The use of a temporary buffer prevents the threads of unexpected wait during
+io access. The "Auto" mode is not implemented yet and fallback to "file" mode
+for the moment.
+
* ftrace: Boolean. If enable, rt-app logs in ftrace the main events of the use
case. Default value is False.
@@ -75,6 +89,7 @@ each threads (see gnuplot section for more details). Default value is False.
"pi_enabled" : false,
"lock_pages" : false,
"logdir" : "./",
+ "log_size" : "file",
"log_basename" : "rt-app",
"ftrace" : false,
"gnuplot" : false,
diff --git a/src/rt-app.c b/src/rt-app.c
index 6a27308..805cc35 100644
--- a/src/rt-app.c
+++ b/src/rt-app.c
@@ -391,10 +391,11 @@ void *thread_body(void *arg)
timing_point_t *curr_timing;
timing_point_t *timings;
timing_point_t tmp_timing;
+ unsigned int timings_size, timing_loop;
pid_t tid;
struct sched_attr attr;
unsigned int flags = 0;
- int ret, i, j, loop;
+ int ret, i, j, loop, idx;
/* Set thread name */
ret = pthread_setname_np(pthread_self(), data->name);
@@ -488,6 +489,15 @@ void *thread_body(void *arg)
exit(EXIT_FAILURE);
}
+ if (opts.logsize > 0) {
+ timings = malloc(opts.logsize);
+ timings_size = opts.logsize / sizeof(timing_point_t);
+ } else {
+ timings = NULL;
+ timings_size = 0;
+ }
+ timing_loop = 0;
+
/* Lock pages */
if (data->lock_pages == 1)
{
@@ -502,8 +512,6 @@ void *thread_body(void *arg)
log_notice("[%d] starting thread ...\n", data->ind);
- timings = NULL;
-
fprintf(data->log_handler, "#idx\tperf\trun\tperiod\tstart\t\tend\t\trel_st\n");
if (opts.ftrace)
@@ -526,7 +534,7 @@ void *thread_body(void *arg)
}
}
#endif
- i = j = loop = 0;
+ i = j = loop = idx = 0;
while (continue_running && (i != data->loop)) {
struct timespec t_diff, t_rel_start;
@@ -541,7 +549,7 @@ void *thread_body(void *arg)
clock_gettime(CLOCK_MONOTONIC, &t_end);
if (timings)
- curr_timing = &timings[loop];
+ curr_timing = &timings[idx];
else
curr_timing = &tmp_timing;
@@ -556,7 +564,7 @@ void *thread_body(void *arg)
curr_timing->duration = duration;
curr_timing->perf = perf;
- if (!timings)
+ if (opts.logsize && !timings)
log_timing(data->log_handler, curr_timing);
if (opts.ftrace)
@@ -575,6 +583,12 @@ void *thread_body(void *arg)
pdata = &data->phases[j];
}
+
+ idx++;
+ if (idx >= timings_size) {
+ timing_loop = 1;
+ idx = 0;
+ }
}
param.sched_priority = 0;
@@ -587,9 +601,13 @@ void *thread_body(void *arg)
exit(EXIT_FAILURE);
}
- if (timings)
- for (j=0; j < loop; j++)
+ if (timings) {
+ for (j = idx; timing_loop && (j < timings_size); j++)
+ log_timing(data->log_handler, &timings[j]);
+ for (j = 0; j < idx; j++)
log_timing(data->log_handler, &timings[j]);
+ }
+
if (opts.ftrace)
log_ftrace(ft_data.marker_fd, "[%d] exiting", data->ind);
diff --git a/src/rt-app_parse_config.c b/src/rt-app_parse_config.c
index def3070..98374cd 100644
--- a/src/rt-app_parse_config.c
+++ b/src/rt-app_parse_config.c
@@ -744,8 +744,8 @@ parse_tasks(struct json_object *tasks, rtapp_options_t *opts)
static void
parse_global(struct json_object *global, rtapp_options_t *opts)
{
- char *policy, *cal_str;
- struct json_object *cal_obj;
+ char *policy, *tmp_str;
+ struct json_object *tmp_obj;
int scan_cnt;
log_info(PFX "Parsing global section");
@@ -760,6 +760,7 @@ parse_global(struct json_object *global, rtapp_options_t *opts)
opts->logdir = strdup("./");
opts->lock_pages = 1;
opts->logbasename = strdup("rt-app");
+ opts->logsize = 0;
opts->ftrace = 0;
opts->pi_enabled = 0;
opts->io_device = strdup("/dev/null");
@@ -781,27 +782,27 @@ parse_global(struct json_object *global, rtapp_options_t *opts)
*/
free(policy);
- cal_obj = get_in_object(global, "calibration", TRUE);
- if (cal_obj == NULL) {
+ tmp_obj = get_in_object(global, "calibration", TRUE);
+ if (tmp_obj == NULL) {
/* no setting ? Calibrate CPU0 */
opts->calib_cpu = 0;
opts->calib_ns_per_loop = 0;
log_error("missing calibration setting force CPU0");
} else {
- if (json_object_is_type(cal_obj, json_type_int)) {
+ if (json_object_is_type(tmp_obj, json_type_int)) {
/* integer (no " ") detected. */
- opts->calib_ns_per_loop = json_object_get_int(cal_obj);
+ opts->calib_ns_per_loop = json_object_get_int(tmp_obj);
log_debug("ns_per_loop %d", opts->calib_ns_per_loop);
} else {
/* Get CPU number */
- cal_str = get_string_value_from(global, "calibration",
+ tmp_str = get_string_value_from(global, "calibration",
TRUE, "CPU0");
- scan_cnt = sscanf(cal_str, "CPU%d", &opts->calib_cpu);
+ scan_cnt = sscanf(tmp_str, "CPU%d", &opts->calib_cpu);
/*
* get_string_value_from allocate the string so with have to free it
* once useless
*/
- free(cal_str);
+ free(tmp_str);
if (!scan_cnt) {
log_critical(PFX "Invalid calibration CPU%d", opts->calib_cpu);
exit(EXIT_INV_CONFIG);
@@ -810,6 +811,38 @@ parse_global(struct json_object *global, rtapp_options_t *opts)
}
}
+ tmp_obj = get_in_object(global, "log_size", TRUE);
+ if (tmp_obj == NULL) {
+ /* no size ? use file system */
+ opts->logsize = -2;
+ } else {
+ if (json_object_is_type(tmp_obj, json_type_int)) {
+ /* integer (no " ") detected. */
+ /* buffer size is set in MB */
+ opts->logsize = json_object_get_int(tmp_obj) << 20;
+ log_notice("Log buffer size fixed to %dMB per threads", (opts->logsize >> 20));
+ } else {
+ /* Get CPU number */
+ tmp_str = get_string_value_from(global, "log_size",
+ TRUE, "disable");
+
+ if (strcmp(tmp_str, "disable"))
+ opts->logsize = 0;
+ else if (strcmp(tmp_str, "file"))
+ opts->logsize = -2;
+ else if (strcmp(tmp_str, "auto"))
+ opts->logsize = -2; /* Automatic buffer size computation is not supported yet so we fall back on file system mode */
+
+ log_debug("Log buffer set to %s mode", tmp_str);
+
+ /*
+ * get_string_value_from allocate the string so with have to free it
+ * once useless
+ */
+ free(tmp_str);
+ }
+ }
+
opts->logdir = get_string_value_from(global, "logdir", TRUE, "./");
opts->lock_pages = get_bool_value_from(global, "lock_pages", TRUE, 1);
opts->logbasename = get_string_value_from(global, "log_basename",
diff --git a/src/rt-app_types.h b/src/rt-app_types.h
index aab96a7..2ce9c9d 100644
--- a/src/rt-app_types.h
+++ b/src/rt-app_types.h
@@ -170,6 +170,7 @@ typedef struct _rtapp_options_t {
char *logdir;
char *logbasename;
+ int logsize;
int gnuplot;
int calib_cpu;
int calib_ns_per_loop;
--
1.9.1
If the next wake up date of the timer is already in the past when we execute
the event, we resets the timer.t_next to the current time.
Otherwise, if the delay has been too large, we might never recover it and the
timer will always be in the past.
Signed-off-by: Vincent Guittot <vincent.guittot(a)linaro.org>
---
src/rt-app.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/rt-app.c b/src/rt-app.c
index 37e9892..20383a2 100644
--- a/src/rt-app.c
+++ b/src/rt-app.c
@@ -253,6 +253,8 @@ static int run_event(event_data_t *event, int dry_run,
clock_gettime(CLOCK_MONOTONIC, &t_now);
if (timespec_lower(&t_now, &rdata->res.timer.t_next))
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &rdata->res.timer.t_next, NULL);
+ else
+ clock_gettime(CLOCK_MONOTONIC, &rdata->res.timer.t_next);
}
break;
case rtapp_suspend:
--
1.9.1
Hi Linaro Sched team,
I am trying to cross compile rt-app to arm android. I've followed the
steps mentioned in the Readme file. But I am facing some issues while
configuring it to arm.
attached are the config log.
Command issued
export CC=arm-linux-gnueabi-gcc
./configure --host=arm
Also i am using following http://packages.ubuntu.com/trusty/libjson-c-dev
--
Thanks & Regards,
M.Srikanth Kumar.
From: Xunlei Pang <pang.xunlei(a)linaro.org>
DVFS adds a latency in the execution of task because of the time to
decide to move at max freq. We need to measure this latency and check
that the governor stays in an acceptable range.
When rt-app runs a json file, a log file is created for each thread.
This log file records the number of loop that has been executed and
the duration for executing these loops (per phase). We can use these
figures to evaluate to latency that is added by a cpufreq governor
and its "performance efficiency".
We use the run+sleep pattern to do the measurement, for the run time per
loop, the performance governor should run the expected duration as the
CPU stays a max freq. At the opposite, the powersave governor will give
use the longest duration (as it stays at lowest OPP). Other governor will
be somewhere between the 2 previous duration as they will use several OPP
and will go back to max frequency after a defined duration which depends
on its monitoring period.
The formula:
duration of powersave gov - duration of the gov
-------------------------------------------------------- x 100%
duration of powersave gov - duration of performance gov
will give the efficiency of the governor. 100% means as efficient as
the perf governor and 0% means as efficient as the powersave governor.
This patch offers json files and shell scripts to do the measurement.
Usage:
./calibration.sh <cpu>
cpu: cpu number on which you want to run the test
./test.sh <governor> <cpu> <runtime> <sleeptime> [<loops>]
governor: target CPUFreq governor you want to test
cpu: cpu number on which you want to run the test. Be the same
as the one passed to "calibration.sh".
runtime: running time in ms per loop of the workload pattern
sleeptime: sleeping time in ms per loop of the workload pattern
loops: repeat times of the workload pattern. default: 10
Example:
"./calibration.sh 0" means to calculate the computing capacity of CPU0 which
will be used in the following test.
"./test.sh ondemand 0 100 100 20" means to
test "ondemand" on CPU0 with workload pattern "run 100ms + sleep 100ms"(20 loops).
NOTE:
- Make sure there are "sed", "cut", "grep", "rt-app", etc tools on
your test machine, and run the scripts under root privilege.
- Run the test while the system is idle.
- You can change the target governor's parameters after running "calibration.sh",
but before "test.sh".
Signed-off-by: Xunlei Pang <pang.xunlei(a)linaro.org>
---
doc/examples/cpufreq_governor_efficiency/README | 60 ++++++++++++
.../cpufreq_governor_efficiency/calibration.json | 26 ++++++
.../cpufreq_governor_efficiency/calibration.sh | 17 ++++
doc/examples/cpufreq_governor_efficiency/dvfs.json | 27 ++++++
doc/examples/cpufreq_governor_efficiency/dvfs.sh | 38 ++++++++
doc/examples/cpufreq_governor_efficiency/test.sh | 104 +++++++++++++++++++++
6 files changed, 272 insertions(+)
create mode 100755 doc/examples/cpufreq_governor_efficiency/README
create mode 100755 doc/examples/cpufreq_governor_efficiency/calibration.json
create mode 100755 doc/examples/cpufreq_governor_efficiency/calibration.sh
create mode 100755 doc/examples/cpufreq_governor_efficiency/dvfs.json
create mode 100755 doc/examples/cpufreq_governor_efficiency/dvfs.sh
create mode 100755 doc/examples/cpufreq_governor_efficiency/test.sh
diff --git a/doc/examples/cpufreq_governor_efficiency/README b/doc/examples/cpufreq_governor_efficiency/README
new file mode 100755
index 0000000..10482b8
--- /dev/null
+++ b/doc/examples/cpufreq_governor_efficiency/README
@@ -0,0 +1,60 @@
+Measure the efficiency of cpufreq governors using rt-app
+
+BACKGROUND:
+ DVFS adds a latency in the execution of task because of the time to
+ decide to move at max freq. We need to measure this latency and check
+ that the governor stays in an acceptable range.
+
+ When rt-app runs a json file, a log file is created for each thread.
+ This log file records the number of loop that has been executed and
+ the duration for executing these loops (per phase). We can use these
+ figures to evaluate to latency that is added by a cpufreq governor
+ and its "performance efficiency".
+
+ We use the run+sleep pattern to do the measurement, for the run time per
+ loop, the performance governor should run the expected duration as the
+ CPU stays a max freq. At the opposite, the powersave governor will give
+ use the longest duration (as it stays at lowest OPP). Other governor will
+ be somewhere between the 2 previous duration as they will use several OPP
+ and will go back to max frequency after a defined duration which depends
+ on its monitoring period.
+
+ The formula:
+
+ duration of powersave gov - duration of the gov
+ -------------------------------------------------------- x 100%
+ duration of powersave gov - duration of performance gov
+
+ will give the efficiency of the governor. 100% means as efficient as
+ the perf governor and 0% means as efficient as the powersave governor.
+
+ This test offers json files and shell scripts to do the measurement.
+
+Usage:
+ ./calibration.sh <cpu>
+ cpu: cpu number on which you want to run the test
+
+ ./test.sh <governor> <cpu> <runtime> <sleeptime> [<loops>]
+ governor: target CPUFreq governor you want to test
+ cpu: cpu number on which you want to run the test. Be the same
+ as the one passing to "calibration.sh".
+ runtime: running time in ms per loop of the workload pattern
+ sleeptime: sleeping time in ms per loop of the workload pattern
+ loops: repeat times of the workload pattern. default: 10
+
+Example:
+ "./calibration.sh 0" means to calculate the computing capacity of CPU0 which
+ will be used in the following test.
+
+ "./test.sh ondemand 0 100 100 20" means to
+ test "ondemand" on CPU0 with workload pattern "run 100ms + sleep 100ms"(20 loops).
+
+NOTE:
+ - Make sure there are "sed", "cut", "grep", "rt-app", etc tools on
+ your test machine, and run the scripts under root privilege.
+
+ - Run the test while the system is idle.
+
+ - You can change the target governor's parameters after running "calibration.sh",
+ but before "test.sh".
+
diff --git a/doc/examples/cpufreq_governor_efficiency/calibration.json b/doc/examples/cpufreq_governor_efficiency/calibration.json
new file mode 100755
index 0000000..2d5870c
--- /dev/null
+++ b/doc/examples/cpufreq_governor_efficiency/calibration.json
@@ -0,0 +1,26 @@
+{
+ "tasks" : {
+ "thread" : {
+ "instance" : 1,
+ "loop" : 1,
+ "phases" : {
+ "run" : {
+ "loop" : 1,
+ "run" : 2000,
+ },
+ "sleep" : {
+ "loop" : 1,
+ "sleep" : 2000,
+ }
+ }
+ }
+ },
+ "global" : {
+ "default_policy" : "SCHED_FIFO",
+ "calibration" : "CPU0",
+ "lock_pages" : true,
+ "ftrace" : false,
+ "logdir" : "./",
+ }
+}
+
diff --git a/doc/examples/cpufreq_governor_efficiency/calibration.sh b/doc/examples/cpufreq_governor_efficiency/calibration.sh
new file mode 100755
index 0000000..a217487
--- /dev/null
+++ b/doc/examples/cpufreq_governor_efficiency/calibration.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+set -e
+
+if [ ! $1 ] ; then
+ echo "Please input one cpu"
+ exit
+fi
+
+echo performance > /sys/devices/system/cpu/cpu$1/cpufreq/scaling_governor
+
+sleep 1
+
+sed 's/"calibration" : "CPU.*",/"calibration" : "CPU'$1'",/' -i calibration.json
+pLoad=$(rt-app calibration.json 2>&1 |grep pLoad |sed 's/.*= \(.*\)ns.*/\1/')
+sed 's/"calibration" : .*,/"calibration" : '$pLoad',/' -i dvfs.json
+echo CPU$1\'s pLoad is $pLoad
diff --git a/doc/examples/cpufreq_governor_efficiency/dvfs.json b/doc/examples/cpufreq_governor_efficiency/dvfs.json
new file mode 100755
index 0000000..c8447df
--- /dev/null
+++ b/doc/examples/cpufreq_governor_efficiency/dvfs.json
@@ -0,0 +1,27 @@
+{
+ "tasks" : {
+ "thread" : {
+ "instance" : 1,
+ "cpus" : [0],
+"loop" : 21,
+ "phases" : {
+ "running" : {
+ "loop" : 1,
+ "run" : 100,
+ },
+ "sleeping" : {
+ "loop" : 1,
+ "sleep" : 100,
+ }
+ }
+ }
+ },
+ "global" : {
+ "default_policy" : "SCHED_OTHER",
+ "calibration" : 90,
+ "lock_pages" : true,
+ "ftrace" : false,
+ "logdir" : "./",
+ }
+}
+
diff --git a/doc/examples/cpufreq_governor_efficiency/dvfs.sh b/doc/examples/cpufreq_governor_efficiency/dvfs.sh
new file mode 100755
index 0000000..00ce81d
--- /dev/null
+++ b/doc/examples/cpufreq_governor_efficiency/dvfs.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+# $1 $2 $3 $4 $5: governor cpu run sleep loops
+set -e
+
+echo $1 > /sys/devices/system/cpu/cpu$2/cpufreq/scaling_governor
+#echo $1 > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor
+sed 's/"cpus" : \[.*\],/"cpus" : \['$2'\],/' -i dvfs.json
+sleep 3
+
+if [ $3 ] ; then
+ sed 's/"run" : .*,/"run" : '$3',/' -i dvfs.json
+fi
+
+if [ $4 ] ; then
+ sed 's/"sleep" : .*,/"sleep" : '$4',/' -i dvfs.json
+fi
+
+if [ $5 ] ; then
+ sed 's/^"loop" : .*,/"loop" : '$5',/' -i dvfs.json
+fi
+
+rt-app dvfs.json 2> /dev/null
+
+if [ $1 ] ; then
+ mv -f rt-app-thread-0.log rt-app_$1_run$3us_sleep$4us.log
+
+ sum=0
+ loop=0
+ for i in $(cat rt-app_$1_run$3us_sleep$4us.log | sed 'n;d' | sed '1d' |cut -f 3); do
+ loop=$(expr $loop + 1)
+ sum=$(expr $sum + $i)
+ done
+ sum=$(expr $sum / $loop)
+ echo $sum
+ rm -f rt-app_$1_run$3us_sleep$4us.log
+fi
+
diff --git a/doc/examples/cpufreq_governor_efficiency/test.sh b/doc/examples/cpufreq_governor_efficiency/test.sh
new file mode 100755
index 0000000..0160952
--- /dev/null
+++ b/doc/examples/cpufreq_governor_efficiency/test.sh
@@ -0,0 +1,104 @@
+#!/bin/sh
+
+set -e
+
+test_efficiency() {
+
+ FILENAME="results_$RANDOM$$.txt"
+
+ if [ -e /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors ]; then
+ for i in $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors); do
+ if [ $i = $1 ] ; then
+ gov_target=$i
+ fi
+ export gov_$i=$(echo $i)
+ done
+ else
+ echo "cpufreq sysfs is not available!"
+ exit
+ fi
+
+ if [ ! $gov_target ] ; then
+ echo " Can't find $1 governor!"
+ exit
+ fi
+
+ if [ ! $gov_performance ] ; then
+ echo "Can't find performance governor!"
+ exit
+ fi
+
+ if [ ! $gov_powersave ] ; then
+ echo "Can't find powersave governor!"
+ exit
+ fi
+
+ if [ $gov_target = $gov_performance ] || [ $gov_target = $gov_powersave ] ; then
+ echo "Please input a governor other than \"performance\" or \"powersave\""
+ exit
+ fi
+
+ # Get target gov data first
+ dvfs.sh $1 $2 $3 $4 $5 > $FILENAME
+ target=$(cat $FILENAME |sed -n '1p')
+
+ # Get powersave data
+ dvfs.sh powersave $2 $3 $4 $5 > $FILENAME
+ powersave=$(cat $FILENAME |sed -n '1p')
+
+ # Get performance data
+ dvfs.sh performance $2 $3 $4 $5 > $FILENAME
+ performance=$(cat $FILENAME |sed -n '1p')
+
+ if [ $performance -ge $powersave ] ; then
+ echo "powersave: $powersave"
+ echo "performance: $performance"
+ echo "Error! performance spent more time than powersave!"
+ exit
+ fi
+
+ echo "\"powersave\" efficiency: 0%"
+ echo "\"performance\" efficiency: 100%"
+
+ denominator=$(expr $powersave - $performance)
+
+ if [ $powersave -le $target ]; then
+ target=0
+ else
+ numerator=$(expr $powersave - $target)
+ numerator=$(expr $numerator \* 100)
+ target=$(expr $numerator / $denominator)
+ if [ $target -gt 100 ]; then
+ target=100
+ fi
+ fi
+
+ echo "\"$gov_target\" efficiency: $target%"
+
+ rm -f $FILENAME
+}
+
+if [ $# -lt 4 ]; then
+ echo "Usage: ./test.sh <governor> <cpu> <runtime> <sleeptime> [<loops>]"
+ echo "governor: target CPUFreq governor you want to test"
+ echo "cpu: cpu number on which you want to run the test"
+ echo "runtime: running time in ms per loop of the workload pattern"
+ echo "sleeptime: sleeping time in ms per loop of the workload pattern"
+ echo "loops: repeat times of the workload pattern. default: 10"
+ echo "\nExample:\n\"./test.sh ondemand 0 100 100 20\" means\nTest \"ondemand\" on CPU0 with workload pattern \"run 100ms + sleep 100ms\"(20 loops).\n"
+ exit
+fi
+
+if [ $# = 4 ]; then
+ loops=10
+else
+ loops=$5
+fi
+
+echo "Test \"$1\" on CPU$2 with workload pattern \"run $3ms + sleep $4ms\"($loops loops)."
+
+sleep 1
+PATH=$PATH:.
+
+test_efficiency $1 $2 $(expr $3 \* 1000) $(expr $4 \* 1000) $loops
+
--
1.9.1
This series adds several new features to rt-app, e.g. signal, wait,
broadcast, run, sleep ...etc. and updates the example taskset.json file to
reflect those new features.
These patches are also found:
ssh://git@git.linaro.org/people/picheng.chen/rt-app.git features_series1
Sanjay Singh Rawat (1):
add delay param in thread parameters
Vincent Guittot (10):
Add new wait, signal, and broadcast resources
update the .json test file to reflect new capabilities
add loop feature
rt-app: make load frequency independent.
update example file with new loop capabilities
add sleep and run type of resources
update taskset.json example with run and sleep capabilities
make possible to remove the sleep step
modify stat to reflect new behavior
update example file with more capabilities
doc/taskset.json | 104 ++++++++++++----------
src/rt-app.c | 155 +++++++++++++++++++++++++++------
src/rt-app_parse_config.c | 214 +++++++++++++++++++++++++++++++++++++---------
src/rt-app_types.h | 35 +++++++-
src/rt-app_utils.c | 64 ++++++++++++++
src/rt-app_utils.h | 9 ++
6 files changed, 467 insertions(+), 114 deletions(-)
--
1.9.1
Now if don't set the option -S for buffer size, idlestat will init ftrace
buffer with below formula:
percpu_buffer_size =
((2 * TRACE_IDLE_LENGTH * TRACE_IDLE_NRHITS_PER_SEC) +
(TRACE_CPUFREQ_LENGTH * TRACE_CPUFREQ_NRHITS_PER_SEC)) * duration;
According to current macros' definition, if want to run the test case
for 40s, then idlestat will need the trace buffer for one CPU is:
(2*196*10000 + 196*100) Bytes/second x 40 seconds = 157584000 Bytes; So
need allocate 150MB for one CPU, if system have 8 CPUs, then totally need
allocate 150MB * 8 = 1.2GB; finally it reports the failure in kernel
if the system cannot allocate so much buffer size:
[ 42.562531] idlestat: page allocation failure: order:0, mode:0x10d0
[ 42.568817] CPU: 2 PID: 819 Comm: idlestat Not tainted 4.2.0-rc4+ #106
[ 42.575372] Hardware name: HiKey Development Board (DT)
[ 42.580610] Call trace:
[ 42.583067] [<ffffffc00008a624>] dump_backtrace+0x0/0x164
[ 42.588465] [<ffffffc00008a7a4>] show_stack+0x1c/0x28
[ 42.593535] [<ffffffc0006d3b4c>] dump_stack+0x80/0xc4
[ 42.598589] [<ffffffc00018a064>] warn_alloc_failed+0xe4/0x13c
[ 42.604355] [<ffffffc00018dac0>] __alloc_pages_nodemask+0x6a8/0x814
[ 42.610636] [<ffffffc000152774>] __rb_allocate_pages.isra.55+0x60/0x164
[ 42.617251] [<ffffffc000154718>] ring_buffer_resize+0x250/0x428
[ 42.623192] [<ffffffc000158808>] __tracing_resize_ring_buffer+0x54/0x17c
[ 42.629905] [<ffffffc0001589d8>] tracing_entries_write+0xa8/0x158
[ 42.636000] [<ffffffc0001f2fec>] __vfs_write+0x44/0x130
[ 42.641240] [<ffffffc0001f3a50>] vfs_write+0x98/0x1a0
[ 42.646291] [<ffffffc0001f4630>] SyS_write+0x50/0xb0
After review the macro definition, TRACE_IDLE_NRHITS_PER_SEC is 10000;
usually the CPU will enter/exit idle states much less than 1000 times per
second, so reduce it to 1000 which will be enough for profiling.
Signed-off-by: Leo Yan <leo.yan(a)linaro.org>
---
trace.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/trace.h b/trace.h
index a2f5867..863c248 100644
--- a/trace.h
+++ b/trace.h
@@ -34,7 +34,7 @@
#define TRACE_FREE TRACE_PATH "/free_buffer"
#define TRACE_FILE TRACE_PATH "/trace"
#define TRACE_STAT_FILE TRACE_PATH "/per_cpu/cpu0/stats"
-#define TRACE_IDLE_NRHITS_PER_SEC 10000
+#define TRACE_IDLE_NRHITS_PER_SEC 1000
#define TRACE_IDLE_LENGTH 196
#define TRACE_CPUFREQ_NRHITS_PER_SEC 100
#define TRACE_CPUFREQ_LENGTH 196
--
1.9.1
Replacing the list address with one specific for scheduler tools.
On Tue, Jul 14, 2015 at 12:27 PM, Leo Yan <leo.yan(a)linaro.org> wrote:
> Hi all,
>
> I saw the energy model related patches have been posted [1], so i'd
> like to ask some questions for the tool rt-app:
>
> - I downloaded rt-app from the address [2];
>
> - For the case "rt-app [4]: mp3 playback use-case model", is it the
> same one with doc/examples/mp3-long.json?
>
> - For the case "rt-app [4]: 5 ~[6,13,19,25,31,38,44,50]% periodic
> (2ms) tasks for 30s", i have not seen there have .json scripts for
> these cases; so could you help point where i can get related
> scripts?
>
> - i read the case doc/examples/tutorial/example3.json, its comments
> say "starts with a 10% load during 1sec (100 loops) and then
> increase 90% for the next sec (100 loops)".
>
> it's confused me due i cannot calculate the same workload with
> the comment clarified. For the phase "light", it only specifies the
> flow as run 1ms + timer 30ms, so the workload only have 1/30 =
> 3.33%; for the phase "heavy", it will get workload = 4/30 = 13.33%;
>
> Could you help confirm if i wrongly understand this case?
>
> {
> /*
> * Simple use case which starts with a 10% load during 1sec (100 loops)
> * and then increase to 90% for the next sec (100 loops)
> */
> "tasks" : {
> "thread0" : {
> "instance" : 12,
> "loop" : 1,
> "phases" : {
> "light" : {
> "loop" : 10,
> "run" : 1000,
> "timer" : { "ref" : "unique", "period" : 30000 }
> },
> "heavy" : {
> "loop" : 10,
> "run" : 4000,
> "timer" : { "ref" : "unique", "period" : 30000 }
> }
> }
> }
> },
> "global" : {
> "logdir" : "./",
> "log_basename" : "rt-app3",
> "ftrace" : true,
> "gnuplot" : true
> }
> }
>
> [1] http://thread.gmane.org/gmane.linux.power-management.general/62093
> [2] https://github.com/scheduler-tools/rt-app.git exp/eas_v5
>
> Thanks,
> Leo Yan