为什么我的spin_lock_irqsave()没有锁住时钟中断?
2013-04-15 23:03
555 查看
尝试用spin_lock_irqsave(),发现没有禁掉时钟中断,不知道我哪里理解错了?
kernel版本:
uname -a 结果:
Linux localhost.localdomain 2.6.18 #1 Sat Jul 19 13:06:00 EDT 2008 i686 i686 i386 GNU/Linux
复制代码
我的代码:
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/spinlock.h>
static spinlock_t my_spinlock;
static int __init init_test()
{
unsigned long flags;
spin_lock_init(&my_spinlock);
spin_lock_irqsave(&my_spinlock, flags);
return 0;
}
static void __exit init_exit()
{
return;
}
module_init(init_test);
module_exit(init_exit);
复制代码
加载module以后,通过这样的命令查看墙上时钟:
#date; sleep 2; date
输出结果:
Sun Apr 19 12:59:42 EDT 2009
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
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#define IF_MASK 0x00000200
static spinlock_t my_spinlock;
static unsigned int is_interrupt_enable()
{
unsigned long my_eflags;
asm volatile ("pushfl /n/t"
"popl %0"
:"=a"(my_eflags));
return (((my_eflags & IF_MASK) == 0) ? 0 : 1);
}
static int __init init_test()
{
unsigned long flags;
spin_lock_init(&my_spinlock);
spin_lock_irqsave(&my_spinlock, flags);
printk("from kernelspace init: interrupt was enable : %d/n", is_interrupt_enable());
return 0;
}
static void __exit init_exit()
{
return;
}
MODULE_LICENSE("GPL");
module_init(init_test);
module_exit(init_exit);
复制代码
编译以后生成my_spin_lock.ko
然后再写一段userspace program : test.c
#include <stdio.h>
#include <stdlib.h>
#define IF_MASK 0x00000200
#define CMD_LEN 100
unsigned int is_interrupt_enable()
{
unsigned long my_eflags;
asm volatile ("pushfl /n/t"
"popl %0 /n/t"
:"=a"(my_eflags));
return (((my_eflags & IF_MASK) == 0) ? 0 : 1);
}
int main (int argc, char *argv[])
{
if (argc != 2)
{
printf("usersage: insmod your_kernel_module/n");
return 0;
}
char cmd[CMD_LEN];
memset(cmd, 0, sizeof(cmd));
sprintf(cmd, "insmod %s", argv[1]);
printf("from userspace, before insmod, inerrput is enable : %d/n", is_interrupt_enable());
system(cmd); /*insmod kernel module*/
printf("from userspace, after insmod, interrupt is enable : %d/n", is_interrupt_enable());
memset(cmd, 0, sizeof(cmd));
sprintf(cmd, "rmmod %s", argv[1]);
system(cmd); /*rmmod kernel module*/
return 0;
}
复制代码
编译以后生成test二进制文件
然后下命令:
./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被打开了。
kernel版本:
uname -a 结果:
Linux localhost.localdomain 2.6.18 #1 Sat Jul 19 13:06:00 EDT 2008 i686 i686 i386 GNU/Linux
复制代码
我的代码:
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/spinlock.h>
static spinlock_t my_spinlock;
static int __init init_test()
{
unsigned long flags;
spin_lock_init(&my_spinlock);
spin_lock_irqsave(&my_spinlock, flags);
return 0;
}
static void __exit init_exit()
{
return;
}
module_init(init_test);
module_exit(init_exit);
复制代码
加载module以后,通过这样的命令查看墙上时钟:
#date; sleep 2; date
输出结果:
Sun Apr 19 12:59:42 EDT 2009
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
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#define IF_MASK 0x00000200
static spinlock_t my_spinlock;
static unsigned int is_interrupt_enable()
{
unsigned long my_eflags;
asm volatile ("pushfl /n/t"
"popl %0"
:"=a"(my_eflags));
return (((my_eflags & IF_MASK) == 0) ? 0 : 1);
}
static int __init init_test()
{
unsigned long flags;
spin_lock_init(&my_spinlock);
spin_lock_irqsave(&my_spinlock, flags);
printk("from kernelspace init: interrupt was enable : %d/n", is_interrupt_enable());
return 0;
}
static void __exit init_exit()
{
return;
}
MODULE_LICENSE("GPL");
module_init(init_test);
module_exit(init_exit);
复制代码
编译以后生成my_spin_lock.ko
然后再写一段userspace program : test.c
#include <stdio.h>
#include <stdlib.h>
#define IF_MASK 0x00000200
#define CMD_LEN 100
unsigned int is_interrupt_enable()
{
unsigned long my_eflags;
asm volatile ("pushfl /n/t"
"popl %0 /n/t"
:"=a"(my_eflags));
return (((my_eflags & IF_MASK) == 0) ? 0 : 1);
}
int main (int argc, char *argv[])
{
if (argc != 2)
{
printf("usersage: insmod your_kernel_module/n");
return 0;
}
char cmd[CMD_LEN];
memset(cmd, 0, sizeof(cmd));
sprintf(cmd, "insmod %s", argv[1]);
printf("from userspace, before insmod, inerrput is enable : %d/n", is_interrupt_enable());
system(cmd); /*insmod kernel module*/
printf("from userspace, after insmod, interrupt is enable : %d/n", is_interrupt_enable());
memset(cmd, 0, sizeof(cmd));
sprintf(cmd, "rmmod %s", argv[1]);
system(cmd); /*rmmod kernel module*/
return 0;
}
复制代码
编译以后生成test二进制文件
然后下命令:
./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被打开了。
相关文章推荐
- [理解] 为什么我的spin_lock_irqsave()没有锁住时钟中断?
- spin_lock_irqsave关中断后,为什么要再禁止抢占呢,不多余吗?
- spin_lock_irqsave关中断后,为什么要再禁止抢占
- spin_lock_irqsave ----由bluesleep module 带来的tip
- Linux内核spin_lock、spin_lock_irq 和 spin_lock_irqsave
- 【转】那些情况该使用它们spin_lock到spin_lock_irqsave
- 那些情况该使用它们spin_lock到spin_lock_irqsave
- 【转】那些情况该使用它们spin_lock到spin_lock_irqsave
- 从spin_lock到spin_lock_irqsave
- 从spin_lock到spin_lock_irqsave
- 互斥锁 spin_lock < spin_lock_bh < spin_lock_irq < spin_lock_irqsave
- STM32系统时钟为什么没有定义呢
- Linux内核spin_lock、spin_lock_irq、spin_lock_irqsave
- spin_lock_irq和spin_lock_irqsave
- STM32系统时钟为什么没有定义呢
- 为什么CPU时钟频率在过去5年里没有增加?
- spin_lock 和 spin_lock_irqsave
- spin_lock, spin_lock_irq and spin_lock_irqsave
- spin_lock和spin_lock_irqsave
- 从spin_lock到spin_lock_irqsave