mirror of
https://github.com/sysprog21/lkmpg.git
synced 2025-04-24 05:24:06 +08:00
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
This commit is contained in:
parent
a035231815
commit
3682d9e6d5
@ -15,6 +15,7 @@
|
||||
#include <linux/printk.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 10, 0)
|
||||
#define NO_GPIO_REQUEST_ARRAY
|
||||
@ -42,16 +43,17 @@ static struct gpio buttons[] = {
|
||||
{ 18, GPIOF_IN, "LED 1 OFF BUTTON" },
|
||||
};
|
||||
|
||||
/* Tasklet containing some non-trivial amount of processing */
|
||||
static void bottomhalf_tasklet_fn(unsigned long data)
|
||||
/* Workqueue function containing some non-trivial amount of processing */
|
||||
static void bottomhalf_work_fn(struct work_struct *work)
|
||||
{
|
||||
pr_info("Bottom half tasklet starts\n");
|
||||
pr_info("Bottom half workqueue starts\n");
|
||||
/* do something which takes a while */
|
||||
mdelay(500);
|
||||
pr_info("Bottom half tasklet ends\n");
|
||||
msleep(500);
|
||||
|
||||
pr_info("Bottom half workqueue ends\n");
|
||||
}
|
||||
|
||||
static DECLARE_TASKLET_OLD(buttontask, bottomhalf_tasklet_fn);
|
||||
static DECLARE_WORK(bottomhalf_work, bottomhalf_work_fn);
|
||||
|
||||
/* interrupt function triggered when a button is pressed */
|
||||
static irqreturn_t button_isr(int irq, void *data)
|
||||
@ -63,8 +65,7 @@ static irqreturn_t button_isr(int irq, void *data)
|
||||
gpio_set_value(leds[0].gpio, 0);
|
||||
|
||||
/* Do the rest at leisure via the scheduler */
|
||||
tasklet_schedule(&buttontask);
|
||||
|
||||
schedule_work(&bottomhalf_work);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user