加入收藏 | 设为首页 | 会员中心 | 我要投稿 淮北站长网 (https://www.0561zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 运营中心 > 交互 > 正文

深入理解RCU实现

发布时间:2016-11-01 18:25:30 所属栏目:交互 来源:站长网
导读:副标题#e# 深入理解RCU实现 ——基于 内核2.6.21 RCU实现(lvyilong316) RCU(Read-Copy Update),顾名思义就是读-拷贝修改,它是基于其原理命名的。对于被RCU保护的共享数据结构, 读者不需要获得任何锁就可以访问它,但写者在访问它时首先拷贝一个副本,然

                                call_rcu(&e->rcu, audit_free_rule, e);

                                return 0;

                        }

                }

                return -EFAULT;         /* No matching rule */

        }

        static inline int audit_add_rule(struct audit_entry *entry,

                                         struct list_head *list)

        {

                if (entry->rule.flags & AUDIT_PREPEND) {

                        entry->rule.flags &= ~AUDIT_PREPEND;

                        list_add_rcu(&entry->list, list);

                } else {

                        list_add_tail_rcu(&entry->list, list);

                }

                return 0;

        }

    对于链表删除操作,list_del替换为list_del_rcu和call_rcu,这是因为被删除的链表项可能还在被别的读者引用,所以不能立即删除,必须等到所有读者经历一个quiescent state才可以删除。另外,list_for_each_entry并没有被替换为list_for_each_entry_rcu,这是因为,只有一个写者在做链表删除操作,因此没有必要使用_rcu版本。

    通常情况下,write_lock和write_unlock应当分别替换成spin_lock和spin_unlock,但是对于只是对链表进行增加和删除操作而且只有一个写者的写端,在使用了_rcu版本的链表操作API后,rwlock可以完全消除,不需要spinlock来同步读者的访问。对于上面的例子, 由于已经有audit_netlink_sem被调用者保持,所以spinlock就没有必要了。

    这种情况允许修改结果延后一定时间才可见,而且写者对链表仅仅做增加和删除操作,所以转换成使用RCU非常容易。

写端需要对链表条目进行修改操作

    如果写者需要对链表条目进行修改,那么就需要首先拷贝要修改的条目,然后修改条目的拷贝,等修改完毕后,再使用条目拷贝取代要修改的条目,要修改条目将被在经历一个grace period后安全删除。

    对于系统调用审计代码,并没有这种情况。这里假设有修改的情况,那么使用rwlock的修改代码应当如下:

       static inline int audit_upd_rule(struct audit_rule *rule,

                                         struct list_head *list,

                                         __u32 newaction,

                                         __u32 newfield_count)

        {

                struct audit_entry  *e;

                struct audit_newentry *ne;

                write_lock(&auditsc_lock);

                /* Note: audit_netlink_sem held by caller. */

                list_for_each_entry(e, list, list) {

(编辑:淮北站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读