案例分析 | SurfaceFlinger Binder RT 被降级到CFS

分享一个简单的有意思案例

实际项目上,不止一次遇到Sf 中的线程从RT 掉到CFS 120

比如这段:Launcher 主线程binder call 到Sf,但是由于Sf binder 线程被抢占,导致整个binder 耗时较长,从而导致Launcher 侧掉了几帧

往前追溯,看下这个Sf binder 线程何时被降级以及降级原因

正是由于这次的HWC async binder call到Sf 侧,导致Sf binder 线程被降级到了120

对应Ftrace 日志
binder:1060_3-1496 ( 1060) [002] .... 58582.132796: binder_set_priority: proc=1060 thread=1496 old_prio=97 new_prio=120 desired_prio=120

对应降级的code

到这里,看起来似乎是Aosp 的自身逻辑导致

inherit_rt
@inherit_rt: inherit RT scheduling policy from caller

翻下了历史提交
[PATCH 06/13] ANDROID: binder: add RT inheritance flag to node. - Martijn Coenen

inherit_rt 这个属性通常是由上层调用setInheritRt 传递下来的

js 复制代码
void BBinder::setInheritRt(bool inheritRt) {
    LOG_ALWAYS_FATAL_IF(mParceled,
                        "setInheritRt() should not be called after a binder object "
                        "is parceled/sent to another process");

    Extras* e = mExtras.load(std::memory_order_acquire);

    if (!e) {
        if (!inheritRt) {
            return;
        }

        e = getOrCreateExtras();
        if (!e) return; // out of memory
    }

    e->mInheritRt = inheritRt;
}

默认情况下,AIDL 不会继承实时优先级。必须根据 binder 使用 setInheritRt 函数才能启用实时优先级继承

ref: 适用于 HAL 的 AIDL | Android Open Source Project

目前全局搜使用的地方,只有audio 等少数对实时性要求高的场景下会将该属性置为true

再回过头来看这个问题,整理下:

最初是Launcher binder 同步call 到Sf binder 线程,但是Sf binder 线程被抢占导致Launcher 掉帧 而Sf binder 线程被抢占的原因,在于前面HWC 一次async binder call 之后,Sf binder 掉到binder 默认优先级120.

那么如何先临时改掉这个问题呢?

临时改法其实有多种,上层或kernel 中都可以规避这个问题,比如可以通过trace_android_vh_binder_priority_skip 接口做一些预判处理,针对这种场景提前skip 掉。

Google 对于AIDL binder 默认不支持RT 继承的本意也是出于对过多RT 会影响性能的考虑,这样修改是否有side effect?这个还有待斟酌.

相关推荐
聆风吟º36 分钟前
【Spring Boot 报错已解决】别让端口配置卡壳!Spring Boot “Binding to target failed” 报错解决思路
android·java·spring boot
非专业程序员Ping8 小时前
HarfBuzz概览
android·ios·swift·font
Jeled9 小时前
「高级 Android 架构师成长路线」的第 1 阶段 —— 强化体系与架构思维(Clean Architecture 实战)
android·kotlin·android studio·1024程序员节
明道源码11 小时前
Kotlin 控制流、函数、Lambda、高阶函数
android·开发语言·kotlin
消失的旧时光-194313 小时前
Kotlin × Gson:为什么遍历 JsonObject 要用 entrySet()
android·kotlin·数据处理·1024程序员节
G果14 小时前
安卓APP页面之间传参(Android studio 开发)
android·java·android studio
曾凡宇先生16 小时前
无法远程连接 MySQL
android·开发语言·数据库·sql·tcp/ip·mysql·adb
zhangphil17 小时前
Android GPU的RenderThread Texture upload上传Bitmap优化prepareToDraw
android
柿蒂18 小时前
聊聊SliverPersistentHeader优先消费滑动的设计
android·flutter
假装多好12320 小时前
android三方调试几个常用命令
android·1024程序员节·三方,gms