免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
0
11 [报告]
发表于 2009-04-21 16:31 |只看该作者
原帖由 epegasus 于 2009-4-21 16:16 发表
我也试过了,cli,local_irq_save
都不行,而且是在真实机上,会不会是因为在进程上下文的原因?
对中断不了解...

我的是p4双核,加spin_lock_irqsave或是cli,而没有spin_unlock_irqrestore,sti,会有一个bug信息。不过不会死机。spin_is_locked()显示加锁成功。

而且在正常情况下,视乎也不会关时钟中断。
我在spin_lock_irqsave和spin_unlock_irqrestore之前测试jiffies是否增加,如果没有就继续loop。如果关闭中断,系统就会死机,但实际上并没有死机,而且jiffies值在增加。

论坛徽章:
0
12 [报告]
发表于 2009-04-21 16:43 |只看该作者
原帖由 richardhesidu 于 2009-4-21 16:31 发表

我的是p4双核,加spin_lock_irqsave或是cli,而没有spin_unlock_irqrestore,sti,会有一个bug信息。不过不会死机。spin_is_locked()显示加锁成功。

而且在正常情况下,视乎也不会关时钟中断。
我在spin_ ...

确实,spin_lock_irqsave在单处理器什么都不做.
不过local_irq_save和cli怎么也没用了?
我没看jiffies,我直接看我的还能否输入.

论坛徽章:
0
13 [报告]
发表于 2009-04-21 17:56 |只看该作者
哪里理解错了呢?
奇怪~

论坛徽章:
0
14 [报告]
发表于 2009-04-21 18:18 |只看该作者
原帖由 epegasus 于 2009-4-21 16:43 发表

确实,spin_lock_irqsave在单处理器什么都不做.
不过local_irq_save和cli怎么也没用了?
我没看jiffies,我直接看我的还能否输入.


UP下,关了中断,cat /proc/interrupts输出有变化吗,即中断数在增加么?

论坛徽章:
0
15 [报告]
发表于 2009-04-21 19:51 |只看该作者

回复 #14 eexplorer 的帖子

查了一下kernel source, commit 59f9415ffb9759e950d775f4c400f747b332cc02.

这个patch里会用do_one_initcall()来call module->init() function, do_one_initcall()会check local irq status, 如果loca irq 被关掉的话,它会打开

论坛徽章:
0
16 [报告]
发表于 2009-04-21 20:03 |只看该作者
原帖由 eexplorer 于 2009-4-21 19:51 发表
查了一下kernel source, commit 59f9415ffb9759e950d775f4c400f747b332cc02.

这个patch里会用do_one_initcall()来call module->init() function, do_one_initcall()会check local irq status, 如果loca irq  ...


do_one_initcall()什么时候被调用呢?

论坛徽章:
0
17 [报告]
发表于 2009-04-21 20:06 |只看该作者
原帖由 new_learner 于 2009-4-21 20:03 发表


do_one_initcall()什么时候被调用呢?


在你load module的时候,sys_init_module() -> do_one_initcall(mod->init), mod->init就是你的init_test()

论坛徽章:
0
18 [报告]
发表于 2009-04-21 21:59 |只看该作者
原帖由 eexplorer 于 2009-4-21 20:06 发表


在你load module的时候,sys_init_module() -> do_one_initcall(mod->init), mod->init就是你的init_test()

我的kernel版本是2.6.18,还没有你说的do_one_initcall()函数。
我也没有手动打过patch。

2.6.18中sys_init_module()的实现如下:

  1. /* This is where the real work happens */
  2. asmlinkage long
  3. sys_init_module(void __user *umod,
  4.                 unsigned long len,
  5.                 const char __user *uargs)
  6. {
  7.         struct module *mod;
  8.         int ret = 0;

  9.         /* Must have permission */
  10.         if (!capable(CAP_SYS_MODULE))
  11.                 return -EPERM;

  12.         /* Only one module load at a time, please */
  13.         if (mutex_lock_interruptible(&module_mutex) != 0)
  14.                 return -EINTR;

  15.         /* Do all the hard work */
  16.         mod = load_module(umod, len, uargs);
  17.         if (IS_ERR(mod)) {
  18.                 mutex_unlock(&module_mutex);
  19.                 return PTR_ERR(mod);
  20.         }

  21.         /* Now sew it into the lists.  They won't access us, since
  22.            strong_try_module_get() will fail. */
  23.         stop_machine_run(__link_module, mod, NR_CPUS);

  24.         /* Drop lock so they can recurse */
  25.         mutex_unlock(&module_mutex);

  26.         blocking_notifier_call_chain(&module_notify_list,
  27.                         MODULE_STATE_COMING, mod);

  28.         /* Start the module */
  29.         if (mod->init != NULL)
  30.                 ret = mod->init();  /*这里是我自己的module的init函数吧?如果在这里关闭了中断,后面的代码没有看到有重新打开中断的地方。。。*/
  31.         if (ret < 0) {
  32.                 /* Init routine failed: abort.  Try to protect us from
  33.                    buggy refcounters. */
  34.                 mod->state = MODULE_STATE_GOING;
  35.                 synchronize_sched();
  36.                 if (mod->unsafe)
  37.                         printk(KERN_ERR "%s: module is now stuck!\n",
  38.                                mod->name);
  39.                 else {
  40.                         module_put(mod);
  41.                         mutex_lock(&module_mutex);
  42.                         free_module(mod);
  43.                         mutex_unlock(&module_mutex);
  44.                 }
  45.                 return ret;
  46.         }

  47.         /* Now it's a first class citizen! */
  48.         mutex_lock(&module_mutex);
  49.         mod->state = MODULE_STATE_LIVE;
  50.         /* Drop initial reference. */
  51.         module_put(mod);
  52.         unwind_remove_table(mod->unwind_info, 1);
  53.         module_free(mod, mod->module_init);
  54.         mod->module_init = NULL;
  55.         mod->init_size = 0;
  56.         mod->init_text_size = 0;
  57.         mutex_unlock(&module_mutex);

  58.         return 0;
  59. }
复制代码

其中,代码

  1. ret = mod->init();
复制代码

是在执行我写的module的init函数吧,如果我在init里关闭了中断,在mod->init()的后面我没有看到有其他地方重新打开中断啊?

请指教...

论坛徽章:
0
19 [报告]
发表于 2009-04-21 22:58 |只看该作者

回复 #18 new_learner 的帖子

终于想到原因了

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

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

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

感觉有道理。。。。
多谢!
明天我再验证一下:)
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP