分享

module中调用spin_lock_irqsave没锁住内核

 Liucw2012 2012-04-18

理解] 为什么我的spin_lock_irqsave()没有锁住时钟中断?(这里的用户态汇编检测中断标志位的代码很值得参考)

分类: kernel 650人阅读 评论(0) 收藏 举报

LZ:

尝试用spin_lock_irqsave(),发现没有禁掉时钟中断,不知道我哪里理解错了?
kernel版本:

1.uname -a 结果:
2.
3.Linux localhost.localdomain 2.6.18 #1 Sat Jul 19 13:06:00 EDT 2008 i686 i686 i386 GNU/Linux
复制代码


我的代码:

1.#include <linux/kernel.h>
2.#include <linux/init.h>
3.#include <linux/module.h>
4.#include <linux/spinlock.h>
5.
6.static spinlock_t my_spinlock;
7.
8.static int __init init_test()
9.{
10.        unsigned long flags;
11.
12.        spin_lock_init(&my_spinlock);
13.
14.        spin_lock_irqsave(&my_spinlock, flags);
15.        return 0;
16.}
17.
18.static void __exit init_exit()
19.{
20.        return;
21.}
22.
23.module_init(init_test);
24.module_exit(init_exit);
复制代码


加载module以后,通过这样的命令查看墙上时钟:

1.#date; sleep 2; date
2.
3.输出结果:
4.Sun Apr 19 12:59:42 EDT 2009
5.Sun Apr 19 12:59:44 EDT 2009
复制代码

墙上时钟仍然在变化,说明时钟中断没有被禁掉。
但我理解的spin_lock_irqsave()会通过cli关掉所有IRQ,并且我在module中也没有spin_unlock_irqrestore(),所以按理说在加载了这个module之后,系统就不会响应任何外部可屏蔽中断了。但实际结果却不是这样。

我哪里理解错了呢?请各位指点,多谢!


--------------------------------------------------------------------------------

解答:

写了一段kernel module和 userspace program来验证:

kernel module: my_spin_lock.c

1.#include <linux/kernel.h>
2.#include <linux/init.h>
3.#include <linux/module.h>
4.#include <linux/spinlock.h>
5.
6.#define IF_MASK 0x00000200
7.
8.static spinlock_t my_spinlock;
9.
10.static unsigned int is_interrupt_enable()
11.{
12.        unsigned long my_eflags;
13.        asm volatile ("pushfl /n/t"
14.        "popl %0"
15.        :"=a"(my_eflags));
16.
17.        return (((my_eflags & IF_MASK) == 0) ? 0 : 1);
18.}
19.
20.static int __init init_test()
21.{
22.        unsigned long flags;
23.        spin_lock_init(&my_spinlock);
24.
25.        spin_lock_irqsave(&my_spinlock, flags);
26.        printk("from kernelspace init: interrupt was enable : %d/n", is_interrupt_enable());
27.        return 0;
28.}
29.
30.static void __exit init_exit()
31.{
32.        return;
33.}
34.
35.MODULE_LICENSE("GPL");
36.module_init(init_test);
37.module_exit(init_exit);
复制代码


编译以后生成my_spin_lock.ko

然后再写一段userspace program : test.c

1.#include <stdio.h>
2.#include <stdlib.h>
3.
4.#define IF_MASK 0x00000200
5.#define CMD_LEN 100
6.
7.unsigned int is_interrupt_enable()
8.{
9.        unsigned long my_eflags;
10.
11.        asm volatile ("pushfl /n/t"
12.        "popl %0 /n/t"
13.        :"=a"(my_eflags));
14.       
15.        return (((my_eflags & IF_MASK) == 0) ? 0 : 1);
16.}
17.
18.int main (int argc, char *argv[])
19.{
20.        if (argc != 2)
21.        {
22.                printf("usersage: insmod your_kernel_module/n");
23.                return 0;       
24.        }
25.        char cmd[CMD_LEN];
26.
27.        memset(cmd, 0, sizeof(cmd));
28.        sprintf(cmd, "insmod %s", argv[1]);
29.
30.        printf("from userspace, before insmod, inerrput is enable : %d/n", is_interrupt_enable());
31.        system(cmd); /*insmod kernel module*/
32.        printf("from userspace, after insmod, interrupt is enable : %d/n", is_interrupt_enable());       
33.
34.
35.        memset(cmd, 0, sizeof(cmd));
36.        sprintf(cmd, "rmmod %s", argv[1]);
37.        system(cmd); /*rmmod kernel module*/
38.       
39.       
40.        return 0;
41.}
复制代码


编译以后生成test二进制文件

然后下命令:

1../test my_spin_lock.ko
复制代码


运行结果:

 

QUOTE:
from userspace, before insmod, interrupt is enable : 1
from kernelspace init: interrupt was enable : 0
from userspace, after insmod, interrupt is enable: 1

 

可见,运行了kernel module的init函数以后,interrupt确实被禁止了。然后返回到用户态,interrupt被打开了。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/do2jiang/archive/2010/04/15/5487219.aspx

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多