- 論壇徽章:
- 0
|
本帖最后由 71v5 于 2014-06-29 22:44 編輯
[sched_highest函數(shù)]-確定系統(tǒng)中cpu運(yùn)行隊(duì)列負(fù)載最高的cpu,并返回該cpu的logical cpu id,繼續(xù)以cpu拓?fù)鋱D開始,因?yàn)闄z查cpu負(fù)載
的過程跟cpu拓?fù)鋱D密切相關(guān),這里為了簡(jiǎn)化分析,做下面的假設(shè):
1:cpuset_t類型的大小為1字節(jié),并且bit位以從左到右的順序編號(hào),那么:
對(duì)于cpu_top中的cg_mask成員,其編碼為11111111, 表示該group中包含的cpu的logical id為0,1,2,3,4,5,6,7。
對(duì)于group[1]中的cg_mask成員,其編碼為11110000,表示該group中包含的cpu的logical id為0,1,2,3。
對(duì)于group[2]中的cg_mask成員,其編碼為00001111,表示該group中包含的cpu的logical id為4,5,6,7。
2:因?yàn)椴还苁谴_定負(fù)載最高的cpu還是負(fù)載最低的cpu,最終都是通過函數(shù)cpu_search來操作的,所以在cpu_search函數(shù)中
略去了一些不相關(guān)的操作,比如檢查負(fù)載最高的cpu時(shí),就略去了和檢查負(fù)載最低的cpu相關(guān)的代碼,略去的代碼以下面
的"。。。。。。。。。。。。。。。。。。。"標(biāo)識(shí)。
3:cpu運(yùn)行隊(duì)列分別為tdq_cpu[0],tdq_cpu[1],tdq_cpu[2],tdq_cpu[3]等
07.jpg (677.33 KB, 下載次數(shù): 385)
下載附件
2014-06-28 16:28 上傳
[數(shù)據(jù)類型struct cpu_search]:- /************************************************************************
- * struct cpu_search類型的數(shù)據(jù)對(duì)象在函數(shù)cpu_search中使用,用來保存
- 查找的結(jié)果。
- cs_mask:一個(gè)cpu掩碼位圖,位圖中設(shè)置為1的bit位對(duì)應(yīng)的cpu將在
- 函數(shù)cpu_search中檢查其負(fù)載。
- cs_prefer:在檢查cpu運(yùn)行隊(duì)列負(fù)載最低cpu的時(shí)候使用,一般設(shè)置為
- 上一次調(diào)用函數(shù)sched_highest返回的cpu的logical cpu id,當(dāng)所
- 檢查的cpu和cs_prefer相同時(shí),將cs_prefer運(yùn)行隊(duì)列的負(fù)載減去
- 一個(gè)常數(shù)。
- cs_limit:一個(gè)負(fù)載閾值。
- cs_cpu:cpu運(yùn)行隊(duì)列負(fù)載最低或者最高的cpu對(duì)應(yīng)的logical cpu id。
- cs_load:相應(yīng)的負(fù)載。
- cs_pri:一般情況下,可以忽略。
- *********************************/
- 577 struct cpu_search {
- 578 cpuset_t cs_mask;
- 579 u_int cs_prefer;
- 580 int cs_pri; /* Min priority for low. */
- 581 int cs_limit; /* Max load for low, min load for high. */
- 582 int cs_cpu;
- 583 int cs_load;
- 584 };
- /************************************************************
- * 傳遞給cpu_search函數(shù)的標(biāo)志,含義如下:
- CPU_SEARCH_LOWEST:只確定cpu運(yùn)行隊(duì)列負(fù)載最低的cpu。
- CPU_SEARCH_HIGHEST:只確定cpu運(yùn)行隊(duì)列負(fù)載最高的cpu。
- CPU_SEARCH_BOTH:同時(shí)確定cpu運(yùn)行隊(duì)列負(fù)載最高和最低的cpu。
- *****************************/
- 586 #define CPU_SEARCH_LOWEST 0x1
- 587 #define CPU_SEARCH_HIGHEST 0x2
- 588 #define CPU_SEARCH_BOTH (CPU_SEARCH_LOWEST|CPU_SEARCH_HIGHEST)
復(fù)制代碼 [sched_highest函數(shù)]:- /********************************************************************************************
- * Find the cpu with the highest load via the highest loaded path.
- 一般情況下,在確定系統(tǒng)中cpu運(yùn)行隊(duì)列負(fù)載最高的cpu時(shí),會(huì)以下面的參數(shù)調(diào)用sched_highest函數(shù):
- cg:cpu_top。
- mask:類型為cpuset_t的cpu位圖,這里的編碼為11111111,在隨后從sched_balance_group函數(shù)中
- 的for循環(huán)中繼續(xù)調(diào)用sched_highest函數(shù)時(shí),mask的值會(huì)改變,不過mask中bit位為1的cpu
- 都要被檢查。
- minload:這里的值為1。
- 該函數(shù)實(shí)際上使用參數(shù)mask,minload初始化一個(gè)struct cpu_serach類型的數(shù)據(jù)對(duì)象,
- 然后再調(diào)用cpu_search_highest函數(shù),該函數(shù)為函數(shù)cpu_search的簡(jiǎn)單封裝。
- 函數(shù)sched_highest返回值如果為-1:在一般情況下,如果返回值為-1,就表示所檢查cpu運(yùn)行隊(duì)列
- 中可遷移thread的數(shù)目為0.
- 函數(shù)sched_highest返回其它值:相應(yīng)cpu的logical cpu id,該cpu運(yùn)行隊(duì)列中可遷移thread的數(shù)目
- 非零,并且負(fù)載最高。
- **************************************/
- 762 static inline int
- 763 sched_highest(const struct cpu_group *cg, cpuset_t mask, int minload)
- 764 {
- 765 struct cpu_search high;
- 766
- 767 high.cs_cpu = -1;
- 768 high.cs_mask = mask;
- 769 high.cs_limit = minload;
- 770 cpu_search_highest(cg, &high);
- 771 return high.cs_cpu;
- 772 }
- 726 int
- 727 cpu_search_highest(const struct cpu_group *cg, struct cpu_search *high)
- 728 {
- 729 return cpu_search(cg, NULL, high, CPU_SEARCH_HIGHEST);
- 730 }
復(fù)制代碼 [函數(shù)cpu_search]-該函數(shù)實(shí)際上是一個(gè)遞歸過程,根據(jù)之前的假定,遞歸深度為1,這里分檢查cpu_top和檢查child cpu_group兩種情況來分析該函數(shù),因?yàn)?br />
這兩種情況cpu_search函數(shù)的執(zhí)行流程不一樣。
[檢查cpu_top-調(diào)用函數(shù)cpu_search]:- /***********************************************************************************************
- * 參數(shù)描述:
- cg:cpu_top
- low:NULL。
- high:類型為struct cpu_search的數(shù)據(jù)對(duì)象,各成員如下:
- high.cs_cpu = -1;
- high.cs_mask = mask; // 11111111
- high.cs_limit = minload;// 1
- match:CPU_SEARCH_HIGHEST
- 當(dāng)函數(shù)cpu_search返回時(shí),high指向的struct cpu_search對(duì)象中包含了group[1]和group[2]中
- cpu運(yùn)行隊(duì)列負(fù)載最高cpu的logical cpu id和相應(yīng)運(yùn)行隊(duì)列的負(fù)載。
- 函數(shù)的返回值為group[2]和group[1]中cpu運(yùn)行隊(duì)列的總負(fù)載。
- ******************************************/
- 612 static __inline int
- 613 cpu_search(const struct cpu_group *cg, struct cpu_search *low,
- 614 struct cpu_search *high, const int match)
- 615 {
- /****************************************************************************
- * 局部變量描述:
- lgroup:檢查負(fù)載最低的cpu時(shí)使用。
- hgroup:檢查負(fù)載最低的cpu時(shí)使用
- cpumask:cpu位圖。
- child:指向child cpu_group。
- tdq:指向相應(yīng)cpu的運(yùn)行隊(duì)列。
- cpu:相應(yīng)cpu的logical cpu id。
- i:child cpu_group的數(shù)目。
- hload:cpu的最高負(fù)載。
- load:
- total:總負(fù)載。
- rnd,*rndptr:一個(gè)隨機(jī)數(shù)值,不明白其含義,但是不影響這里的分析,眾會(huì)員
- 知道的話請(qǐng)及時(shí)聯(lián)系啊。
- *************************************/
- 616 struct cpu_search lgroup;
- 617 struct cpu_search hgroup;
- 618 cpuset_t cpumask;
- 619 struct cpu_group *child;
- 620 struct tdq *tdq;
- 621 int cpu, i, hload, lload, load, total, rnd, *rndptr;
- 622
- /**************************************************************************
- * cpumask:此時(shí)的編碼為11111111.
-
- *****************/
- 623 total = 0;
- 624 cpumask = cg->cg_mask;
- 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
- 629 if (match & CPU_SEARCH_HIGHEST) {
- 630 hload = INT_MIN;
- 631 hgroup = *high;
- 632 }
- 633
- /***********************************************************************************
- * mp_maxid:
- Max CPU ID,初始化時(shí)被設(shè)置為mp_maxid = mp_ncpus - 1; 被初始化為7.
- 635-712:之間的for循環(huán)執(zhí)行兩次,每次循環(huán)都檢查一個(gè)child cpu_group。
- 第一次for循環(huán):調(diào)用函數(shù)cpu_search檢查group[2]
- i = 2,cpu = 7;
-
- 636-643:執(zhí)行else語句,child為&group[2];
-
- 649-685:這里將執(zhí)行if語句,即將調(diào)用函數(shù)cpu_search檢查group[2].
- 650:group[2]中的cg_mask成員編碼為00001111,CPU_NAND執(zhí)行完后,
- cpumask的編碼為11110000。
-
- 第二次for循環(huán):調(diào)用函數(shù)cpu_search檢查group[1].
- i = 1,cpu = 7.
- 636-643:執(zhí)行else語句,child為&group[1];
-
- 649-685:這里將執(zhí)行if語句,即將調(diào)用函數(shù)cpu_search檢查group[1].
- 650:group[1]中的cg_mask成員編碼為11110000,CPU_NAND執(zhí)行完后,
- cpumask的編碼為00000000。
- *************************************************/
- 634 /* Iterate through the child CPU groups and then remaining CPUs. */
- 635 for (i = cg->cg_children, cpu = mp_maxid; i >= 0; ) {
- 636 if (i == 0) {
- 637 while (cpu >= 0 && !CPU_ISSET(cpu, &cpumask))
- 638 cpu--;
- 639 if (cpu < 0)
- 640 break;
- 641 child = NULL;
- 642 } else
- 643 child = &cg->cg_child[i - 1];
- 644
- 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
- 647 if (match & CPU_SEARCH_HIGHEST)
- 648 hgroup.cs_cpu = -1;
- 649 if (child) { /* Handle child CPU group. */
- 650 CPU_NAND(&cpumask, &child->cg_mask);
- 651 switch (match) {
- 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
- 655 case CPU_SEARCH_HIGHEST:
- 656 load = cpu_search_highest(child, &hgroup);
- 657 break;
- 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
- 661 }
- 662 } else { /* Handle child CPU. */
- 663 tdq = TDQ_CPU(cpu);
- 664 load = tdq->tdq_load * 256;
- 665 rndptr = DPCPU_PTR(randomval);
- 666 rnd = (*rndptr = *rndptr * 69069 + 5) >> 26;
- 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
- 678 if (match & CPU_SEARCH_HIGHEST)
- 679 if (tdq->tdq_load >= hgroup.cs_limit &&
- 680 tdq->tdq_transferable &&
- 681 CPU_ISSET(cpu, &hgroup.cs_mask)) {
- 682 hgroup.cs_cpu = cpu;
- 683 hgroup.cs_load = load - rnd;
- 684 }
- 685 }
- /*************************************************************************************************
- * cpu_search函數(shù)檢查完group[2]完成后:
-
- 686:遞增total。
- 698-705:變量high指向的struct cpu_search對(duì)象包含了group[2]中運(yùn)行隊(duì)列負(fù)載最高cpu的
- logical cpu id及其運(yùn)行隊(duì)列的負(fù)載。
- 706-711:執(zhí)行if語句前child為&group[2],i = 2,cpumask的編碼為11110000
- 執(zhí)行if語句后i = 1。
- 此時(shí)進(jìn)行下一次for循環(huán),將調(diào)用函數(shù)cpu_search檢查group[1].
- cpu_search函數(shù)檢查完group[1]完成后:
-
- 686:遞增total。
- 698-705:變量high指向的struct cpu_search對(duì)象包含了group[1]和group[2]中運(yùn)行隊(duì)列負(fù)載最高cpu的
- logical cpu id及其運(yùn)行隊(duì)列的負(fù)載。
- 706-711:執(zhí)行if語句前child為&group[2],i = 1,cpumask的編碼為00000000
- 執(zhí)行if語句后i = 0。
- 此時(shí)708-709行就直接跳出了for循環(huán)。
- ************************************/
- 686 total += load;
- 687
- 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
- 698 if (match & CPU_SEARCH_HIGHEST)
- 699 if (hgroup.cs_cpu >= 0 &&
- 700 (load > hload ||
- 701 (load == hload && hgroup.cs_load > high->cs_load))) {
- 702 hload = load;
- 703 high->cs_cpu = hgroup.cs_cpu;
- 704 high->cs_load = hgroup.cs_load;
- 705 }
- 706 if (child) {
- 707 i--;
- 708 if (i == 0 && CPU_EMPTY(&cpumask))
- 709 break;
- 710 } else
- 711 cpu--;
- 712 }
- 713 return (total);
- 714 }
復(fù)制代碼 [檢查child cpu_group-調(diào)用函數(shù)cpu_search]:- /****************************************************************************
- * 檢查group[2]:
- 參數(shù)描述:
- cg:&group[2]
- low:NULL。
- high:類型為struct cpu_search的數(shù)據(jù)對(duì)象,各成員如下:
- high.cs_cpu = -1;
- high.cs_mask = mask; // 11111111
- high.cs_limit = minload;// 1
- match:CPU_SEARCH_HIGHEST
- 檢查group[1]:
- 參數(shù)描述:
- cg:&group[1]
- low:NULL。
- high:類型為struct cpu_search的數(shù)據(jù)對(duì)象,各成員如下:
- high.cs_cpu = -1;
- high.cs_mask = mask; // 11111111
- high.cs_limit = minload;// 1
- match:CPU_SEARCH_HIGHEST
- 檢查group[2],當(dāng)函數(shù)cpu_search返回時(shí),high指向的struct cpu_search對(duì)象
- 中包含了group[2]中負(fù)載最高cpu的logical cpu id和相應(yīng)運(yùn)行隊(duì)列的負(fù)載。
- 函數(shù)的返回值為group[2]中cpu運(yùn)行隊(duì)列的總負(fù)載。
- 檢查group[1],當(dāng)函數(shù)cpu_search返回時(shí),high指向的struct cpu_search對(duì)象
- 中包含了group[1]中負(fù)載最高cpu的logical cpu id和相應(yīng)運(yùn)行隊(duì)列的負(fù)載。
- 函數(shù)的返回值為group[1]中cpu運(yùn)行隊(duì)列的總負(fù)載。
- ******************************************/
- 612 static __inline int
- 613 cpu_search(const struct cpu_group *cg, struct cpu_search *low,
- 614 struct cpu_search *high, const int match)
- 615 {
- /****************************************************************************
- * 局部變量描述:
- lgroup:檢查負(fù)載最低的cpu時(shí)使用。
- hgroup:檢查負(fù)載最低的cpu時(shí)使用
- cpumask:cpu位圖。
- child:指向child cpu_group。
- tdq:指向相應(yīng)cpu的運(yùn)行隊(duì)列。
- cpu:相應(yīng)cpu的logical cpu id。
- i:child cpu_group的數(shù)目。
- hload:cpu的最高負(fù)載。
- load:
- total:總負(fù)載。
- rnd,*rndptr:一個(gè)隨機(jī)數(shù)值,不明白其含義,但是不影響這里的分析,眾會(huì)員
- 知道的話請(qǐng)及時(shí)聯(lián)系啊。
- *************************************/
- 616 struct cpu_search lgroup;
- 617 struct cpu_search hgroup;
- 618 cpuset_t cpumask;
- 619 struct cpu_group *child;
- 620 struct tdq *tdq;
- 621 int cpu, i, hload, lload, load, total, rnd, *rndptr;
- 622
- /**************************************************************************
- * 檢查group[2]:
- cpumask:此時(shí)的編碼為00001111.
- 檢查group[1]:
- cpumask:此時(shí)的編碼為11110000.
- *******************************************/
- 623 total = 0;
- 624 cpumask = cg->cg_mask;
- 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
- 629 if (match & CPU_SEARCH_HIGHEST) {
- 630 hload = INT_MIN;
- 631 hgroup = *high;
- 632 }
- 633
- /***********************************************************************************
- * 檢查group[2]:
- mp_maxid:
- Max CPU ID,初始化時(shí)被設(shè)置為mp_maxid = mp_ncpus - 1; 被初始化為7.
- 635-712:之間的for循環(huán)執(zhí)行四次,檢查child cpu_group,即group[2]中包含的cpu上運(yùn)行
- 隊(duì)列的負(fù)載。
- 第一次for循環(huán):
- i = 0,cpu = 7
-
- 第二次for循環(huán):
- i = 0,cpu = 6
- 第三次for循環(huán):
- i = 0,cpu = 5
- 第四次for循環(huán):
- i = 0,cpu = 4
- 636-643:執(zhí)行if語句,因?yàn)間roup[2]沒有child cpu_group,所以child為NULL。
- 637-638:跳過不屬于group[2]中包含的cpu。
- 639-640:group[2]中的cpu已檢查完畢,執(zhí)行跳出for循環(huán)的操作。
- 649-685:這里將執(zhí)行else語句,檢查相應(yīng)cpu運(yùn)行隊(duì)列的負(fù)載。
-
- 檢查group[1]:
- mp_maxid:
- Max CPU ID,初始化時(shí)被設(shè)置為mp_maxid = mp_ncpus - 1; 被初始化為7.
- 635-712:之間的for循環(huán)執(zhí)行四次,檢查child cpu_group,即group[1]中包含的cpu上運(yùn)行
- 隊(duì)列的負(fù)載。
- 第一次for循環(huán):
- i = 0,cpu = 3
-
- 第二次for循環(huán):
- i = 0,cpu = 2
- 第三次for循環(huán):
- i = 0,cpu = 1
- 第四次for循環(huán):
- i = 0,cpu = 0
- 從上面可以看出,每個(gè)cpu_group中的cpu都要被檢查,但是下面678-683之間的宏CPU_ISSET
- 會(huì)再次將cpu限制在一個(gè)特定的cpu集合中。
- 636-643:執(zhí)行if語句,因?yàn)間roup[1]沒有child cpu_group,所以child為NULL。
- 637-638:跳過不屬于group[1]中包含的cpu。
- 639-640:group[1]中的cpu已檢查完畢,執(zhí)行跳出for循環(huán)的操作。
- 649-685:這里將執(zhí)行else語句,檢查相應(yīng)cpu運(yùn)行隊(duì)列的負(fù)載。
-
- *************************************************/
- 634 /* Iterate through the child CPU groups and then remaining CPUs. */
- 635 for (i = cg->cg_children, cpu = mp_maxid; i >= 0; ) {
- 636 if (i == 0) {
- 637 while (cpu >= 0 && !CPU_ISSET(cpu, &cpumask))
- 638 cpu--;
- 639 if (cpu < 0)
- 640 break;
- 641 child = NULL;
- 642 } else
- 643 child = &cg->cg_child[i - 1];
- 644
- 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
- 647 if (match & CPU_SEARCH_HIGHEST)
- 648 hgroup.cs_cpu = -1;
- 649 if (child) { /* Handle child CPU group. */
- 650 CPU_NAND(&cpumask, &child->cg_mask);
- 651 switch (match) {
- 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
- 655 case CPU_SEARCH_HIGHEST:
- 656 load = cpu_search_highest(child, &hgroup);
- 657 break;
- 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
- 661 }
- 662 } else {
- /**********************************************************************************
- * tdq_load:對(duì)應(yīng)cpu運(yùn)行隊(duì)列的負(fù)載,當(dāng)把一個(gè)thread添加到struct tdq中三個(gè)運(yùn)行
- 隊(duì)列中的一個(gè)時(shí),就會(huì)遞增tdq_load成員,該成員同時(shí)也用來
- 選擇運(yùn)行隊(duì)列負(fù)載最高和最低的CPU。
- tdq_transferable: 一個(gè)計(jì)數(shù)器,相應(yīng)cpu運(yùn)行隊(duì)列中可遷移線程的數(shù)目。在函數(shù)
- tdq_runq_add中遞增。
- 663-684:檢查相應(yīng)cpu運(yùn)行隊(duì)列上的負(fù)載, Handle child CPU.
-
- 663:tdq為&tdq_cpu[cpu]。
- 665-666:更新一個(gè)每cpu變量randomval。
- 678-684:將當(dāng)前檢查cpu運(yùn)行隊(duì)列的負(fù)載即logical cpu id保存到局部變量hgroup中。
- 從這里可以看出,上面636-641之間的while循環(huán)將cpu限定在相應(yīng)的cpu_group中
- ,這里的CPU_ISSET宏再次將cpu限制在所要檢查的特定cpu集合中。
- 在一般情況下,只有當(dāng)相應(yīng)cpu運(yùn)行隊(duì)列中可遷移的thread數(shù)目非零時(shí),
- 變量hgroup中才包含有意義的值。
- 686:遞增total。
- ***************************************/
- 663 tdq = TDQ_CPU(cpu);
- 664 load = tdq->tdq_load * 256;
- 665 rndptr = DPCPU_PTR(randomval);
- 666 rnd = (*rndptr = *rndptr * 69069 + 5) >> 26;
- 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
- 678 if (match & CPU_SEARCH_HIGHEST)
- 679 if (tdq->tdq_load >= hgroup.cs_limit &&
- 680 tdq->tdq_transferable &&
- 681 CPU_ISSET(cpu, &hgroup.cs_mask)) {
- 682 hgroup.cs_cpu = cpu;
- 683 hgroup.cs_load = load - rnd;
- 684 }
- 685 }
- 686 total += load;
- 687
- 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
- /*********************************************************************************
- * 698-705:
- 變量high指向的struct cpu_search對(duì)象始終包含的是當(dāng)前cpu_group中運(yùn)行隊(duì)列負(fù)載
- 最高cpu的logical cpu id及其運(yùn)行隊(duì)列的負(fù)載。
- **********************/
- 698 if (match & CPU_SEARCH_HIGHEST)
- 699 if (hgroup.cs_cpu >= 0 &&
- 700 (load > hload ||
- 701 (load == hload && hgroup.cs_load > high->cs_load))) {
- 702 hload = load;
- 703 high->cs_cpu = hgroup.cs_cpu;
- 704 high->cs_load = hgroup.cs_load;
- 705 }
- /********************************************************************************
- * 706-711:
- 這里將執(zhí)行else語句,遞減cpu.
- ***********************************/
- 706 if (child) {
- 707 i--;
- 708 if (i == 0 && CPU_EMPTY(&cpumask))
- 709 break;
- 710 } else
- 711 cpu--;
- 712 }
- 713 return (total);
- 714 }
復(fù)制代碼 |
|