您好我正在尝试使用来自使用Allwinner SOC在ARM板(来自Olimex)的内核模块中创建的tasklet的call_usermodehelper_exec来运行用户空间进程。
我的代码很简单:
#include <linux/kernel.h>
#include <linux/module.h>
char my_tasklet_data[]="tasklet executed";
static int umh_test(void)
{
struct subprocess_info *sub_info;
char *argv[] = { "/usr/bin/logger", "help!", NULL };
static char *envp[] = {
"HOME=/",
"TERM=linux",
"PATH=/sbin:/bin:/usr/sbin:/usr/bin", NULL };
sub_info = call_usermodehelper_setup(argv[0], argv, envp, GFP_ATOMIC);
if (sub_info == NULL) return -ENOMEM;
return call_usermodehelper_exec(sub_info, UMH_WAIT_PROC);
}
void my_tasklet_function(unsigned long data)
{
printk(KERN_INFO "%s\n", (char *)data);
umh_test();
return;
}
DECLARE_TASKLET(my_tasklet, my_tasklet_function,
(unsigned long) &my_tasklet_data);
static int __init my_tasklet_init(void)
{
tasklet_schedule(&my_tasklet);
return 0;
}
module_init(my_tasklet_init);
static void __exit my_tasklet_cleanup(void)
{
tasklet_kill(&my_tasklet);
}
module_exit(my_tasklet_cleanup);
执行insmod tasklet.ko tasklet后调用/ usr / bin / logger更多,但是我也遇到了令人讨厌的内核错误:
[ 969.327698] tasklet executed
<3>BUG: scheduling while atomic: ksoftirqd/0/3/0x00000102
[ 969.335769] BUG: scheduling while atomic: ksoftirqd/0/3/0x00000102
<d>Modules linked in:[ 969.343861] Modules linked in:root@a20-olimex:~#tasklet(O) tasklet(O) disp_ump disp_ump mali_drm mali_drm cpufreq_powersave cpufreq_powersave cpufreq_stats cpufreq_stats drm drm cpufreq_userspace cpufreq_userspace cpufreq_conservative cpufreq_conservative mali mali g_ether g_ether pwm_sunxi pwm_sunxi sun4i_csi0 sun4i_csi0 videobuf_dma_contig videobuf_dma_contig videobuf_core videobuf_core gt2005 gt2005 sun4i_keyboard sun4i_keyboard ledtrig_heartbeat ledtrig_heartbeat leds_sunxi leds_sunxi led_class led_class sunxi_emac sunxi_emac sunxi_gmac sunxi_gmac sunxi_cedar_mod sunxi_cedar_mod 8192cu 8192cu ump ump lcd lcd [last unloaded: tasklet] [last unloaded: tasklet]
[<c0015058>] (unwind_backtrace+0x0/0x134) from [<c058455c>] (__schedule+0x744/0x7d0)
[ 969.410844] [<c0015058>] (unwind_backtrace+0x0/0x134) from [<c058455c>] (__schedule+0x744/0x7d0)
[<c058455c>] (__schedule+0x744/0x7d0) from [<c0582a20>] (schedule_timeout+0x1b8/0x220)
[ 969.427299] [<c058455c>] (__schedule+0x744/0x7d0) from [<c0582a20>] (schedule_timeout+0x1b8/0x220)
[<c0582a20>] (schedule_timeout+0x1b8/0x220) from [<c0583c04>] (wait_for_common+0xe4/0x138)
[ 969.444267] [<c0582a20>] (schedule_timeout+0x1b8/0x220) from [<c0583c04>] (wait_for_common+0xe4/0x138)
[<c0583c04>] (wait_for_common+0xe4/0x138) from [<c0049dc0>] (call_usermodehelper_exec+0x140/0x154)
[ 969.462267] [<c0583c04>] (wait_for_common+0xe4/0x138) from [<c0049dc0>] (call_usermodehelper_exec+0x140/0x154)
[<c0049dc0>] (call_usermodehelper_exec+0x140/0x154) from [<bf1c6050>] (my_tasklet_function+0x50/0x58 [tasklet])
[ 969.482096] [<c0049dc0>] (call_usermodehelper_exec+0x140/0x154) from [<bf1c6050>] (my_tasklet_function+0x50/0x58 [tasklet])
[<bf1c6050>] (my_tasklet_function+0x50/0x58 [tasklet]) from [<c003c800>] (tasklet_action+0x98/0x134)
[ 969.502110] [<bf1c6050>] (my_tasklet_function+0x50/0x58 [tasklet]) from [<c003c800>] (tasklet_action+0x98/0x134)
[<c003c800>] (tasklet_action+0x98/0x134) from [<c003c9d4>] (__do_softirq+0xd4/0x168)
[ 969.519768] [<c003c800>] (tasklet_action+0x98/0x134) from [<c003c9d4>] (__do_softirq+0xd4/0x168)
[<c003c9d4>] (__do_softirq+0xd4/0x168) from [<c003cb58>] (run_ksoftirqd+0xf0/0x1bc)
[ 969.535943] [<c003c9d4>] (__do_softirq+0xd4/0x168) from [<c003cb58>] (run_ksoftirqd+0xf0/0x1bc)
[<c003cb58>] (run_ksoftirqd+0xf0/0x1bc) from [<c00513a4>] (kthread+0x90/0x94)
[ 969.551513] [<c003cb58>] (run_ksoftirqd+0xf0/0x1bc) from [<c00513a4>] (kthread+0x90/0x94)
[<c00513a4>] (kthread+0x90/0x94) from [<c000f4b8>] (kernel_thread_exit+0x0/0x8)
[ 969.566739] [<c00513a4>] (kthread+0x90/0x94) from [<c000f4b8>] (kernel_thread_exit+0x0/0x8)
我尝试找到类似的问题,因为我正在学习驱动程序开发,但我发现所有问题都与问题有关,我们称之为内核破坏版本。 我使用自己的内核构建,并且我不排除可以与内核相关的内容,但是如果有人对某些主题是新的,他会确保代码没有任何应受谴责的错误。
所以任何帮助都将受到赞赏
答案 0 :(得分:2)
对call_usermodehelper_exec
的评论部分说明:
* @wait: wait for the application to finish and return status.
* when UMH_NO_WAIT don't wait at all, but you get no useful error back
* when the program couldn't be exec'ed. This makes it safe to call
* from interrupt context.
从tasklet调用实际上是一个中断上下文,所以你不能在那里等待。也就是说,您无法阻止,因为没有要阻止的任务上下文。 (这就是&#34;调度,而原子&#34;告诉你。)
您需要使用流程上下文部分,或者您需要使用UMH_NO_WAIT
而不是UMH_WAIT_PROC
。例如,你可以拥有
使用来自UMH_WAIT_PROC
的{{1}}进行了用户模式助手调用,因为您有一个任务上下文。
答案 1 :(得分:1)
Tasklet在soft-irq上下文中执行,因此无法休眠(调用schedule
函数)。
来自另一方的Usermode助手可以睡眠(就像任何其他用户空间代码一样)。
这就是你收到BUG: scheduling while atomic
消息的原因。