A simple guide of using LinuxKI

I think LinuxKI is an underrated Linux performance tuning tool. When I worked in HPE, one of my colleagues heavily relied on LinuxKI to do performance tuning. I still remember one of his workload is like this: 8 Oracle databases run in 8 docker containers simultaneously, and he did following things every day:
(1) Execute runki to collect data;
(2) Use kiall to analyse data, then tune some parameters;
(3) Go back to step (1).

Below is a simple guide of how to use LinuxKI, and I assume the LinuxKI is already installed:
(1) Collect data in /dev/shm directory to reduced the risk of missing LinuxKI events during the tracing and does not add to the disk workload, but be sure /dev/shm has enough memory:

$ cd /dev/mem

(2) Run runki command (-R options means capturing advanced CPU stats):

$ sudo /opt/linuxki/runki -R

After finishing, there is a compressed *.tgz file:

$ ll -h
total 359M
-rw-r--r--. 1 root root 359M Apr 29 13:39 ki_all.pocket-p2.0429_1337.tgz

(3) Copy the *.tgz file into home directory:

$ cp ki_all.pocket-p2.0429_1337.tgz ~/

and now the original file can be safely removed.

(4) The final step is generating the reports:

$ cd ~
$ /opt/linuxki/kiall -r
Processing files in: /home/nanxiao/pocket-p2/0429_1337
Merging KI binary files.  Please wait...
ki.bin files merged by kiinfo -likimerge
/opt/linuxki/kiinfo -kitrace -ts 0429_1337
/opt/linuxki/kiinfo -kiall csv -html -ts 0429_1337
kiall complete

Then we can check and analyse the reports now.

Test locking a spinlock twice behaviour

I was curious whether pthread_spin_lock() can really detect deadlock scenario, so I wrote a simple program to test:

#include <stdio.h>
#include <pthread.h>

int
main(void)
{
    pthread_spinlock_t lock;
    if (pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE) != 0) {
        perror("pthread_spin_init error");
        return 1;
    }

    if (pthread_spin_lock(&lock) != 0) {
        perror("pthread_spin_lock 1 error");
        return 1;
    }

    if (pthread_spin_lock(&lock) != 0) {
        perror("pthread_spin_lock 2 error");
        return 1;
    }

    return 0;
}

Tested it on both Linux and FreeBSD, the program blocked on the second pthread_spin_lock, never return:

$ ./double_lock

P.S., the code can be found here.

Beware of out-of-boundary access of array

Today my colleague fixed one bug related to out-of-boundary access of array: a hash function returns the selected index of the array, but the hash function’s return value is int, so in corner case, when the hash value is overflow, it can become negative, and this will cause access an invalid element of the array. The lessons I learnt from this bug:
(1) Review the return value of hash function;
(2) Pay attention to the index when accessing array, is it possible to cause out-of-boundary access?

How to obtain a big-endian CPU machine

Last week, I wanted to test whether a trivial function works OK on big-endian CPU. I have ARM and X86_64 machines at hand, but both them are little-endian. After searching online, I come across Running a emulated SparcStation 20 with qemu-sparc, though I heard about qemu before, but never used it, so wanted to give it a spin.

The installation of qemu is straightforward, then I created a NetBSD-10.1-sparc machine in just 3 steps (omit some configurations unneeded for me):

$ qemu-img create -f qcow2 ss20.image 4G
$ qemu-system-sparc -M SS-20 -m 256 -drive file=NetBSD-10.1-sparc.iso,bus=0,unit=2,media=cdrom,readonly=on -drive file=ss20.image,bus=0,unit=0,media=disk -full-screen -boot d
$ qemu-system-sparc -M SS-20 -m 256 -drive file=ss20.image,bus=0,unit=0,media=disk -full-screen -boot c

Then the machine booted successfully and met my requirement perfectly!