arm: Add auto hotplug driver This driver is simple and cheap and aims…

… to avoid unnecessary hotplug events and unnecessary task migrations. The design is simple. The value of nr_running() (which is the current number of runnable threads) is averaged over X samples by a ringbuffer. If the value is over a dynamically calculated value, all CPUs are onlined. When the value falls under another dynamically calculated value, the CPUs are offlined with a 2 second delay.

If there is persistent load on the system, the CPUs will not continually
thrash between onlining and offlining and continually migrate tasks.
The number of online CPUs will remain constant until the load has dropped
below the dynamically calculated value.

The online and offline values are dynamically scaled based on the number of
CPUs online, as is the sampling rate of the driver. This aims to reduce the
expense of the driver and also reduce the number of unless hotplug transitions
which could have been avoided had cpufreq been given the chance to ramp the
online CPUs up and deal with the load.

This driver will also offline secondary cores when the screen is turned off,
providing earlysuspend is available.
It also has a module param to set the minimum number of online CPUs:
/sys/module/auto_hotplug/parameters/min_online_cpus
This value is ignored when the device enters earlysuspend, as the secondary
CPUs are all offlined, but is set again when the screen is turned back on.

Signed-off-by: Seongmin Park <r_data@naver.com>
arm: auto_hotplug:
UPDATES:
Step1:
 v0.200 Add hotplug_boostpulse() function which is called from cpufreq and onlines an additional CPU instantly providing <50% of CPUs are online. This improves interactivity substantially.

Change schedule_work() functions to schedule_work_on() to ensure they are
always queued on the 1st CPU.

Fix the utter ugliness inside hotplug_offline_work_fn(), we now use
for_each_online_cpu() and break out after the first cpu_down() is called.

Fix a few variable names.

STEP2:
v0.201 Increase sampling periods to 25 with a minimum sampling rate of 20ms. This will give a best case average for any 500ms period, which works well with boostpulse, and it makes the overhead of the driver cheaper.

Don't attempt to online CPUs with boostpulse when early_suspend() has
been called.

Add some TODOs and comments to the code.

STEP3:
v0.210

*Use dedicated workqueue for better control and ability to easily flush.
*Implement HOTPLUG_PAUSED flag which allows sampling to continue but stops
any hotplug events from occurring unless the load spikes drastically high.
*Implement HOTPLUG_DISABLED flag which can be called externally as nvidia
likes to do at shutdown for T3.
*Add boostpulse sysfs interface (kanged from cpufreq.c) at:
/sys/devices/system/cpu/auto_hotplug/boostpulse
*Rewrite boostpulse to work in oneshot mode always. Fixed mode isn't
required any longer.
*Use 10 sampling periods of min 20ms each. Too many sampling periods was
causing spurious onlines because too much history was being averaged.
*Add ability to online only 1 CPU instead of all CPUs if load dictates.
*Change some of the delayed work items into normal work.
*Fix averaging error caused by avg_running not being reinitialised at each
invocation of hotplug_decision_work_fn()
*Rewrite the decision code to implement paused and disabled flags and use
else if instead of if if if.
*Tidy up the onlining and offlining work functions.
*Fix the bug causing all secondary cores to be offlined when hotplugging
was started. We now start sampling with the paused flag set which allows
the array to fill so the average will be representative of the current
system load. We clear the pause flag after 10 seconds to allow hotplugging.

STEP4:
v0.211 tentatively working

STEP5:
v0.220 * Now that it actually works properly, the locking is not required * Fixup decision logic and use consistent variables throughout * Use cancel_delayed_work() when necessary instead of blindly using cancel_delayed_work_sync() * Increase ENABLE_LOAD_THRESHOLD slightly to 225 to avoid most spurious cpu_up() calls

STEP6:
wrap all pr_info into the existing debug mode so we don't spam the kernel log