当前位置: 首页 > news >正文

rt-linux下__slab_alloc里的另外一处可能睡眠的逻辑

一、背景

在之前的博客 tasklet上下文内存分配触发might_alloc检查及同步回收调用链
里,我们讲了一处内存分配时会引起睡眠的调用链(这个引起睡眠的这个调用链它是在普通linux里也是存在的)。这篇博客里,我们讲一处内存分配路径下在rt-linux下会出现睡眠的另外一处调用链。

我们在第二章里说明一下这处调用链,在第三章里,拓展说一下,rt-linux内核里的这种内存分配路径下的睡眠和唤醒逻辑所造成的一些调度有关的一些问题。

二、rt-linux下__slab_alloc里的另外一处可能睡眠的调用链

这个另外一处可能睡眠的调用链是一处使用锁的调用,在rt-linux下普通spinlock也是会引起睡眠的。

2.1 rt-linux下__slab_alloc里加锁的地方

rt-linux下__slab_alloc里的这另外一处可能睡眠的调用链所导致的一次warning的calltrace的打印里的部分调用链如下:

现在的内核版本基本都是使用的CONFIG_SLUB来代替CONFIG_SLAB,slub是基于slab核心实现的,slub改写自slob,是slob的优化后版本,比slab性能更好。如下图是内核文档里的相关说明:

所以,对应代码里是slub.c下的__slab_alloc函数,

在__slab_alloc函数里,还是明显地看到有使用锁的地方:

2.2 local_lock_irqsave在rt-linux里的实现

上图里的local_lock_irqsave虽然在普通内核里是会关抢占和禁用irq的,但是在rt-linux版本里,它是不会关抢占和禁用irq的,我们来看一下rt-linux里local_lock_irqsave的实现:

如下图local_lock_irqsave直接使用了__local_lock_irqsave:

rt-linux打开了CONFIG_PREEMPT_RT编译选项,所以,__local_lock_irqsave是调用的下图的逻辑:

即调用的__local_lock:

可以看到__local_lock会禁用migrate之外,就是调用的spin_lock,只是这个spinlock是一个per_cpu变量而已,实际调用流程和spin_lock是一样的。

要注意,这里只是禁用了迁移,抢占没有禁用,所以,在持锁期间,它是可能被抢占的。但是,更重要的是,在rt-linux的普通spinlock锁逻辑里,它会进行睡眠。

2.3 rt-linux里的spinlock里的rtlock_might_resched检查

在开启了CONFIG_PREEMPT_RT后,在rt-linux的spinlock_rt.c里的普通spinlock的核心逻辑__rt_spin_lock函数里,有如下的rtlock_might_resched的检查:

这个检查是为了在rt-linux里,避免在一些关中断/关抢占场景下,使用普通spinlock,检查的逻辑如下图在core.c里的__might_resched里:

这个检查是一个warning,但是实际上,如果看到这样的warning,就是说明有巨大的风险的,为什么这么说,因为,打印warning表示是在非预期的上下文下(关中断或关抢占)使用了rt-linux的普通spinlock。

假设,在关中断下,进入了rt-linux的普通spinlock锁里的睡眠的逻辑,也就是在关中断下调用了schedule函数,这是很明显的会导致系统错乱的情况,至于后面造成panic还是系统死锁都是有可能的。

三、rt-linux下内存分配逻辑引起的一些问题

在rt-linux下,除了要注意上面 2.3 里描述的在一些中断关闭或者抢占关闭的场景下使用可能睡眠的接口以外,还有不少因为rt-linux的普通spinlock锁有睡眠逻辑(有睡眠逻辑,自然就有相应的唤醒逻辑),从而导致一些性能有关的问题。

在之前的  博客里,我们讲到了rt-linux下的一个cgroup cpu的死锁问题 rt-linux下的cgroup cpu的死锁bug,还有rt-linux下的 rt-linux下的底层锁依赖因cgroup cpu功能导致不相干进程的高时延问题 。这里,对于rt-linux下的底层锁依赖,导致的不相干的进程之间的高时延问题,再做一定的说明。

3.1 内存分配路径下常见的两种锁导致的进程间的干扰

内存分配路径主要有两种锁,会产生这样的不相干进程之间的干扰,一种是在博客  里讲到的下图的唤醒关系:

还有一种是pre-cpu的锁导致的唤醒关系:

其实从上图里可以看到per-cpu的唤醒动作所发生的cpu和被唤醒任务锁在的cpu是同一个cpu,这其实在上面 2.2 里已经可以解释了,因为slab的分配所用的锁都是per-cpu的,自然相干扰的是同一个cpu上的任务。

但是,上面说的第一种,也就是一些全局的锁,从图里也可以看到,唤醒动作发生的cpu和被唤醒任务所在的cpu不是一个cpu:

3.2 除了slab分配时local_lock之间的干扰,还有lru_rotate锁及lru_lock锁

在上一节贴出的调用链里有lru_add_drain_cpu函数,lru_add_drain_cpu函数里有在执行pagevec_lru_move_fn前进入了lru_rotate.lock这个锁:

如上图看到lru_rotate.lock是一个local_lock,在rt-linux下也是会睡眠的,不过local_lock只涉及到同一个cpu上的影响。

对于不同cpu上的影响的锁是在上图里的pagevec_lru_move_fn函数里的逻辑:

也就是调用的folio_lruvec_relock_irqsave函数,folio_lruvec_relock_irqsave函数继而调用了folio_lruvec_lock_irqsave函数:

而folio_lruvec_lock_irqsave函数在打开memory cgroup时是如下实现:

使用的是lru_lock锁。


文章转载自:

http://vECl9EiE.crdtx.cn
http://C1KocA77.crdtx.cn
http://9DeveSMY.crdtx.cn
http://W3oYfLdE.crdtx.cn
http://AWvAONSb.crdtx.cn
http://R9SMrBMV.crdtx.cn
http://MeVzMTu9.crdtx.cn
http://GCFZfYqD.crdtx.cn
http://0UqtA0HE.crdtx.cn
http://uacvRq2P.crdtx.cn
http://kfVE8G5T.crdtx.cn
http://VoRzPeub.crdtx.cn
http://tTSRFvOO.crdtx.cn
http://XgAIrQej.crdtx.cn
http://xozDLsYx.crdtx.cn
http://kfRuryOk.crdtx.cn
http://hcVl9IR2.crdtx.cn
http://6Y6L0e7c.crdtx.cn
http://6SAz87sZ.crdtx.cn
http://ryk4RgKx.crdtx.cn
http://SnkxeoW4.crdtx.cn
http://IEV2QvPC.crdtx.cn
http://VcestBLf.crdtx.cn
http://7oi1CSmw.crdtx.cn
http://MXqRm0W3.crdtx.cn
http://lBQHcDwC.crdtx.cn
http://8S7ypK4A.crdtx.cn
http://byEj9PBa.crdtx.cn
http://8gfgOcrv.crdtx.cn
http://EifmZOhz.crdtx.cn
http://www.dtcms.com/a/385327.html

相关文章:

  • 如何统计DrawMeshInstancedIndirect绘制物体的Triangle数据
  • Android音视频学习路线图
  • 深入理解C语言指针(一)| 从内存到传址调用,掌握指针的核心本质
  • 代码审计-PHP专题原生开发文件上传删除包含文件操作监控Zend源码解密1day分析
  • springboot与vue中webSocket前后端连接问题
  • 数据结构——顺序存储链式存储
  • Vue 脚手架与webpack
  • pytest单元测试框架
  • CentOS7.9绿色安装mysql5.7.44
  • Cell Biology Learning Track(I)膜结构
  • 医院用的桌面管控软件有哪些?适用于医院的桌面管控软件推荐
  • 异步编程三剑客:回调、闭包与Promise组合实战
  • MySQL 主从同步(复制)实战
  • redis面试点记录
  • mysql和postgresql如何选择
  • 电磁兼容性(EMC)法规
  • 【论文笔记】Self-Supervised Point Cloud Prediction for Autonomous Driving
  • MySQL数据库(四)—— 使用MyCat实现MySQL主从读写分离实战指南
  • HTB paper
  • oracle认证有哪几种?如何选择
  • YoloV8改进策略:上采样改进|反卷积|数学上可逆的反卷积」塞进 YOLOv8,涨点不涨参!图像恢复黑科技 Converse2D 的跨界奇袭!
  • springboot netty 服务端网络编程入门与实战
  • 从零开始学AI——15
  • Linux C库函数的可重入与不可重入版本说明
  • ZooKeeper核心知识点总结:分布式系统的“协调者”
  • Unreal故障艺术之RGB颜色分离故障
  • 金融数据---东方财富人气榜-A股
  • 设计模式详解——创建型
  • Java 泛型与通配符全解析
  • Python变量与数据类型全解析:从命名规则到类型转换