diff --git a/.gitignore b/.gitignore index 650494b..b44a480 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.o *.ko *cmd +*.dwo *.swp *.symvers *.mod @@ -31,4 +32,4 @@ lkmpg.pdf *.xref # format checks -expected-format +expected-format \ No newline at end of file diff --git a/Makefile b/Makefile index 4b54113..788474c 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ $(PROJ).pdf: lkmpg.tex html: lkmpg.tex html.cfg sed $ 's/\t/ /g' lkmpg.tex > lkmpg-for-ht.tex - make4ht --shell-escape --utf8 --format html5 --config html.cfg --output-dir html lkmpg-for-ht.tex + make4ht --shell-escape --utf8 --format html5 --config html.cfg --output-dir html lkmpg-for-ht.tex "fn-in" ln -sf lkmpg-for-ht.html html/index.html rm -f lkmpg-for-ht.tex lkmpg-for-ht.xref lkmpg-for-ht.tmp lkmpg-for-ht.html lkmpg-for-ht.css lkmpg-for-ht.4ct lkmpg-for-ht.4tc lkmpg-for-ht.dvi lkmpg-for-ht.lg lkmpg-for-ht.idv lkmpg*.svg lkmpg-for-ht.log lkmpg-for-ht.aux rm -rf _minted-$(PROJ) _minted-lkmpg-for-ht diff --git a/examples/bottomhalf.c b/examples/bottomhalf.c index 9117d1b..6abc990 100644 --- a/examples/bottomhalf.c +++ b/examples/bottomhalf.c @@ -14,6 +14,13 @@ #include #include +/* Macro DECLARE_TASKLET_OLD exists for compatibiity. + * See https://lwn.net/Articles/830964/ + */ +#ifndef DECLARE_TASKLET_OLD +#define DECLARE_TASKLET_OLD(arg1, arg2) DECLARE_TASKLET(arg1, arg2, 0L) +#endif + static int button_irqs[] = {-1, -1}; /* Define GPIOs for LEDs. @@ -38,7 +45,7 @@ static void bottomhalf_tasklet_fn(unsigned long data) pr_info("Bottom half tasklet ends\n"); } -DECLARE_TASKLET(buttontask, bottomhalf_tasklet_fn, 0L); +DECLARE_TASKLET_OLD(buttontask, bottomhalf_tasklet_fn); /* interrupt function triggered when a button is pressed */ static irqreturn_t button_isr(int irq, void *data) diff --git a/examples/cryptosk.c b/examples/cryptosk.c index 82af616..b9a84f4 100644 --- a/examples/cryptosk.c +++ b/examples/cryptosk.c @@ -4,6 +4,8 @@ #include #include #include +#include +#include #define SYMMETRIC_KEY_LENGTH 32 #define CIPHER_BLOCK_SIZE 16 diff --git a/examples/example_tasklet.c b/examples/example_tasklet.c index a0cbd3c..c5502f0 100644 --- a/examples/example_tasklet.c +++ b/examples/example_tasklet.c @@ -6,6 +6,13 @@ #include #include +/* Macro DECLARE_TASKLET_OLD exists for compatibiity. + * See https://lwn.net/Articles/830964/ + */ +#ifndef DECLARE_TASKLET_OLD +#define DECLARE_TASKLET_OLD(arg1, arg2) DECLARE_TASKLET(arg1, arg2, 0L) +#endif + static void tasklet_fn(unsigned long data) { pr_info("Example tasklet starts\n"); @@ -13,7 +20,7 @@ static void tasklet_fn(unsigned long data) pr_info("Example tasklet ends\n"); } -DECLARE_TASKLET(mytask, tasklet_fn, 0L); +DECLARE_TASKLET_OLD(mytask, tasklet_fn); static int example_tasklet_init(void) { diff --git a/examples/syscall.c b/examples/syscall.c index b9087f4..7b8153f 100644 --- a/examples/syscall.c +++ b/examples/syscall.c @@ -14,8 +14,8 @@ #include #include #include /* which will have params */ -#include -#include /* The list of system calls */ +#include /* The list of system calls */ +#include /* For the current (process) structure, we need this to know who the * current user is. @@ -23,6 +23,15 @@ #include #include +/* The in-kernel calls to the ksys_close() syscall were removed in Linux v5.11+. + */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)) +#include /* ksys_close() wrapper for backward compatibility */ +#define close_fd ksys_close +#else +#include /* For close_fd */ +#endif + unsigned long **sys_call_table; unsigned long original_cr0; @@ -80,7 +89,7 @@ static unsigned long **aquire_sys_call_table(void) while (offset < ULLONG_MAX) { sct = (unsigned long **) offset; - if (sct[__NR_close] == (unsigned long *) ksys_close) + if (sct[__NR_close] == (unsigned long *) close_fd) return sct; offset += sizeof(void *); diff --git a/lkmpg.tex b/lkmpg.tex index 485a5d3..60563be 100644 --- a/lkmpg.tex +++ b/lkmpg.tex @@ -1421,6 +1421,15 @@ Example tasklet starts Example tasklet init continues... Example tasklet ends \end{verbatim} +Although tasklet is easy to use, it comes with several defators, and developers are discussing about getting rid of tasklet in linux kernel. +The tasklet callback runs in atomic context, inside a software interrupt, meaning that it cannot sleep or access user-space data, so not all work can be done in a tasklet handler. +Also, the kernel only allows one instance of any given tasklet to be running at any given time; multiple different tasklet callbacks can run in parallel. + +In recent kernels, tasklets can be replaced by workqueues, timers, or threaded interrupts.\footnote{The goal of threaded interrupts is to push more of the work to separate threads, so that the minimum needed for acknowledging an interrupt is reduced, and therefore the time spent handling the interrupt (where it can't handle any other interrupts at the same time) is reduced. +See https://lwn.net/Articles/302043/} +While the removal of tasklets remains a longer-term goal, the current kernel contains more than a hundred uses of tasklets. +Now developers are proceeding with the API changes and the macro \cpp|DECLARE_TASKLET_OLD| exists for compatibiity. +For further information, see \url{https://lwn.net/Articles/830964/}. \subsection{Work queues} \label{sec:workqueue}