全部博文(47)
分类: LINUX
2006-12-19 21:35:09
ioctl在linux系统中属于原子操作, 实际就是带锁的操作.
在写内核或驱动时,使用ioctl和应用层交互要比/proc来得安全的多.
以下是对ioctl原子性的代码分析:
static long (struct *, unsigned int ,
unsigned long )
{
int = -;
if (!->f_op)
goto ;
/**
* kernel 里有unlocked ioctl, 不加锁的ioctl,
* kernel 会先check file_operations 里是否有不加锁ioctl,
* 有则优先调用
*/
if (->f_op->unlocked_ioctl) {
= ->f_op->unlocked_ioctl(, , );
if ( == -)
= -;
goto ;
} else if (->f_op->) {
/* 一般情况调用到这里: */
/* lock_kernel 调用ioctl之前加锁 */
();
/* 调用ioctl */
= ->f_op->(->f_dentry->d_inode,
, , );
/* 解锁 */
();
}
:
return ;
}
static inline void __lock_kernel(void)
{
/**
* 禁止内核抢占, 实际上是增加当前线程结构中的
* 抢占记数 current_thread_info()->
* 不一定能真正disable preempt
*/
();
if ((!(&kernel_flag))) {
/*
* If preemption was disabled even before this
* was called, there's nothing we can be polite
* about - just spin.
*/
/**
* 如果获得spin lock失败, 则检查抢占记数,
* 如果抢占被禁止, 则直接等待对kernel_flag加锁
*/
if (() > 1) {
(&kernel_flag);
return;
}
/*
* Otherwise, let's wait for the kernel lock
* with preemption enabled..
*/
/**
* 如果抢占未被禁止, 则减少抢占记数, 使能抢占,
* 等待kernel_flag锁被释放. 不过这里的等待可以被抢占
* 释放CPU给其他内核路径
*/
do {
();
while ((&kernel_flag))
(); /* 可以被抢占 */
();
} while (!(&kernel_flag));
}
}