422 /** 423 * cpumask_and - *dstp = *src1p & *src2p 424 * @dstp: the cpumask result 425 * @src1p: the first input 426 * @src2p: the second input 427 * 428 * If *@dstp is empty, returns 0, else returns 1 429 */ 430 static inline int cpumask_and(struct cpumask *dstp, 431 const struct cpumask *src1p, 432 const struct cpumask *src2p) 433 { 434 return bitmap_and(cpumask_bits(dstp), cpumask_bits(src1p), 435 cpumask_bits(src2p), nr_cpumask_bits); 436 }
前段时间在社区看到一个schedule cluster调度功能,其中有块代码在选择idle cpu时候, 对其中设置cpu_mask硬是没有梳理清楚,此时正好借此机会梳理下
struct task_struct *p
cpumask_and(cpus, cpu_cluster_mask(target), p->cpus_ptr);
从cpumask_and函数定义可以知道,cpus作为目的cpu_mask, 希望从cpu_cluster_mask和task_struct的cpus_ptr两者相与中获取cpu_maks的值,但是task_struct中
的cpus_ptr,其实其表示的是当前进程可使用的cpu掩码值,通常不对进程进行taskset等相关设置的话,直接表示cpu_all_mask,可运行在所有cpu上。再通过查找当前cpu target所在的cluster_mask,通过相与的方式,进一步缩小获取下一个idle cpu的方位,而cluster mask在armv8架构上是共享L3tag的,所以从idle选择这样的一个idle cpu是很有意义的,这可以使得程序的运行效率大大提升。
- [RFC,v5,0/4] scheduler: expose the topology of clusters and add cluster scheduler
- [RFC,v5,1/4] topology: Represent clusters of CPUs within a die
- [RFC,v5,2/4] scheduler: add scheduler level for clusters
- [RFC,v5,3/4] scheduler: scan idle cpu in cluster before scanning the whole llc
- [RFC,v5,4/4] scheduler: Add cluster scheduler level for x86