Skip to content

Commit 870b26f

Browse files
committed
Update several example code for newer kernel
Known issues with current example code: If you using newer kernel(e.g linux 5.11.x) to compile the example code, you may meet following error: 1. syscall.c:83:50: error: ‘ksys_close’ undeclared; 2. cryptosk.c:17:24: error: field ‘sg’ has incomplete type 3. cryptosk.c:143:9: error: implicit declaration of function ‘get_random_bytes’ 4. error: macro "DECLARE_TASKLET" passed 3 arguments, but takes just 2 Solutions/workaround: 1. In syscall.c, replace #include <linux/syscalls.h> with #include <linux/fdtable.h> and replace ksys_close with close_fd if the kernel version >= 5.11. [1][2] 2. Add #include <linux/scatterlist.h> into cryptosk.c 3. Add #include <linux/random.h> into cryptosk.c 4. In bottomhalf.c and example_tasklet.c, replace DECLARE_TASKLET with DECLARE_TASKLET_OLD and dispose third argument(0L). [3] [1] - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1572bfdf21d4d50e51941498ffe0b56c2289f783 [2] - https://www.mail-archive.com/[email protected]//msg11939.html [3] - https://patchwork.kernel.org/project/kernel-hardening/patch/[email protected]/
1 parent bd8342b commit 870b26f

File tree

7 files changed

+42
-7
lines changed

7 files changed

+42
-7
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
*.o
33
*.ko
44
*cmd
5+
*.dwo
56
*.swp
67
*.symvers
78
*.mod
@@ -31,4 +32,4 @@ lkmpg.pdf
3132
*.xref
3233

3334
# format checks
34-
expected-format
35+
expected-format

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ $(PROJ).pdf: lkmpg.tex
99

1010
html: lkmpg.tex html.cfg
1111
sed $ 's/\t/ /g' lkmpg.tex > lkmpg-for-ht.tex
12-
make4ht --shell-escape --utf8 --format html5 --config html.cfg --output-dir html lkmpg-for-ht.tex
12+
make4ht --shell-escape --utf8 --format html5 --config html.cfg --output-dir html lkmpg-for-ht.tex "fn-in"
1313
ln -sf lkmpg-for-ht.html html/index.html
1414
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
1515
rm -rf _minted-$(PROJ) _minted-lkmpg-for-ht

examples/bottomhalf.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@
1414
#include <linux/kernel.h>
1515
#include <linux/module.h>
1616

17+
/* Macro DECLARE_TASKLET_OLD exists for compatibiity.
18+
* See https://lwn.net/Articles/830964/
19+
*/
20+
#ifndef DECLARE_TASKLET_OLD
21+
#define DECLARE_TASKLET_OLD(arg1, arg2) DECLARE_TASKLET(arg1, arg2, 0L)
22+
#endif
23+
1724
static int button_irqs[] = {-1, -1};
1825

1926
/* Define GPIOs for LEDs.
@@ -38,7 +45,7 @@ static void bottomhalf_tasklet_fn(unsigned long data)
3845
pr_info("Bottom half tasklet ends\n");
3946
}
4047

41-
DECLARE_TASKLET(buttontask, bottomhalf_tasklet_fn, 0L);
48+
DECLARE_TASKLET_OLD(buttontask, bottomhalf_tasklet_fn);
4249

4350
/* interrupt function triggered when a button is pressed */
4451
static irqreturn_t button_isr(int irq, void *data)

examples/cryptosk.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include <crypto/internal/skcipher.h>
55
#include <linux/crypto.h>
66
#include <linux/module.h>
7+
#include <linux/random.h>
8+
#include <linux/scatterlist.h>
79

810
#define SYMMETRIC_KEY_LENGTH 32
911
#define CIPHER_BLOCK_SIZE 16

examples/example_tasklet.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,21 @@
66
#include <linux/kernel.h>
77
#include <linux/module.h>
88

9+
/* Macro DECLARE_TASKLET_OLD exists for compatibiity.
10+
* See https://lwn.net/Articles/830964/
11+
*/
12+
#ifndef DECLARE_TASKLET_OLD
13+
#define DECLARE_TASKLET_OLD(arg1, arg2) DECLARE_TASKLET(arg1, arg2, 0L)
14+
#endif
15+
916
static void tasklet_fn(unsigned long data)
1017
{
1118
pr_info("Example tasklet starts\n");
1219
mdelay(5000);
1320
pr_info("Example tasklet ends\n");
1421
}
1522

16-
DECLARE_TASKLET(mytask, tasklet_fn, 0L);
23+
DECLARE_TASKLET_OLD(mytask, tasklet_fn);
1724

1825
static int example_tasklet_init(void)
1926
{

examples/syscall.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,24 @@
1414
#include <linux/kernel.h>
1515
#include <linux/module.h>
1616
#include <linux/moduleparam.h> /* which will have params */
17-
#include <linux/syscalls.h>
18-
#include <linux/unistd.h> /* The list of system calls */
17+
#include <linux/unistd.h> /* The list of system calls */
18+
#include <linux/version.h>
1919

2020
/* For the current (process) structure, we need this to know who the
2121
* current user is.
2222
*/
2323
#include <linux/sched.h>
2424
#include <linux/uaccess.h>
2525

26+
/* The in-kernel calls to the ksys_close() syscall were removed in Linux v5.11+.
27+
*/
28+
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0))
29+
#include <linux/syscalls.h> /* ksys_close() wrapper for backward compatibility */
30+
#define close_fd ksys_close
31+
#else
32+
#include <linux/fdtable.h> /* For close_fd */
33+
#endif
34+
2635
unsigned long **sys_call_table;
2736
unsigned long original_cr0;
2837

@@ -80,7 +89,7 @@ static unsigned long **aquire_sys_call_table(void)
8089
while (offset < ULLONG_MAX) {
8190
sct = (unsigned long **) offset;
8291

83-
if (sct[__NR_close] == (unsigned long *) ksys_close)
92+
if (sct[__NR_close] == (unsigned long *) close_fd)
8493
return sct;
8594

8695
offset += sizeof(void *);

lkmpg.tex

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,6 +1421,15 @@ \subsection{Tasklets}
14211421
Example tasklet init continues...
14221422
Example tasklet ends
14231423
\end{verbatim}
1424+
Although tasklet is easy to use, it comes with several defators, and developers are discussing about getting rid of tasklet in linux kernel.
1425+
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.
1426+
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.
1427+
1428+
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.
1429+
See https://lwn.net/Articles/302043/}
1430+
While the removal of tasklets remains a longer-term goal, the current kernel contains more than a hundred uses of tasklets.
1431+
Now developers are proceeding with the API changes and the macro \cpp|DECLARE_TASKLET_OLD| exists for compatibiity.
1432+
For further information, see \url{https://lwn.net/Articles/830964/}.
14241433

14251434
\subsection{Work queues}
14261435
\label{sec:workqueue}

0 commit comments

Comments
 (0)