torstai 2. syyskuuta 2010

Unresponsive N900? Create another swap partition.

Was wondering about my N900 often being very slow and unresponsive (and trying to make up some easy explanation to my wife how can it it take 2-3 minutes to silent the alarm of my new state-of-the-art mobile computer-phone-thingy when it happens to ring half an hour too early). Noticed that is because of IO waits caused by swapping. Sure I got dozens of apps but hey isn't that what this device has been built for. Wondering how to improve it so bumped at this thread going straight into the point.

There were already step-by-step instructions for creating those partitions but as I happened to be MUCH more comfortable with fdisk than sfdisk and there was fdisk installed with the Easy Debian package, did the tricks with that. Also, other parts of that process were scattered all around this thread and the internet so decided to do some wrap-up.

So, here's how to:

- Back-up whatever needed from the card, it WILL be empty after this procedure.
- Close anything that might use the uSD card
- Run Debian chroot (install Easy Debian if you don't have it already)

- On the console:
---
umount /media/mmc1
fdisk /dev/mmcblk1
p #print partition list, check it's the correct device, see how many cylinders you got and how many bytes per cylinder.

d #delete partition
<enter> #partition number, default=1

n #new partition
p #primary
<enter> #start cylinder, default=1
1900 #end cylinder, my 16GB card has 1949 cyls and 49 happened to be pretty close to 384MB which should be fine so 1900 can be used for the data partition

n #new partition
p #primary
<enter> #start cylinder, default=first non-allocated
<enter> #end cylinder, end of device = allocate the rest for swap

t #change partition type
1 #partition number
b #vfat

t #change partition type
1 #partition number
82 #Linux swap

p #print table, check everything is OK

w #write table

<open back cover> #Re-seat the card to make kernel forget the old parameters
<remove card>
<insert card>
<re-insert back cover>

mkswap /dev/mmcblk1p1 #prepare the swap partition
swapon /dev/mmcblk1p1 #enable the swap partition
free #check that you now have more swap
mkfs.vfat -F 32 /dev/mmcblk1p1 #format main partition
mount /media/mmc1
---

Now test copying something into your uSD card to see it works properly.

The swap partition won't be automatically taken in use after reboot, create a startup script like this one into /etc/event.d to make it automatically. (More information about start scripts).

/etc/event.d/swap_sd
start on started hildon-desktop
stop on starting shutdown
console none
service

script

sleep 60
swapon /dev/mmcblk1p2

end script


Did this only today so don't have much experience yet but so far feels more like a new device than a mere performance improvement! Trying to abuse it to make IO waits hit the roof but no, can't get them over 30% so haven't managed to make it unresponsive. I'd guess it'll be worse after a couple of days uptime but looks promising anyway.

My card is a Nokia 16GB class 2 card so shouldn't be that fast but measured with "hdparm -tT /dev/mmcblkxx" ("apt-get install hdparm" with Debian chroot to get it) to be actually a bit faster than a no-name class 6 8GB card. Hdparm gives about 15MB/s non-cached read speeds for this 16GB card and about 20 MB/s for the internal /dev/mmcblk0p3 swap so the card is clearly slower but still helps a lot.

--
Update: Seems that the new swap partition will have a lower priority than the original one so won't be used before the first one is exhausted = no performance boost.

To enable striping, they need to have equal priority. The built-in "swapon" doesn't support that but the one coming with Easy Debian does:

[root@deb-m5v3d: ~]swapoff /dev/mmcblk1p2     # Turn off uSD swap
[root@deb-m5v3d: ~]swapon -p 0 /dev/mmcblk1p2 # Turn on uSD swap with priority 0
[root@deb-m5v3d: ~]swapoff /dev/mmcblk0p3     # Turn off internal swap
[root@deb-m5v3d: ~]swapon -p 0 /dev/mmcblk0p3 # Turn on internal swap with priority 0
[root@deb-m5v3d: ~]swapon -s                  # Check the status
Filename    Type  Size Used Priority
/dev/mmcblk0p3                          partition 786424 236 0
/dev/mmcblk1p2                          partition 393584 120276 0

--
Update: Crashed now and then so gave out using double swaps. Not sure if those restarts had anything to do with the swap areas, I didn't much worry about development statuses of apps.

--
Update 2012-09-14: My N900's USB port finally gave up, and after some time the touch sensor, so I finally had to find another phone to replace it. Some deep researching (that's how engineers do shopping) gave me a clear picture of current phone options, so I could order the optimal replacement. A second hand N900 with nothing else, so the price was fine, even if it was the first phone ever I had to pay for. Then found out a friend of mine has a N900 with broken motherboard, but screen apparently OK, so after replacing bits here and there I got one fully functional one (with a brighter screen from one of the others), one working except USB, and one with nothing much working except USB, so I could use it as a battery charger. This lengthy description just tries to say that I ended up with a perfect N900 and a backup one, even with pretty much the same data and configuration, if/when I manage to brick the perfect one, so I could more freely try things. Welcome CSSU and testing performance improvements. This time testing one thing at a time, and avoiding dev status apps.

After finding my overclocking limits (ULV/1150MHz, will write something abt those some day), I continued to the swap challenge zone, and again enabled the second swap as above, and found there's a nifty tool called Swappolube that can be used to easily change swap settings make them survive reboot. Now I have been running this setup (ULV/1150MHz, prio 0 swap on both eMMC and uSD, and swappiness set to 30 with Swappolube) for about three weeks with no problems, the only unplanned shutdown due to running out of battery once.

My current swap settings:

Swappiness 30
Dirty ratio 40 (default)
Dirty BGD Ratio 10 (default)
Dirty expire centisecs 0
Dirty Writeback Centisecs 0
Page cluster 0
VFS Cache Pressure 100 (default)
Laptop Mode 1
MMC0 Requests 128 (default)
MMc1 Requests 128 (default)
min. free kBytes 2039 (default)
Kill Allocating Task false
TCP Timestamps true
TCP No MetricsSave false
I tried first with all at the "recommended" values but quickly got a reboot, now that it seems to work fine, I might start setting those back to recommended one by one every couple of days.

Compared to the original, this configuration is from another planet; for some hours tried to use my other N900 which is pretty much a mirror copy, but with the original clock speed and swap settings - well, you know the feeling when you find the old (used to be) absurdly fast 486 from the attic, and after your i7 quad core it won't feel exactly quick anymore.