【WALT】top task 相关代码详解
代码版本:Linux4.9 android-msm-crosshatch-4.9-android12
文章目录
结构体
我们先来看看与 top task 有关的结构体。
#define NUM_TRACKED_WINDOWS 2
#define NUM_LOAD_INDICES 1000
#define DECLARE_BITMAP_ARRAY(name,nr,bits) \
unsigned long name[nr][BITS_TO_LONGS(bits)]
struct rq {
……
#ifdef CONFIG_SCHED_WALT
……
struct load_subtractions load_subs[NUM_TRACKED_WINDOWS];
DECLARE_BITMAP_ARRAY(top_tasks_bitmap,
NUM_TRACKED_WINDOWS, NUM_LOAD_INDICES);
u8 *top_tasks[NUM_TRACKED_WINDOWS];
u8 curr_table;
int prev_top;
int curr_top;
#endif
……
}
top_tasks_bitmap 是一个位图,一个位有 2 种状态,即 0 和 1。位图本质上是数组,适用于大规模数据,但数据状态又不是很多的情况,通常是用来判断某个数据存不存在的。
top_tasks_bitmap 的作用是可以快速找到当前 CPU 的运行队列在上一个窗口(prev)和当前窗口(curr)中有哪些区间在执行任务。
- 区间:一个窗口被分为了 NUM_LOAD_INDICES 个区间。(默认为 1000 个)
在一个 CPU 的运行队列的结构体中,通过 top_tasks 数组来跟踪 prev 和 curr 两个窗口的 top task 情况,通过 curr_table 来标识哪一个 top_tasks 是 curr 的。curr_table 非 0 即 1。
prev_top 和 curr_top 的值为 prev 窗口 和 curr 窗口中最后一个任务执行结束时的时间所处区间的下标。换句话说,它们指示了 prev 窗口 和 curr 窗口中最后一个还在执行任务的区间。
初始化 & 清理函数
#define NUM_TRACKED_WINDOWS 2
#define NUM_LOAD_INDICES 1000
void walt_sched_init(struct rq *rq)
{
……
for (j = 0; j < NUM_TRACKED_WINDOWS; j++) {
memset(&rq->load_subs[j], 0,
sizeof(struct load_subtractions));
rq->top_tasks[j] = kcalloc(NUM_LOAD_INDICES,
sizeof(u8), GFP_NOWAIT);
/* No other choice */
BUG_ON(!rq->top_tasks[j]);
clear_top_tasks_bitmap(rq->top_tasks_bitmap[j]);
}
……
}
static const unsigned int top_tasks_bitmap_size =
BITS_TO_LONGS(NUM_LOAD_INDICES + 1) * sizeof(unsigned long);
void clear_top_tasks_bitmap(unsigned long *bitmap)
{
memset(bitmap, 0, top_tasks_bitmap_size);
__set_bit(NUM_LOAD_INDICES, bitmap);
}
static inline void clear_top_tasks_table(u8 *table)
{
memset(table, 0, NUM_LOAD_INDICES * sizeof(u8));
}
初始化就是分配内存。如果分配是从一个原子上下文中进行的,例如中断处理程序,使用 GFP_NOWAIT 。这个 标志可以防止直接回收和IO或文件系统操作。因此,在内存压力下, GFP_NOWAIT 分配 可能会失败。(该段话来自《内存分配指南》)
更新 top task
#

本文详细解读了Linux4.9Android-msm-crosshatch-4.9-android12中WALT调度器的toptask相关代码,涉及结构体定义、内存初始化与清理、窗口翻滚时的toptask更新以及计算toptask负载的过程。
最低0.47元/天 解锁文章
1万+





