Developer Notes

Note Regarding kGraft

The following note is for those who maintain kernel modules for use SUSE Linux Enterprise Server 12.

Background

kGraft is a technology allowing for live patching of a running kernel with zero interruption to it’s execution. It’s the core of the SUSE Linux Enterprise Live Patching offering. For interoperability with kGraft, specific attention is required when developing kernel modules that utilize kernel threads.

kGraft and Kernel Threads

kGraft, by its design, requires to have a well-defined point in execution of each thread, where it’s safe to perform per-thread migration from “unpatched universe” to the patched one (for details on how kGraft’s consistency model works, please refer to our slides 1).

For userspace threads, such a point is defined at the userspace / kernelspace boundary, which means the process is migrated to a “patched universe” at the time it’s exiting from the kernel system call.

Kernel threads, on the other hand, never cross the kernelspace/userspace boundary, yet they need to be migrated as well in order to allow the kGraft patching process to finalize.

kGraft is migrating freezable kernel threads at the point they issue a try_to_freeze() call, as this is considered a well defined execution point in kernel thread lifetime (with respect to semantical context). kGraft also automatically takes care of kernel threads which are managed by kthread_worker. However, we currently don’t have a viable “automatic” solution for the non-freezable kernel threads and therefore such threads need to be annotated manually.

Here comes our plea for authors of 3rd party kernel modules: if your module spawns a kernel thread which doesn’t ever call try_to_freeze(), please identify a point in execution of the thread where it can be safely (with respect to kGraft consistency model) migrated to the “patched universe” and annotate that point by explicitly calling:

kgr_task_safe(current);

Also please note that wait_event_{freezable,interruptible}() is a loop by itself internally, hence it’s necessary to make kgr_task_safe() annotation part of the wait_event() condition. For example:

rc = wait_event_interruptible(phba->work_waitq, ({
            kgr_task_safe(current);
            (test_and_clear_bit(LPFC_DATA_READY,
                        &phba->data_flags)
             || kthread_should_stop()); }));

In case of doubt how to identify such point in the thread execution, we encourage authors to contact SUSE.


  1. http://www.novell.com/docrep/2014/03/kGraft.pdf slides 13-16↩︎