免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2180 | 回复: 2

[内核同步] 内核为什么为slab引入SLAB_DESTROY_BY_RCU? [复制链接]

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
发表于 2015-08-14 12:20 |显示全部楼层
内核为什么为slab引入SLAB_DESTROY_BY_RCU?

SLAB_DESTROY_BY_RCU的定义前面有一大推WARNING:
/*
* SLAB_DESTROY_BY_RCU - **WARNING** READ THIS!
*
* This delays freeing the SLAB page by a grace period, it does _NOT_
* delay object freeing. This means that if you do kmem_cache_free()
* that memory location is free to be reused at any time. Thus it may
* be possible to see another object there in the same RCU grace period.

里面明确的说了,它不会delay object freeing.
也就是说,任何刚被free的object都有可能在同一个grace period内被重新分配用来表示另外一个object。

但reused at any time这个特征,应该并不是SLAB_DESTROY_BY_RCU特有的吧?
就算不指定SLAB_DESTROY_BY_RCU,由于slab/slub都有各级cache(per cpu或者node list),也是同样的行为吧?

那SLAB_DESTROY_BY_RCU的意义在哪里?引入这个标记一定是为了解决什么问题吧?

从代码上看,SLAB_DESTROY_BY_RCU只影响slab_destory,但并不是所有的free都会触发destory。
当然,有一点是对的,SLAB_DESTROY_BY_RCU可以保证在grace period结束之前,slab占用的page不会归还给系统而被挪作它用。
/* This feature only ensures the memory location backing the object
* stays valid, the trick to using this is relying on an independent
* object validation pass.

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
发表于 2015-08-14 14:15 |显示全部楼层
本帖最后由 nswcfd 于 2015-08-14 14:22 编辑

找到一个相关的帖子,http://lwn.net/Articles/189044/

1. 每个对象一个rcu_callback,大量对象的时候,增大了rcu子系统的延迟。
2. 被free的对象只有经过grace period之后才能被重用,严重降低了cache hotness。

不过这也引入了新的问题,就是前面提到的reused at any time。

仔细想了一下,应该是对象释放的方法不一样:
a. 非SLAB_DESTROY_BY_RCU,每个对象里面嵌一个rcu_head,使用rcu_callback的方式去释放对象。
b. SLAB_DESTROY_BY_RCU,按传统的方式释放对象,不需要rcu_callback,但相应的,增加了查找的复杂度。

/*
*  rcu_read_lock()
* again:
*  obj = lockless_lookup(key);
*  if (obj) {
*    if (!try_get_ref(obj)) // might fail for free objects
*      goto again;
*
*    if (obj->key != key) { // not the object we expected
*      put_ref(obj);
*      goto again;
*    }
*  }
*  rcu_read_unlock();
*/
其中,查找以后对obj->key再做一次检查,就是为了检测出reused at any time的情况。即lockless_lookup找到之后,obj又被其它CPU释放并快速重新分配给另外一个obj用了(key不同)。
非SLAB_DESTROY_BY_RCU不需要再次检查,因为被释放的对象,只有经过grace period之后才会真的释放并被重用。

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
发表于 2015-08-14 15:45 |显示全部楼层
再补充一个:http://lwn.net/Articles/418853/

Quick Quiz 7: Why would anyone need to distinguish lists based on their NULL pointers? Why not just remember which list you started searching???

A major advantage of hlist-nulls lists is that updaters can free elements to SLAB_DESTROY_BY_RCU slab caches without waiting for an RCU grace period to elapse. However, readers must be extremely careful when traversing such lists: Not only must they conduct their searches within a single RCU read-side critical section, but because any element might be freed and then reallocated at any time, readers must also validate each element that they encounter during their traversal.

Quick Quiz 7: Why would anyone need to distinguish lists based on their NULL pointers? Why not just remember which list you started searching???

Answer: Suppose that CPU 0 is traversing such a list within an RCU read-side critical section, where the elements are allocated from SLAB_DESTROY_BY_RCU slab cache. The elements could therefore be freed and reallocated at any time. If CPU 0 is referencing an element while CPU 1 is freeing that element, and if CPU 1 then quickly reallocates that same element and adds it to some other list, then CPU 0 will be transported to that new list along with the element. In this case, remembering the starting list would clearly be unhelpful.

To make matters worse, suppose that CPU 0 searches a list and fails to find the element that it was looking for. Was that because the element did not exist? Or because CPU 0 got transported to some other list in the meantime? Readers traversing SLAB_DESTROY_BY_RCU lists must carefully validate each element and check for being moved to another list. One way to check for being moved to another list is for each list to have its own value for the NULL pointer. These checks are subtle and easy to get wrong, so please be careful!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP