您好,我是内核开发人员的新手,

创建了一个简单的程序:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/kthread.h>

MODULE_LICENSE("Dual BSD/GPL");


int messager(void*);
struct task_struct* kthrstr;

static int start_module(void)
{
    printk(KERN_INFO "Loading the messager\n");

    kthrstr = kthread_create(messager,NULL,"MESSAGER");
    wake_up_process(kthrstr);
    return 0;
}

static void stop_module(void)
{
    printk(KERN_INFO "Unloading the messager\n");
    kthread_stop(kthrstr);
}

int messager(void* varg)
{
    daemonize("MESSAGER");
    allow_signal(SIGKILL);

    while(1)
    {
        printk(KERN_INFO "Timeout: Hello");
        set_current_state(TASK_INTERRUPTIBLE);
        schedule_timeout(10 * HZ);
        if (signal_pending(current))
            break;
    }
    return 0;
}

module_init(start_module);
module_exit(stop_module);

该模块已正确加载,并且消息也按预期显示在syslog中。但是当使用rmmod卸载模块时,它会出现如下所示的困惑情况。请帮助我确定发生了什么错误以及如何纠正:
[ 2207.466086] Timeout: Hello
[ 2215.756784] Unloading the messager
[ 2217.461846] BUG: unable to handle kernel paging request at f0ca8054
[ 2217.462328] IP: [<f0ca8054>] 0xf0ca8054
[ 2217.462772] *pdpt = 0000000000a76001 *pde = 000000002f8b1067 *pte = 0000000000000000
[ 2217.463003] Oops: 0010 [#1] PREEMPT SMP
[ 2217.463065] last sysfs file: /sys/module/ip6_tables/initstate
[ 2217.463328] Modules linked in: fuse ip6t_LOG xt_tcpudp xt_pkttype ipt_LOG xt_limit vmsync vmblock af_packet mperf snd_pcm_oss snd_mixer_oss snd_seq_midi snd_seq_midi_event snd_seq edd ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_raw xt_NOTRACK ipt_REJECT iptable_raw iptable_filter ip6table_mangle nf_conntrack_netbios_ns nf_conntrack_ipv4 nf_defrag_ipv4 ip_tables xt_conntrack nf_conntrack ip6table_filter ip6_tables x_tables snd_ens1371 gameport snd_rawmidi snd_seq_device snd_ac97_codec ac97_bus snd_pcm sg snd_timer ppdev pcnet32 mptctl snd sr_mod soundcore vmci pcspkr cdrom parport_pc vmxnet shpchp snd_page_alloc parport i2c_piix4 vmw_balloon pci_hotplug floppy button ac container ext4 jbd2 crc16 linear dm_snapshot dm_mod fan processor thermal thermal_sys ata_generic mptspi mptscsih mptbase scsi_transport_spi [last unloaded: printmsg]
[ 2217.463839]
[ 2217.463957] Pid: 6684, comm: MESSAGER Not tainted 2.6.37.1-1.2-desktop #1 VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform
[ 2217.464156] EIP: 0060:[<f0ca8054>] EFLAGS: 00010296 CPU: 0
[ 2217.464216] EIP is at 0xf0ca8054
[ 2217.464249] EAX: 00000000 EBX: e8678430 ECX: 00000286 EDX: 00000000
[ 2217.464275] ESI: 00000000 EDI: f0ca8000 EBP: 00000000 ESP: eccedfb4
[ 2217.464302]  DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
[ 2217.464414] Process MESSAGER (pid: 6684, ti=eccec000 task=e8678430 task.ti=eccec000)
[ 2217.464450] Stack:
[ 2217.464580]  f0ca80f9 00000000 ec52ff2c c0265dc4 00000000 00000000 00000001 00000101
[ 2217.464714]  eccedfd4 eccedfd4 00000000 c0265d50 ec52ff2c c02034e6 00000000 00000000
[ 2217.464734]  00000000 00000000 00000000
[ 2217.464787] Call Trace:
[ 2217.465094] Inexact backtrace:
[ 2217.465097]
[ 2217.476943]  [<c0265dc4>] ? kthread+0x74/0x80
[ 2217.476965]  [<c0265d50>] ? kthread+0x0/0x80
[ 2217.476985]  [<c02034e6>] ? kernel_thread_helper+0x6/0x10
[ 2217.483598] Code:  Bad EIP value.
[ 2217.483786] EIP: [<f0ca8054>] 0xf0ca8054 SS:ESP 0068:eccedfb4
[ 2217.483849] CR2: 00000000f0ca8054
[ 2217.484325] ---[ end trace dc9382a06b455776 ]---

最佳答案

您的模块崩溃是因为对daemonize()的调用导致稍后的kthread_stop()调用无需等待就返回。

此外,如here所述,kthread_stop()不会向线程发送信号,而是使kthread_should_stop()返回true。简而言之,将您的代码更改为在while (!kthread_should_stop())上循环,并删除daemonize(此处不必要和危险)和allow_signal调用。

10-07 22:25