Chinaunix首页 | 论坛 | 博客
  • 博客访问: 302049
  • 博文数量: 47
  • 博客积分: 1411
  • 博客等级: 上尉
  • 技术积分: 500
  • 用 户 组: 普通用户
  • 注册时间: 2006-02-23 09:10
文章分类

全部博文(47)

文章存档

2009年(3)

2008年(4)

2007年(14)

2006年(26)

我的朋友

分类: LINUX

2006-12-19 21:35:09

 
ioctl在linux系统中属于原子操作, 实际就是带锁的操作.
在写内核或驱动时,使用ioctl和应用层交互要比/proc来得安全的多.
以下是对ioctl原子性的代码分析:

1) do_ioctl, 用户层调用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 ;
}

2) lock_kernel 看看如何加锁

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));
}
}
阅读(2683) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~