免费注册 查看新帖 |

Chinaunix

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

[内核同步] file,dentry,inode 释放时都要rcu释放? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-04-27 18:49 |显示全部楼层 |倒序浏览
struct file {
        union {
                struct list_head        fu_list;  //node of super_block->s_files list
                struct rcu_head         fu_rcuhead;
        } f_u;
}

struct dentry {
        union {
                struct list_head d_child;        //child node of parent list(dentry->d_subdirs)
                 struct rcu_head d_rcu;
        } d_u;
}

struct inode {
        union {
                struct list_head        i_dentry;   //list of alias dentries(dentry->d_alias)
                struct rcu_head                i_rcu;
        };
}

file,dentry,inode释放时都通过rcu释放的。
比如:
static inline void file_free(struct file *f)
{
        percpu_counter_dec(&nr_files);
        file_check_state(f);
        call_rcu(&f->f_u.fu_rcuhead, file_free_rcu);
}

file_free_rcu将会把filp释放到slab。

为什么要延迟释放呢,难道有其他地方还在引用filp,但是我实在想不出来有哪些情况还会用到它啊。

还请高手解释下。




论坛徽章:
0
2 [报告]
发表于 2012-04-28 09:54 |显示全部楼层
为什么发帖都没人理呢?
好多贴都是十层大海了,伤心了。

论坛徽章:
0
3 [报告]
发表于 2012-04-28 14:34 |显示全部楼层
本帖最后由 blake326 于 2012-04-28 14:36 编辑

回复 3# GFree_Wind


   void fput(struct file *file)
{
        if (atomic_long_dec_and_test(&file->f_count))
                __fput(file);
}
static void __fput(struct file *file)
{
        file_free(file);
}
static inline void file_free_rcu(struct rcu_head *head)
{
        struct file *f = container_of(head, struct file, f_u.fu_rcuhead);

        put_cred(f->f_cred);
        kmem_cache_free(filp_cachep, f);
}

static inline void file_free(struct file *f)
{
        percpu_counter_dec(&nr_files);
        file_check_state(f);
        call_rcu(&f->f_u.fu_rcuhead, file_free_rcu);
}

一般一个内核路径打开一个file初始化f_count=1,close的时候f_count=0,然后释放,这个时候管它什么共享的子进程,父进程的时候,f_count=0,了,大家都不用它了,谁还会访问它.这个时候直接释放到slab cache有何不可呢?


并且,我也没有看出file变量是rcu变量,因为本身修改file的某个属性时,并没有先去拷贝它然后再修改什么的。

论坛徽章:
0
4 [报告]
发表于 2012-04-28 15:22 |显示全部楼层
这个改动大概是2.6.14加进来的。

同struct files_struct ->        struct fdtable __rcu *fdt 的改动一起过来的。
http://git.kernel.org/?p=linux/k ... 30f09cce577b03f43ef

大概理解了一下:
1. 首先打开了一个tempfile文件。f_count=1
2. 然后打开x个文件。
3. 内核路径A  通过rcu 读取了fdt结构,遍历其所有file结构体,并且很磨蹭需要持续一段时间。。。
4. 又打开y个文件,fdt需要expand_fdtable,rcu设置了新的fdt指针(所有旧的file指针被拷贝到新的fdt中了)。(旧的fdt通过call_rcu延迟释放)
5. 通过新的fdt指针,close tempfile,f_count=0,释放file!!!! 此时内核路径A仍然在访问该file,所以此时必须rcu延迟释放。
6. 内核路径A,终于磨蹭结束了。
7. 等待时机最终rcu释放file。

看来我对rcu的理解还是很差啊。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP