+ -
当前位置:首页 → 问答吧 → vfree 函数导致的oops

vfree 函数导致的oops

时间:2010-08-31

来源:互联网

调用vfree 的代码大致为:
  1. spin_lock_bh(&sip_lock);
  2. ...release hash table...
  3. vfree(hash table);
  4. spin_unlock_bh(&sip_lock);
复制代码
这段代码是在卸载模块时执行的,oops 信息为


QUOTE:
Pid: 6622, comm: rmmod Not tainted (2.6.24.4 #33)
EIP: 0060:[<c01637e2>] EFLAGS: 00010206 CPU: 1
EIP is at vfree+0x12/0x22
EAX: d30f7000 EBX: d8af6f80 ECX: d8a77000 EDX: 0000001a
ESI: 0007ff88 EDI: 0000fff1 EBP: d30f7000 ESP: d30f7f40
DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
Process rmmod (pid: 6622, ti=d30f7000 task=d5024580 task.ti=d30f7000)
Stack: d89f34f6 c01371d3 d79d2b00 c0145963 d89f4700 00000000 bf81c930 c0143daa
       69746e61 7474615f 006b7461 c014b4e6 bf81c930 00000081 40000003 d5024580
       bf81f178 00000880 00000000 d30f7fb8 c0107a16 00000880 0081f178 d89f4700



然后看一下vfree的代码


QUOTE:
/**
*        vfree  -  release memory allocated by vmalloc()
*        @addr:                memory base address
*
*        Free the virtually continuous memory area starting at @addr, as
*        obtained from vmalloc(), vmalloc_32() or __vmalloc(). If @addr is
*        NULL, no operation is performed.
*
*        Must not be called in interrupt context.
*/
void vfree(void *addr)
{
        BUG_ON(in_interrupt());
        __vunmap(addr, 1);
}



根据报错的位置,应该是第一行代码BUG_ON报错的错误,所以我就将前面调用vfree的代码修改如下:
  1. spin_lock_bh(&sip_lock);
  2. ...release hash table...
  3. spin_unlock_bh(&sip_lock);
  4. vfree(hash table);
复制代码
也就是将释放hash表头的动作放在锁的外面执行,就没有问题了。
根据vfree的注释,不能再中断上下文调用,我这里应该不是中断上下啊

作者: Godbach   发布时间: 2010-08-31

回复 Godbach

spin_lock_bh, you are in the bottom half context which in_interrupt() covers.

作者: eexplorer   发布时间: 2010-08-31

多谢LS的解释。意思就是我的调用环境是在中断上下文

作者: Godbach   发布时间: 2010-08-31

本帖最后由 smalloc 于 2010-08-31 23:47 编辑

不能在中断上下文的原因这里有解释.
http://linux.chinaunix.net/bbs/viewthread.php?tid=1128726
看来不是多处理器的情况下还是可以的
估计禁止了BH也是能导致这种死锁的,所以就检查的BH禁止计数.

作者: smalloc   发布时间: 2010-08-31