我试图了解负载均衡器如何在 Linux 内核中的多处理器系统上工作,
Linux 调度程序基本上使用 runques 来存储它接下来必须运行的任务,现在考虑多处理器系统的情况 load_balancer() 的实现方式如 Robert Loves 的书 Linux Kernel Development 2nd edition 中给出的解释如下
首先,load_balance() 调用 find_busiest_queue() 来确定最繁忙的运行队列。换句话说,这是其中进程数最多的运行队列。如果没有运行队列的进程比当前进程多 25% 或更多,则 find_busiest_queue() 返回 NULL 并且 load_balance() 返回。否则,返回最繁忙的运行队列。
其次,load_balance() 决定要从最繁忙的运行队列中提取哪个优先级数组。过期数组是首选,因为这些任务在相对较长的时间内没有运行,因此很可能不在处理器的缓存中(也就是说,它们不是缓存热的)。如果过期的优先级数组为空,则活动的优先级是唯一的选择。
接下来, load_balance() 找到具有任务的最高优先级(最小值)列表,因为公平分配高优先级任务比低优先级任务更重要。
分析给定优先级的每个任务,以找到未运行、未通过处理器关联阻止迁移且未缓存热的任务。如果任务满足此条件,则调用 pull_task() 将任务从最繁忙的运行队列拉到当前运行队列。
只要运行队列保持不平衡,就会重复前两个步骤,并将更多任务从最繁忙的运行队列拉到当前。最后,当不平衡解决时,当前运行队列被解锁并且 load_balance() 返回。
代码如下
static int load_balance(int this_cpu, runqueue_t *this_rq,
struct sched_domain *sd, enum idle_type idle)
{
struct sched_group *group;
runqueue_t *busiest;
unsigned long imbalance;
int nr_moved;
spin_lock(&this_rq->lock);
group = find_busiest_group(sd, this_cpu, &imbalance, idle);
if (!group)
goto out_balanced;
busiest = find_busiest_queue(group);
if (!busiest)
goto out_balanced;
nr_moved = 0;
if (busiest->nr_running > 1) {
double_lock_balance(this_rq, busiest);
nr_moved = move_tasks(this_rq, this_cpu, busiest,
imbalance, sd, idle);
spin_unlock(&busiest->lock);
}
spin_unlock(&this_rq->lock);
if (!nr_moved) {
sd->nr_balance_failed++;
if (unlikely(sd->nr_balance_failed > sd->cache_nice_tries+2)) {
int wake = 0;
spin_lock(&busiest->lock);
if (!busiest->active_balance) {
busiest->active_balance = 1;
busiest->push_cpu = this_cpu;
wake = 1;
}
spin_unlock(&busiest->lock);
if (wake)
wake_up_process(busiest->migration_thread);
sd->nr_balance_failed = sd->cache_nice_tries;
}
} else
sd->nr_balance_failed = 0;
sd->balance_interval = sd->min_interval;
return nr_moved;
out_balanced:
spin_unlock(&this_rq->lock);
if (sd->balance_interval < sd->max_interval)
sd->balance_interval *= 2;
return 0;
}
我不清楚的是上面代码中的结构 struct sched_domain *sd 我检查的这个结构在 include/linux/sched.h 中定义如下 http://lxr.linux.no/linux+v3.7.1/include/ linux/sched.h#L895 这是一个很大的结构,所以为了简单起见,我只给出了一个链接。我想知道的是上面代码中 struct sched_domain 的用途是什么?
为什么在调用 load_balancer() 时使用这个结构代表什么?
这里可能给出了一些东西 http://www.kernel.org/doc/Documentation/scheduler/sched-domains.txt 为什么 CPU 需要调度域?这些域名代表什么?