免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5081 | 回复: 13
打印 上一主题 下一主题

vfree为什么会引起睡眠? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-12-19 11:43 |只看该作者 |倒序浏览
在vfree内核源码里找不到引起睡眠的地方啊,恳请高人告知。

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
2 [报告]
发表于 2008-12-19 12:04 |只看该作者
LDD2上说vmalloc可能睡眠

论坛徽章:
0
3 [报告]
发表于 2008-12-19 14:44 |只看该作者
LKD2 上也说 vmalloc 和 vfree 可能会睡眠,不能在中断上下文中调用,我也想知道是为什么

所以看了一下代码,发现 在 mm/vmalloc.c 中,vfree 是这样实现的:


void vfree(const void *addr)
{
        BUG_ON(in_interrupt());
        __vunmap(addr, 1);
}
EXPORT_SYMBOL(vfree);


再看 __vunmap , 它是这样的:
static void __vunmap(const void *addr, int deallocate_pages)
{
        struct vm_struct *area;

        if (!addr)
                return;

        if ((PAGE_SIZE-1) & (unsigned long)addr) {
                WARN(1, KERN_ERR "Trying to vfree() bad address (%p)\n", addr);
                return;
        }

        area = remove_vm_area(addr);
        if (unlikely(!area)) {
                WARN(1, KERN_ERR "Trying to vfree() nonexistent vm area (%p)\n",
                addr);
                return;
        }

        debug_check_no_locks_freed(addr, area->size);
        debug_check_no_obj_freed(addr, area->size);

        if (deallocate_pages) {
                int i;

                for (i = 0; i < area->nr_pages; i++) {
                        struct page *page = area->pages[i];

                        BUG_ON(!page);
                        __free_page(page);
                }

                if (area->flags & VM_VPAGES)
                        vfree(area->pages);
                else
                        kfree(area->pages);
        }

        kfree(area);
        return;
}


接着看 area = remove_vm_area(addr); 这一句, remove_vm_area():

struct vm_struct *remove_vm_area(const void *addr)
{
        struct vm_struct *v;
        write_lock(&vmlist_lock);
        v = __remove_vm_area(addr);
        write_unlock(&vmlist_lock);
        return v;
}


就是这个函数里,用了一个 write_lock,如果别人持有这把锁的话,在进锁的时候就会休眠了吧?


第一次在内核版发贴,呵呵

论坛徽章:
0
4 [报告]
发表于 2008-12-19 15:22 |只看该作者

回复 #3 windaoo 的帖子

sorry ,上面的 write_lock() 锁是自旋锁,应该不会睡眠
我也很想知道这个问题的真正原因

论坛徽章:
0
5 [报告]
发表于 2008-12-19 15:47 |只看该作者
mail list中有一个这个,说vfree不会睡眠。

http://lkml.indiana.edu/hypermail/linux/kernel/0411.2/1955.html

论坛徽章:
0
6 [报告]
发表于 2008-12-19 18:07 |只看该作者

回复 #3 windaoo 的帖子

这位师兄贴出来的是2.6.26的内核代码吧。

2.6引入了很多更高效的数据结构,为什么vm空间的管理还是用链表,感觉还有待优化。

[ 本帖最后由 NewCore 于 2008-12-19 18:11 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2008-12-19 18:20 |只看该作者
原帖由 scutan 于 2008-12-19 15:47 发表
mail list中有一个这个,说vfree不会睡眠。

http://lkml.indiana.edu/hypermail/linux/kernel/0411.2/1955.html


可是书上说 vfree 会睡眠,而且我这份代码的 vfree 前面的注释这样写:

/**
*        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(const void *addr)
{
        BUG_ON(in_interrupt());
        __vunmap(addr, 1);
}
EXPORT_SYMBOL(vfree);

代码注释里说 不能 在中断上下文中使用


原帖由 NewCore 于 2008-12-19 18:07 发表
这位师兄贴出来的是2.6.26的内核代码吧。

2.6引入了很多更高效的数据结构,为什么vm空间的管理还是用链表,感觉还有待优化。



我这个是 2.6.27 的代码

论坛徽章:
0
8 [报告]
发表于 2008-12-20 12:53 |只看该作者

回复 #7 windaoo 的帖子

突然想到,vfree 之所以不能在中断上下文中使用,应该就是因为那个 write_lock() 了
假如在中断上下文可以使用 vfree 的话,假设这样一个情况:
一个线程正好持有了这把锁,而这时候中断到来了,也要调 vfree ,想要得到这把锁——因为中断处理程序不能被重新调度,所以被中断的、执有这个锁的线程也得不到释放的机会——那么中断处理程序就会一直等待下去,从而造成死锁

不知道这样分析对否?

论坛徽章:
0
9 [报告]
发表于 2008-12-20 14:57 |只看该作者
等vm多了之后会换成红黑树,6l不必担心啦

论坛徽章:
0
10 [报告]
发表于 2008-12-20 15:02 |只看该作者
我想内核代码应该保证在中断上下文不会被抢占吧,lss解释似乎不合理
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP