问题
I want to call a user space program from a kernel module periodically.But the kernel program is freezing the system, while I try to load it. following is the program,
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
#include <linux/jiffies.h>
#include <linux/time.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <linux/hrtimer.h>
#include <linux/sched.h>
#include <linux/delay.h>
#define TIME_PERIOD 50000
static struct hrtimer hr_timer;
static ktime_t ktime_period_ns;
static enum hrtimer_restart timer_callback(struct hrtimer *timer){
char userprog[] = "test.sh";
char *argv[] = {userprog, "2", NULL };
char *envp[] = {"HOME=/", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
printk("\n Timer is running");
hrtimer_forward_now(&hr_timer, ktime_period_ns);
printk("callmodule: %s\n", userprog);
call_usermodehelper(userprog, argv, envp, UMH_WAIT_PROC);
return HRTIMER_RESTART;
}
static int __init timer_init() {
ktime_period_ns= ktime_set( 0, TIME_PERIOD);
hrtimer_init ( &hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
hr_timer.function = timer_callback;
hrtimer_start( &hr_timer, ktime_period_ns, HRTIMER_MODE_REL );
return 0;
}
static int __exit timer_exit(){
int cancelled = hrtimer_cancel(&hr_timer);
if (cancelled)
printk(KERN_ERR "Timer is still running\n");
else
printk(KERN_ERR "Timer is cancelled\n");
}
module_init(timer_init);
module_exit(timer_exit);
MODULE_LICENSE("GPL");
test.sh is a script which just echoes a comment. I have tested the call_usermodehelper part and timer part individually and it is working fine. But while I am combining the two codes, the system hangs. Can anybody please help me to solve the problem.
回答1:
Quick look around strongly suggests that hrtimer callbacks are executed from an irq context, which is expected - how else are you going to get high resoluton?
But this also means you must no block, while your callback can block due to call_usermodehelper regardless of NOWAIT passed.
So it seems you are testing your module on a kernel with debugging disabled, which is fundamentally wrong.
But this is less relevant as the thing you are trying to achieve in the first place looks fundamentally wrong.
I can only recommend you elaborate what is the actual problem. There is absolutely now way that forking + execing has anything to do with something requiring a high resolution timer.
来源:https://stackoverflow.com/questions/35480122/kernel-module-periodically-calling-user-space-program