Saturday, 28 July 2012

Test Nexus S kernel release 3.0.38-25 (ICS & JB) – IDLE2 v0.212

Quick post, bugfix update:

  • Fixed issue in IDLE2 causing ANR in systemui and subsequent soft reboot when turning screen on after being in call or playing music.
  • Fixed issue where some users with a specific AMOLED panel would get a yellow / green tint.

3.0.38-25 kernel releases for ICS, JB, JB-i9023 & JellyBelly available from here.

Thursday, 26 July 2012

Test Nexus S kernel release 3.0.38-23 (ICS & JB) – IDLE2 v0.210

So, another test release.

Short changelog this time, the main improvement is IDLE2 v0.210 which implements the DEEP-IDLE TOP ON state for use when bluetooth or GPS is active. This should hopefully bring some power savings in those situations, but your mileage may vary.

I also implemented a load of micro-optimisations of variables and functions in the idle2 code to hopefully speed up the hot paths even more and make them cheaper.

Changelog:

  • Interactive governor boost enabled and set as default
  • IDLE2 v0.210
  • Version provided for i9023 users which contains the patch from codeworkx which should fix the CRT off animation

Download:

Update: Please use –24 instead, –23 has been removed due to a bug which is fixed in –24 which is available here.

I will write a blog post shortly detailing the bug and changes in –24.

Wednesday, 25 July 2012

Test Nexus S kernel release 3.0.38-22 (ICS & JB)

So, another test release for both ICS and JB.

This one includes my new implementation of IDLE2, which seems to work much better and save significantly more power than the last one.

Changelog:

  • Adjusted ondemand tunables to make ramping up occur faster for better responsiveness.
  • Implemented bigmem hack which should work on all ROMs and give an additional ~50MB of RAM
  • Disabled the expensive KSM due to the above.
  • New implementation of IDLE2, enabled by default. Please see my previous post on IDLE2 for details.

Available here for ICS and here for JB.

And for anyone feeling adventurous, there is one here for JB with the interactive governor set as default with interaction boost mode enabled.

Source here as always.

IDLE2 v0.201

So, I have spent a lot of time recently thinking about how best to implement IDLE2.

I decided to do something which hadn’t been done before, and implement both IDLE states so they are available concurrently without having to ‘switch’ between them, as was being done previously.

I implemented 2 idle states, IDLE (which was already implemented) and IDLE2, which is better described as DEEP IDLE TOP OFF, referred to as IDLE2 mode from hereon in.

I spent a lot of time making the hot paths as cheap as possible, wherever possible using variables for storage and checking them instead of polling (expensive) functions. This has paid off with a doubling of the number of times the CPU enters IDLE2 mode.

I also implemented PM notifiers to disable IDLE2 mode when suspend is active instead of hooking into the suspend sequence. However, due to the implementation, IDLE2 mode should never be enabled when the device is suspending, so it is just a failsafe.

Bluetooth caused me a massive headache, and although I have managed to partially solve the issue, I’m not entirely happy with the fix. Due to the way bluetooth works in ICS/JB, it is permanently enabled. This causes an issue, as IDLE2 mode is incompatible with bluetooth, enabling IDLE2 mode whilst the bluetooth is actively working breaks the link. The fix for this is a bit of a fudge. I added a hook to herring-rfkill to call a function when the GPIO_BT_HOST_WAKE goes high. This sets the external_active variable to true in cpuidle.c, which tells cpuidle to ignore the IDLE2 mode. When the gpio goes low again, a function is called which sets external_active to false, but it queues it for 60 seconds time. If another interrupt occurs, the queued inactive work will be cancelled and so on. This should work for the majority of bluetooth use cases. If the devices don’t ping each other every minute, I would be surprised. But, if this doesn’t work for you, IDLE2 mode can be disabled with a switch.

I implemented a hook into the audio subsystem so IDLE2 mode will not be activated unless audio playback has been active for 30 seconds. This choice was made to stop spurious activations of IDLE2 mode when there are system notifications, for example.

IDLE2 mode will now be activated under the following circumstances:

  • The disabled switch is not set
  • Audio playback has been active for 30 seconds
  • USB cable is disconnected
  • Bluetooth is inactive (see above)
  • Earlysuspend is active (screen is turned off)
  • Various clocks are gated and various subsystems are power gated
  • No interrupts pending

Added code to disable cpufreq and clamp the CPU at 800MHz when the conditions are right for IDLE2 mode to be entered. This appears to save significantly more power.

Codewise, many of the IDLE2 specific functions have been moved into idle2.h, to keep them separate from the standard cpufreq code. The asm has also been further cleaned up, with calls to the generic flush_cache_all() and cpu_do_idle() functions instead of using asm calls. The remaining asm is involved in saving and restoring registers for IDLE2 mode. Exit latency has been set to 400, which is what is stated in the S5PC100 TRM. Residency time has been reduced to 2000, as even going into IDLE2 for short periods is more efficient than using regular idle or not idling at all.

IDLE2 mode now has a disable switch, which can be activated with the following command:

echo 1 > /sys/module/cpuidle/parameters/idle2_disabled

As the IDLE2 state is now implemented concurrently with IDLE, info can be obtained from the standard cpuidle interfaces.

For normal IDLE these can be found here:

/sys/devices/system/cpu/cpu0/cpuidle/state0

And IDLE2 can be found here:

/sys/devices/system/cpu/cpu0/cpuidle/state1

 

I think that is all the improvements.

Patches v0.200 and v0.201 are available on my github which will need to be applied on top of all the rest of the IDLE2 patches.

My kernel, implementing IDLE2 v0.201, is available here.

I will squash them and release a standalone patch at some point in the near future.

Update: Standalone patch is available here.

Sunday, 22 July 2012

Test Nexus S kernel release 3.0.38-21 (ICS and JB)

Another test release, both for Android 4.0 (ICS) and Android 4.1 (JB) this time.

Status of ICS support is that it will be supported for another month, although I don’t expect many people to be using it because JB is far superior.

Changelog:

  • Disabled IDLE2 until I decide exactly how the invocation code will be implemented and get the implementation completed and bugfree.
  • Fixed a ton of complier warnings which had been irritating me for a while (21 commits in total).
  • Merged to mainline 3.0.38 and merged in android-common-3.0.

ICS version here.

JB version here.

Source: ICS JB.

Thursday, 19 July 2012

Test Nexus S kernel release 3.0.37-18 & IDLE2 v0.130

New test release today, following on from yesterdays IDLE2 release.

This release contains a bugfix for bluetooth audio streaming, which was broken when IDLE2 was entered.

The fix simply checks to see if the GPIO_BT_HOST_WAKE is high and if it is, it puts the SoC into TOP ON DEEP-IDLE mode instead of TOP OFF DEEP-IDLE mode.

Simply enabling bluetooth will not make you go into TOP ON mode. The bluetooth has to be active and doing something, such as streaming or otherwise communicating with another device.

The only other small change in IDLE2 v0.130 is the argument to s5p_set_idle2_lock() was changed from an int to a bool.

New kernel available here, IDLE2 patches available on my github.

Wednesday, 18 July 2012

Test Nexus S kernel release 3.0.37-17

So, a test release today, with something new, my idle2 port from Samsungs P1000 kernel. Read about that here.

There is no point in repeating what I have already written there. If you have any questions about the implementation, please comment in that post, but no stupid questions please, they will be deleted.

As 3.0.36-14 stable with the following changes:

  • idle2, which is a replacement for deep-idle.
  • Merged to 3.0.37 from mainline – nothing scary there.
  • Merged android-common-3.0 – just a wifi module bugfix.

Available here.

IDLE2 for s5pv210 SoC v0.122

As some of you will know, I have been working on a port of Samsungs IDLE2 / LPAUDIO feature from their 2.6.32 P1000 kernel to the 3.0.x i902x kernel.

This implements the same thing as deep idle attempts to do, but it has several benefits over the original deep-idle patch, as will be explained below.

I’m pleased to say that I am going to release the source and a kernel with it included today.

This release comes after a large amount of debugging of lockups caused by interactions with the coresight tracing driver and general other breakage, including some asm issues. I did get to a point where I couldn’t get it stable at all, I wasn’t getting any useful output from last_kmsg and I was almost about to give up, but thanks to a decent last_kmsg trace or 2 and gdb <3 I was able to find the problem, fix the issue and get it stable. :) Myself and several others have been running it for about 2 days now, so altogether we have probably amassed about 500 hours of testing, with no issues reported so far.

Differences / Advantages compared to deep-idle:

  • Enabled by default and automatically invoked whenever the conditions are right.
  • When the screen is on, the idle mode is set to NORMAL, which skips all the idle2 code and works as normal, so no change there.
  • When the screen is turned off (earlysuspend), the mode is switched to IDLE2 which is used when all the following conditions are met:
  1. PowerManagerService is holding a wakelock
  2. USB is not plugged in
  3. GPU is not running
  4. MMC & NAND aren’t in use
  5. DMA is clock gated
  6. Audio DMA is not in use
  7. No RTC interrupts pending
  8. It also checks the Vector Interrupt Controller status immediately before saving register state / calling WFI and bails if an interrupt is active
  • Cleaner code paths, optimised for the most likely scenario to save some cycles on branching. Many critical functions inlined to make their execution quicker and cheaper. Many int type functions modified to use the cheapest type possible, normally bool or void.
  • No expensive stat collecting sysfs interface chewing up cpu cycles. I know people will moan that this stops you seeing what it is doing, but, does it really matter if it is working? Just accept that it *is* working. If you really want to check what it is doing, recompile the kernel with the debugging messages enabled and it will spam dmesg with everything that idle2 is doing. :)
  • ASM modified to use existing generic platform cache flush and idle routines rather than duplicate them. Certainly more could be done here, and that is something for a future version, but I’ve made a good start at it.
  • It doesn’t require the CPU to be forced to an artificial frequency for stability. The CPU scales as normal and ranges 100 <> 1000 whilst idle2 is active.
  • DEEP-IDLE TOP OFF mode is default. TOP-ON is not used.
  • There is no requirement for the config_bluetooth_adapter_quick_switch disabling patch as it works perfectly without it.
  • Due to it being hooked into a wakelock, it cannot be invoked at the same time as suspend is called, so it has no way of racing with the suspend code.
  • It seems to be completely stable (so far anyway).

I think that is about it for the advantages, but as you can see, it is a worthwhile improvement.

To do:

  • More code cleanups.
  • Try to make some code paths cheaper.
  • Try to use generic platform asm or unify with platform asm.

Patches and improvement suggestions are welcome. This is one of the most complex things I have released, so there will be improvements to be made and suggestions and patches are more than welcome, specially for any of the todo items.

Wilful kanging, not clearly giving proper credits and not contributing back is extremely unwelcome. Open source is not about copying other peoples work, a principle which some developers don’t get, The GPL was never designed for the purpose of copying code verbatim and riding on other peoples work, it was designed to allow freedom of code, a continual cycle of improvement and peer review, so consider that please.