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).
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)