【内核调度、负载均衡】【select_task_rq_fair】

本文详细解析了Linux内核调度器中的负载均衡机制,重点介绍了select_task_rq_fair函数如何选择目标运行队列,以及find_idlest_cpu和find_idlest_group_cpu函数在寻找最空闲CPU过程中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在新建一个task或者block的task被唤醒的时候,也会执行负载均衡,调用的函数是select_task_rq_fair

和内核周期性调度相似(寻找最忙的cpu上的任务,然后把该任务pull过来执行。或者从最忙的cpu上将当时正在执行的任务停掉,然后放到local cpu上去执行)。只是他寻找的是最idlest的cpu来运行task

select_task_rq_fair

/*
 * select_task_rq_fair: Select target runqueue for the waking task in domains
 * that have the 'sd_flag' flag set. In practice, this is SD_BALANCE_WAKE,
 * SD_BALANCE_FORK, or SD_BALANCE_EXEC.
 *
 * Balances load by selecting the idlest cpu in the idlest group, or under
 * certain conditions an idle sibling cpu if the domain has SD_WAKE_AFFINE set.
 *
 * Returns the target cpu number.
 *
 * preempt must be disabled.
 */
static int
select_task_rq_fair(struct task_struct *p, int prev_cpu, int sd_flag, int wake_flags,
		    int sibling_count_hint)
{
	struct sched_domain *tmp, *affine_sd = NULL;
	struct sched_domain *sd = NULL, *energy_sd = NULL;
	int cpu = smp_processor_id();
	int new_cpu = prev_cpu;/* 默认new_cpu为prev_cpu */
	int want_affine = 0;
	int want_energy = 0;
	int sync = wake_flags & WF_SYNC;

	if (energy_aware()) {//使用EAS做负载均衡
		rcu_read_lock();
		new_cpu = find_energy_efficient_cpu(energy_sd, p,
				cpu, prev_cpu, sync);

		if (new_cpu == -1)
			new_cpu = prev_cpu;

		rcu_read_unlock();
		return new_cpu;
	}

	rcu_read_lock();

	if (sd_flag & SD_BALANCE_WAKE) {
		record_wakee(p);
		want_energy = wake_energy(p, prev_cpu, sd_flag, wake_flags);
		want_affine = !want_energy &&
				//!wake_wide(p)  当前cpu的唤醒次数没有超标
			      !wake_wide(p, sibling_count_hint) &&//
			      !wake_cap(p, cpu, prev_cpu) &&
				  //pumask_test_cpu(cpu, tsk_cpus_allowed(p)) // 当前cpu在进程在P的affinity中
			      cpumask_test_cpu(cpu, &p->cpus_allowed);
	}
	/* (4) 从下往上遍历当前cpu的sd,查询在哪个层次的sd进行负载均衡 */
	for_each_domain(cpu, tmp) {
		if (!(tmp->flags & SD_LOAD_BALANCE))
			break;

		/*
		 * If both cpu and prev_cpu are part of this domain,
		 * cpu is a valid SD_WAKE_AFFINE target.
		 */
		if (want_affine && (tmp->flags & SD_WAKE_AFFINE) &&
		    cpumask_test_cpu(prev_cpu, sched_domain_span(tmp))) {
			affine_sd 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值