[Galaxy S III Android Development] agusdallalba:
vnswap is not working as expected?

Since nobody answered my question on how vnswap worked I went on to find out. And I concluded it's not using the MMC at all, at least in CM12.

This is how it works:

I started with the vnswap source code

This is probably the worst piece of kernel code I've ever seen. I'd love to see Linus Torvalds' reaction if Samsung ever tries to submit this to the mainline kernel :p

As far as I can tell vnswap it's a block device that pretends to be a bigger block device. When there's a write request to it, it builds up a map where each section of the vnswap0 file points to another file you can set in /sys/block/vnswap0/swap_filename. For this to make sense file is should be smaller than or equal to /sys/block/vnswap0/disksize, but it can be anything. It does make sure it's smaller than 1GB, but I don't see why.

This alone can't swap anything, so what's going on? I turns out the kernel has zswap enabled by default. Which according to the official zswap documentation it's an in-memory pool of compressed memory pages, exactly like zram, but dynamic. What I mean with 'dynamic' is that It will use up to /sys/module/zswap/parameters/max_pool_percent of memory, instead of having a fixed uncompressed size like zram. So for examplewhile with zram if there is 500MB of data that compresses to 250MB and you have set a 400MB zram disk, only 400MB of he original 500MB will be compressed, zswap on the other hand will compress everything until the compressed size of the data reaches by default 20% of physical memory. Pages that don't compress well are written to the swap device. However, with zswap the swap device will never be used completely, so it makes sense to use vnswap to 'lie' to the kernel and make it think it has a bigger swap space than what it actually has.

This is how it is implemented:

The vnswap switch in aTweaks ultimately (in source code, this goes to this goes to this goes to this) ends up running /sbin/sswap -s on every boot. I couldn't find a source for this binary, so I ran strace on it. This is what it does:

Reads /sys/block/mmcblk0/device/name, but I can't tell what for without a code decompiler.

Opens /sys/block/mmcblk0/device/smart, but this file doesn't exist!

Sets /sys/block/vnswap0/disksize to 512MiB

Performs a mkswap /dev/block/vnswap0 manually

The equivalent of swapon /dev/block/vnswap0 --discard

What it does not do is set /sys/block/vnswap0/swap_filename to anything! There is code to do this in the binary, as that path and /sys/block/vnswap0/init_backing_storage can be found by running the strings command through it.

Running sswap -h reveals a 'Nandless mode'. But sswap -s and sswap -s -r do exactly the same things according to strace.

And this is why I think this isn't working correctly.

Both sswap -s and sswap -s -r (-r for Nandless) act the same and neither set a backing storage file for vnswap0.

Writes to vnswap0 (with dd if=/dev/zero of=/dev/block/vnswap0 bs=4096) are extremely fast (~200MB/s) and throw lots of 'lost page write due to I/O error on vnswap0' errors to dmesg.

After setting up vnswap manually with:

dd if=/dev/zero of=/cache/swap bs=4096 count=131072 #512 MiB
echo -n '/cache/swap' > /sys/block/vnswap0/swap_filename
echo > /sys/block/vnswap0/init_backing_storage

(I figured out the steps from the vnswap source code) I get no I/O errors and writes to vnswap are ~20MB/s as expected from NAND.

So right now vnswap acts exactly like zram, which for me is great, but may be not what [MENTION=4898097]arter97[/MENTION] wanted. I think this happens because the sswap binary is not compatible with CM12, the i9300, or maybe my particular NAND chip. To know if yours is working 'properly' run cat /sys/block/vnswap0/init_backing_storage in adb shell or the Terminal Emulator app. If the second number is 0 then vnswap is not backed by anything.