免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: new_learner
打印 上一主题 下一主题

为什么我的spin_lock_irqsave()没有锁住时钟中断? [复制链接]

论坛徽章:
0
21 [报告]
发表于 2009-04-22 09:32 |只看该作者
原帖由 eexplorer 于 2009-4-21 22:58 发表
终于想到原因了

由于load module是通过系统调用实现的,当运行完mod->init()后,会从kernel space返回到user space。这时会将所有的寄存器恢复到系统调用前的状态,也就是insmod 进程调用sys_init_module之 ...



我有新的问题.
i386下cli指令是修改IF标志来达到屏蔽中断的目的.
在local_irq_save()和2.4的cli()中都是用的cli指令.
那为什么<lkd2>中断一章说,
"以前的内核中提供一种能够禁止系统中所有处理器的中断的方法,这个函数就是cli()".
那cli指令怎么能实现关所有处理器中断呢?

还有就是可能是新的处理器引入的VIF标志做什么用?

论坛徽章:
0
22 [报告]
发表于 2009-04-22 09:55 |只看该作者
原帖由 epegasus 于 2009-4-22 09:32 发表



我有新的问题.
i386下cli指令是修改IF标志来达到屏蔽中断的目的.
在local_irq_save()和2.4的cli()中都是用的cli指令.
那为什么中断一章说,
"以前的内核中提供一种能够禁止系统中所有处理器 ...


这个cli()函数是怎么实现的呢?有代码吗?

论坛徽章:
0
23 [报告]
发表于 2009-04-22 10:01 |只看该作者
原帖由 new_learner 于 2009-4-22 09:55 发表


这个cli()函数是怎么实现的呢?有代码吗?

2.4中,\include\asm-i386\system.h
#define __cli()                 __asm__ __volatile__("cli": : :"memory")
#define __sti()                        __asm__ __volatile__("sti": : :"memory")

intel 2a 卷

If protected-mode virtual interrupts are not enabled, CLI clears the IF flag in the
EFLAGS register. No other flags are affected. Clearing the IF flag causes the
processor to ignore maskable external interrupts. The IF flag and the CLI and STI
instruction have no affect on the generation of exceptions and NMI interrupts.
When protected-mode virtual interrupts are enabled, CPL is 3, and IOPL is less than
3; CLI clears the VIF flag in the EFLAGS register, leaving IF unaffected. Table 3-6 indi-
cates the action of the CLI instruction depending on the processor operating mode
and the CPL/IOPL of the running program or procedure.

论坛徽章:
0
24 [报告]
发表于 2009-04-22 10:04 |只看该作者
protected-mode virtual interrupts是个什么概念,做什么用的

论坛徽章:
0
25 [报告]
发表于 2009-04-22 11:23 |只看该作者

回复 #23 epegasus 的帖子

> 2.4中,\include\asm-i386\system.h
> #define __cli()                 __asm__ __volatile__("cli": : :"memory")
> #define __sti()                        __asm__ __volatile__("sti": : :"memory")

这个是UP的定义,SMP的定义是#define cli() __global_cli()

VIF,不太清楚,已经很久没看intel的手册了。是不是和virtualization相关?

论坛徽章:
0
26 [报告]
发表于 2009-04-22 16:18 |只看该作者
原帖由 new_learner 于 2009-4-21 23:24 发表

感觉有道理。。。。
多谢!
明天我再验证一下:)


写了一段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. #define IF_MASK 0x00000200

  6. static spinlock_t my_spinlock;

  7. static unsigned int is_interrupt_enable()
  8. {
  9.         unsigned long my_eflags;
  10.         asm volatile ("pushfl \n\t"
  11.         "popl %0"
  12.         :"=a"(my_eflags));

  13.         return (((my_eflags & IF_MASK) == 0) ? 0 : 1);
  14. }

  15. static int __init init_test()
  16. {
  17.         unsigned long flags;
  18.         spin_lock_init(&my_spinlock);

  19.         spin_lock_irqsave(&my_spinlock, flags);
  20.         printk("from kernelspace init: interrupt was enable : %d\n", is_interrupt_enable());
  21.         return 0;
  22. }

  23. static void __exit init_exit()
  24. {
  25.         return;
  26. }

  27. MODULE_LICENSE("GPL");
  28. module_init(init_test);
  29. module_exit(init_exit);
复制代码


编译以后生成my_spin_lock.ko

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

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. #define IF_MASK 0x00000200
  4. #define CMD_LEN 100

  5. unsigned int is_interrupt_enable()
  6. {
  7.         unsigned long my_eflags;

  8.         asm volatile ("pushfl \n\t"
  9.         "popl %0 \n\t"
  10.         :"=a"(my_eflags));
  11.        
  12.         return (((my_eflags & IF_MASK) == 0) ? 0 : 1);
  13. }

  14. int main (int argc, char *argv[])
  15. {
  16.         if (argc != 2)
  17.         {
  18.                 printf("usersage: insmod your_kernel_module\n");
  19.                 return 0;       
  20.         }
  21.         char cmd[CMD_LEN];

  22.         memset(cmd, 0, sizeof(cmd));
  23.         sprintf(cmd, "insmod %s", argv[1]);

  24.         printf("from userspace, before insmod, inerrput is enable : %d\n", is_interrupt_enable());
  25.         system(cmd); /*insmod kernel module*/
  26.         printf("from userspace, after insmod, interrupt is enable : %d\n", is_interrupt_enable());       


  27.         memset(cmd, 0, sizeof(cmd));
  28.         sprintf(cmd, "rmmod %s", argv[1]);
  29.         system(cmd); /*rmmod kernel module*/
  30.        
  31.        
  32.         return 0;
  33. }
复制代码


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

然后下命令:

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


运行结果:
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被打开了。

[ 本帖最后由 new_learner 于 2009-4-22 16:22 编辑 ]

论坛徽章:
0
27 [报告]
发表于 2009-04-22 16:29 |只看该作者
原帖由 eexplorer 于 2009-4-21 22:58 发表
终于想到原因了

由于load module是通过系统调用实现的,当运行完mod->init()后,会从kernel space返回到user space。这时会将所有的寄存器恢复到系统调用前的状态,也就是insmod 进程调用sys_init_module之 ...


恩,觉得这个有道理
在我之前有人用了loca_irq_save禁了中断,我又禁用了一次中断,
后来虽然我没有开中断,但是前面那个人开启了中断,
最后中断还是打开的

而“前面那个人”有可能是外层调用local_irq_save的函数
也有可能是通过陷阱门进出内核空间时保存恢复eflags这个动作。

是这么个意思么

论坛徽章:
0
28 [报告]
发表于 2009-04-22 16:33 |只看该作者
原帖由 peimichael 于 2009-4-22 16:29 发表


恩,觉得这个有道理
在我之前有人用了loca_irq_save禁了中断,我又禁用了一次中断,
后来虽然我没有开中断,但是前面那个人开启了中断,
最后中断还是打开的

而“前面那个人”有可能是外层调用local_ ...

1.关中断不会嵌套
不论前面连续关多少次,后面只要开一次就行了。

2.在我实验的例子里,就是这个意思。

论坛徽章:
0
29 [报告]
发表于 2009-04-22 16:46 |只看该作者
原帖由 new_learner 于 2009-4-22 16:18 发表


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

kernel module: my_spin_lock.c

#include
#include
#include
#include

#define IF_MASK 0x00000200

static spinlock_t my_spinlock ...


LZ的学习激情很高啊,觉得自己老了,很懒,学什么都提不起劲了。。。

论坛徽章:
0
30 [报告]
发表于 2009-04-22 16:50 |只看该作者
原帖由 eexplorer 于 2009-4-22 16:46 发表


LZ的学习激情很高啊,觉得自己老了,很懒,学什么都提不起劲了。。。

偶太菜了,啥都不懂,当然要多学学了。。。^_^
有问题请您多指教啊:)
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP