Linuxカーネルのマルチプロセッサシステムでロードバランサがどのように機能するかを理解しようとしています.
Linux スケジューラは基本的に runques を使用して、次に実行する必要があるタスクを保存します。現在、マルチプロセッサ システムの状況を考慮して、load_balancer() が実装されている方法について説明します。Robert Loves の本 Linux Kernel Development 2nd edition に記載されています。
最初に、load_balance() は find_busiest_queue() を呼び出して、最もビジーなランキューを決定します。つまり、これは最も多くのプロセスを含むランキューです。現在より 25% 以上のプロセスを持つランキューがない場合、find_busiest_queue() は NULL を返し、load_balance() は戻ります。それ以外の場合は、最もビジーなランキューが返されます。
2 番目に、load_balance() は、最もビジーなランキューのどの優先順位の配列から取得するかを決定します。これらのタスクは比較的長い間実行されておらず、プロセッサのキャッシュにない可能性が高い (つまり、キャッシュがホットではない) ため、期限切れの配列が優先されます。期限切れの優先度配列が空の場合、アクティブな配列が唯一の選択肢です。
次に、優先度の高いタスクを優先度の低いタスクよりも公平に分配することが重要であるため、load_balance() は優先度が最も高い (最小値の) タスクのリストを見つけます。
指定された優先度の各タスクが分析され、実行されていないタスク、プロセッサ アフィニティによって移行が妨げられていないタスク、キャッシュ ホットではないタスクが検出されます。タスクがこの基準を満たす場合、pull_task() が呼び出されて、最もビジーなランキューから現在のランキューにタスクがプルされます。
ランキューが不均衡なままである限り、前の 2 つのステップが繰り返され、より多くのタスクが最もビジーなランキューから現在のランキューに引き出されます。最後に、不均衡が解決されると、現在のランキューのロックが解除され、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 の構造です。私がチェックしたこの構造は、 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 にスケジューリング ドメインが必要なのはなぜですか? これらのドメインは何の略ですか?