Ubuntu: bl-agitator fails to switch sometimes in random switching mode
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
big.LITTLE Reference Switcher |
New
|
Medium
|
Omar Ramirez Luna |
Bug Description
hwpack: http://
When bl-agitator is run in random switching mode, sometimes it fails to switch:
root@linaro-
***bl-agitator***
CPU count: 4
CPU0: big freq 1000000 LITTLE freq 100000
CPU1: big freq 1000000 LITTLE freq 100000
CPU2: big freq 1000000 LITTLE freq 100000
CPU3: big freq 1000000 LITTLE freq 100000
Random switcher seed 0 limit 1000
Random switcher seed 0 limit 1000
Random switcher seed 0 limit 1000
Random switcher seed 0 limit 1000
cpu3 scaling_setspeed target 100000 current 1000000... FAIL
error on iteration 27 period 929
cpu0 scaling_setspeed target 100000 current 1000000... FAIL
error on iteration 75 period 907
^CTime elapsed: 0:03:10.1000
Terminated because of SIG 2
root@linaro-
Changed in linaro-big-little-reference: | |
assignee: | nobody → Dave Martin (dave-martin-arm) |
Changed in linaro-big-little-reference: | |
importance: | Undecided → Medium |
I think this is not a bug.
Because the reference switcher does not switch the CPUs independently, the threads will interfere with each other when running the agitator in threaded mode on the reference switcher:
Thread 1: switch to big on CPU0
* all CPUs move to big
Thread 2: switch to little on CPU1
* all CPUs move to little
Thread 1: check that CPU0 is big -> fail
The attached patch adds some locking, to help understand whether this analysis is correct: if so, the modified agitator should not display the failures.
This is not a good fix, though -- we *do* want to switch asynchronously from different threads, because this is a good test of the switcher.
One option is to use a counter to detect concurrent switches so we don't flag up errors unnecessarily. Note that we should only do this for the reference switcher (really we should pay attention to the affected_cpus mask in sysfs).
bl_set_frequency() {
static volatile unsigned switch_count = 0;
unsigned expected_count;
...
expected_count = __sync_ add_and_ fetch(& count, 1); write_file( "scaling_ setspeed" , ...); read_file( "cpuinfo_ cur_freq" , ...);
sysfs_
sysfs_
curr_freq = ...;
/* Treat frequency mismatch as an error, but only if another thread has not done another switch already: */
__sync_ synchronize( );
err = curr_freq != target_freq && switch_count != expected_count;
...
}
(This is totally untested)