Skip to content

Commit 3682d9e

Browse files
committed
Move bottom-half to workqueue for safe sleep
Based on issue #191 (@trulykyle)'s feedback, the original bottomhalf.c example was calling msleep() inside a tasklet, which runs in atomic context and can lead to a kernel crash. This patch moves the time- consuming work to a workqueue, which runs in process context and allows sleeping, while preserving the immediate LED control logic in the ISR. Close #191
1 parent a035231 commit 3682d9e

File tree

1 file changed

+9
-8
lines changed

1 file changed

+9
-8
lines changed

examples/bottomhalf.c

+9-8
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/printk.h>
1616
#include <linux/init.h>
1717
#include <linux/version.h>
18+
#include <linux/workqueue.h>
1819

1920
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 10, 0)
2021
#define NO_GPIO_REQUEST_ARRAY
@@ -42,16 +43,17 @@ static struct gpio buttons[] = {
4243
{ 18, GPIOF_IN, "LED 1 OFF BUTTON" },
4344
};
4445

45-
/* Tasklet containing some non-trivial amount of processing */
46-
static void bottomhalf_tasklet_fn(unsigned long data)
46+
/* Workqueue function containing some non-trivial amount of processing */
47+
static void bottomhalf_work_fn(struct work_struct *work)
4748
{
48-
pr_info("Bottom half tasklet starts\n");
49+
pr_info("Bottom half workqueue starts\n");
4950
/* do something which takes a while */
50-
mdelay(500);
51-
pr_info("Bottom half tasklet ends\n");
51+
msleep(500);
52+
53+
pr_info("Bottom half workqueue ends\n");
5254
}
5355

54-
static DECLARE_TASKLET_OLD(buttontask, bottomhalf_tasklet_fn);
56+
static DECLARE_WORK(bottomhalf_work, bottomhalf_work_fn);
5557

5658
/* interrupt function triggered when a button is pressed */
5759
static irqreturn_t button_isr(int irq, void *data)
@@ -63,8 +65,7 @@ static irqreturn_t button_isr(int irq, void *data)
6365
gpio_set_value(leds[0].gpio, 0);
6466

6567
/* Do the rest at leisure via the scheduler */
66-
tasklet_schedule(&buttontask);
67-
68+
schedule_work(&bottomhalf_work);
6869
return IRQ_HANDLED;
6970
}
7071

0 commit comments

Comments
 (0)