Re: [PATCH -V3 0/8] migrate_pages(): fix several bugs in error path

From: Huang, Ying
Date: Mon Sep 19 2022 - 22:44:10 EST


Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> writes:

> On Wed, 17 Aug 2022 16:14:00 +0800 Huang Ying <ying.huang@xxxxxxxxx> wrote:
>
>> error-inject.patch, test-migrate.c, and test-migrate.sh are as below.
>> It turns out that error injection is an important tool to fix bugs in
>> error path.
>
> Indeed, and thanks for doing this.
>
> Did you consider lib/*inject*.c? If so, was it unsuitable?

I have done some experiments to use some existing error injection
mechanisms in kernel to test the error path of migrate_pages(). After
some googling, I found that the BPF based error injection described in
the following URL is most suitable for my purpose.

https://lwn.net/Articles/740146/

Because the BPF seems quite flexible to satisfy various requirements of
error injection. With it, the execution of some functions can be
skipped and some specified error code can be returned instead.

Works out of box
================

Some error injection functionality just works out of box. For example,
inject some page allocation error in some path. Firstly,
CONFIG_BPF_KPROBE_OVERRIDE needs to be enabled in kernel config. Then,
a simple bpftrace script as follows can be used to inject page
allocation error during migrate_pages().

--------------------ENOMEM-----------------------
kprobe:migrate_pages { @in_migrate_pages++; }
kretprobe:migrate_pages { @in_migrate_pages--; }
kprobe:should_fail_alloc_page / @in_migrate_pages > 0 / {
override(1);
}
-------------------------------------------------

The call chain of error injection is specified via the first 2 lines. I
copied the methods used in BCC inject script. Is there any better
method to specify the call chain?

We can inject error only for THP page allocation too.

--------------------ENOMEM THP-------------------
kprobe:migrate_pages { @in_migrate_pages++; }
kretprobe:migrate_pages { @in_migrate_pages--; }
kprobe:should_fail_alloc_page / @in_migrate_pages > 0 && arg1 == 9 / {
override(1);
}
-------------------------------------------------

Use some hack to override any function
======================================

The in-kernel BPF based error injection mechanism can only override
function return value for the functions in the whitelist, that is,
functions marked with ALLOW_ERROR_INJECTION(). That is quite limited.
The thorough error path testing needs to override the return value of
arbitrary function. So, I use a simple hack patch as follows for that.

-----------------------8<---------------------------------