[커널 18차] 99주차

2023.04.16 18:29

kkr 조회 수:77

스케쥴러 로드밸런스 진행중

git : https://github.com/iamroot18/5.10/commit/f3df1d06d49a6dff3dd8435fc2f41fafe98cc78b

      https://github.com/iamroot18/5.10/commit/0172167f91e4ebb58ecd5a8452ea80f9b98c407c

 

diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
index 359d00fab3f8..9385641d58ef 100644
--- a/drivers/base/arch_topology.c
+++ b/drivers/base/arch_topology.c
@@ -948,15 +948,31 @@ static int __init parse_dt_topology(void)
 struct cpu_topology cpu_topology[NR_CPUS];
 EXPORT_SYMBOL_GPL(cpu_topology);
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - @cpu가 속한 node에서 시작하여 core_sibling, llc_sibling이 각각 포함되있는지 
+ *  검사해 해당 cpu-list가 전부 속해있다면 해당 cpu-list로 대체해서 return한다.
+ * - arm64기준으로는 같은 cluster 내의 core cpumask.
+ */
 const struct cpumask *cpu_coregroup_mask(int cpu)
 {
     const cpumask_t *core_mask = cpumask_of_node(cpu_to_node(cpu));
 
     /* Find the smaller of NUMA, core or LLC siblings */
+/*
+ * IAMROOT, 2023.04.15:
+ * - sibling이 core_mask에 다 포함되있는거면 sibling으로 대체한다.
+ */
     if (cpumask_subset(&cpu_topology[cpu].core_sibling, core_mask)) {
         /* not numa in package, lets use the package siblings */
         core_mask = &cpu_topology[cpu].core_sibling;
     }
+
+/*
+ * IAMROOT, 2023.04.15:
+ * - llc(last level cache)가 있는경우 llc_sibling이 완전히 core_mask에 포함되있는지 검사한다.
+ *   포함되면 llc_sibling으로 대체한다.
+ */
     if (cpu_topology[cpu].llc_id != -1) {
         if (cpumask_subset(&cpu_topology[cpu].llc_sibling, core_mask))
             core_mask = &cpu_topology[cpu].llc_sibling;
diff --git a/include/linux/arch_topology.h b/include/linux/arch_topology.h
index cc2959142171..f6ba9576c2e9 100644
--- a/include/linux/arch_topology.h
+++ b/include/linux/arch_topology.h
@@ -73,6 +73,10 @@ static inline unsigned long topology_get_thermal_pressure(int cpu)
 void topology_set_thermal_pressure(const struct cpumask *cpus,
                    unsigned long th_pressure);
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - arm64는 smt가 현재 없다. thread_id와 thread_sibling은 설정이 안될것이다.
+ */
 struct cpu_topology {
     int thread_id;
     int core_id;
@@ -80,6 +84,12 @@ struct cpu_topology {
     int llc_id;
     cpumask_t thread_sibling;
     cpumask_t core_sibling;
+
+/*
+ * IAMROOT, 2023.04.15:
+ * - cache를 공유하는 list.
+ *   last level cache
+ */
     cpumask_t llc_sibling;
 };
 
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 6bffa02a7b9c..03a0394da2ba 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -316,6 +316,10 @@ extern int cpumask_next_wrap(int n, const struct cpumask *mask, int start, bool
  *
  * After the loop, cpu is >= nr_cpu_ids.
  */
+/*
+ * IAMROOT, 2023.04.15:
+ * - mask1 & mask2를 한후 iterate
+ */
 #define for_each_cpu_and(cpu, mask1, mask2)                \
     for ((cpu) = -1;                        \
         (cpu) = cpumask_next_and((cpu), (mask1), (mask2)),    \
@@ -488,6 +492,11 @@ static inline void cpumask_xor(struct cpumask *dstp,
  *
  * If *@dstp is empty, returns 0, else returns 1
  */
+/*
+ * IAMROOT, 2023.04.15:
+ * - @src2p를 먼저 not을 한후 @src1p와 and한다.
+ *   *src1p & ~*src2p
+ */
 static inline int cpumask_andnot(struct cpumask *dstp,
                   const struct cpumask *src1p,
                   const struct cpumask *src2p)
diff --git a/include/linux/sched/isolation.h b/include/linux/sched/isolation.h
index 47f9167a04af..13e307474fa1 100644
--- a/include/linux/sched/isolation.h
+++ b/include/linux/sched/isolation.h
@@ -5,6 +5,11 @@
 #include <linux/init.h>
 #include <linux/tick.h>
 
+
+/*
+ * IAMROOT, 2023.04.15:
+ * - housekeeping_isolcpus_setup() 참고
+ */
 enum hk_flags {
     HK_FLAG_TIMER        = 1,
     HK_FLAG_RCU        = (1 << 1),
diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h
index fd0e62bdb315..0d6751c8a6c2 100644
--- a/include/linux/sched/topology.h
+++ b/include/linux/sched/topology.h
@@ -81,6 +81,17 @@ struct sched_domain {
     struct sched_domain __rcu *parent;    /* top domain must be null terminated */
     struct sched_domain __rcu *child;    /* bottom domain must be null terminated */
     struct sched_group *groups;    /* the balancing groups of the domain */
+
+/*
+ * IAMROOT, 2023.04.15:
+ * - sd_init()등에서 초기화 하는게 보인다.
+ * - sd_init()에서의 사용 초기값들
+ *   min_interval     : cpu개수를 기준으로 결정된다. cpu 3개 = 3ms.
+ *   max_interval     : min_interval * 2로 결정된다.
+ *   imbalance_pct    : load balance을 할때 특정 기준값을 넘으면 balance를 수행하라는 한계값.
+ *                      117을 기본으로 사용했다.
+ *   balance_interval : cpu개수를 기준으로 결정된다.
+ */
     unsigned long min_interval;    /* Minimum balance interval ms */
     unsigned long max_interval;    /* Maximum balance interval ms */
     unsigned int busy_factor;    /* less balancing by factor if busy */
@@ -178,6 +189,11 @@ bool cpus_share_cache(int this_cpu, int that_cpu);
 typedef const struct cpumask *(*sched_domain_mask_f)(int cpu);
 typedef int (*sched_domain_flags_f)(void);
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - overlap이 될수있는 schedule domain topology level.
+ *   numa topology에만 해당된다.
+ */
 #define SDTL_OVERLAP    0x01
 
 struct sd_data {
@@ -187,6 +203,29 @@ struct sd_data {
     struct sched_group_capacity *__percpu *sgc;
 };
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - topology level 구성. 총 9단계로 구성된다.
+ *   distance단계부턴 cpu가 겹칠수 있다. 겹칠수있는 sdt는 SDTL_OVERLAP
+ *
+ *                                         mask       | sd_flags       |    flags     |
+ *   +----------+----------------+--------------------+----------------+--------------+
+ *   | 종료확인 | NULL           | -                  |       -        |      -       |
+ *   +----------+----------------+--------------------+----------------+--------------|
+ *   |          | 30(distance)   |                    |                |              |
+ *   |          | 25             |                    |                |              |
+ *   | NUMA     | 20             | sd_numa_mask       | cpu_numa_flags | SDTL_OVERLAP |
+ *   |          | 15             |                    |                |              |
+ *   |          | 10(local node) |                    |                |      0       |
+ *   +----------+----------------+--------------------+----------------+--------------+
+ *   |          | die            | cpu_cpu_mask       | NULL           |      0       |
+ *   | default  | mc             | cpu_coregroup_mask | cpu_core_flags |      0       |
+ *   |          | smt            | cpu_smt_mask       | cpu_smt_flags  |      0       |
+ *   +----------+----------------+--------------------+----------------+--------------+
+ *   - default_topology 참고
+ * - ps)
+ *   smt는 arm에는 없고 intel, amd, powerpc에만 현재 존재한다.
+ */
 struct sched_domain_topology_level {
     sched_domain_mask_f mask;
     sched_domain_flags_f sd_flags;
diff --git a/include/linux/topology.h b/include/linux/topology.h
index 8b6750021ca4..2f69424f434d 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -215,12 +215,20 @@ static inline int cpu_to_mem(int cpu)
 #endif
 
 #if defined(CONFIG_SCHED_SMT) && !defined(cpu_smt_mask)
+/*
+ * IAMROOT, 2023.04.15:
+ * - arm64는 현재 smt가 없다.
+ */
 static inline const struct cpumask *cpu_smt_mask(int cpu)
 {
     return topology_sibling_cpumask(cpu);
 }
 #endif
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - @cpu가 속한 node의 cpumask를 return한다.
+ */
 static inline const struct cpumask *cpu_cpu_mask(int cpu)
 {
     return cpumask_of_node(cpu_to_node(cpu));
diff --git a/kernel/sched/isolation.c b/kernel/sched/isolation.c
index 7f06eaf12818..0d14df472d60 100644
--- a/kernel/sched/isolation.c
+++ b/kernel/sched/isolation.c
@@ -11,7 +11,18 @@
 
 DEFINE_STATIC_KEY_FALSE(housekeeping_overridden);
 EXPORT_SYMBOL_GPL(housekeeping_overridden);
+
+/*
+ * IAMROOT, 2023.04.15:
+ * - housekeeping_setup() 참고.
+ *   isolate cpu가 아닌 cpu-list
+ */
 static cpumask_var_t housekeeping_mask;
+/*
+ * IAMROOT, 2023.04.15:
+ * - housekeeping_setup() 참고.
+ *   isolate 종류(HK_FLAG_DOMAIN)
+ */
 static unsigned int housekeeping_flags;
 
 bool housekeeping_enabled(enum hk_flags flags)
@@ -37,6 +48,12 @@ int housekeeping_any_cpu(enum hk_flags flags)
 }
 EXPORT_SYMBOL_GPL(housekeeping_any_cpu);
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - housekeeping_flags에 flags가 set되있으면 해당 flags로 housekeeping 설정이 있다는 뜻.
+ *   housekeeping이 cpu-list를 reteurn한다.
+ *   flag가 없다면 cpu_possible_mask(전체 cpu라는 뜻) return.
+ */
 const struct cpumask *housekeeping_cpumask(enum hk_flags flags)
 {
     if (static_branch_unlikely(&housekeeping_overridden))
@@ -77,11 +94,23 @@ void __init housekeeping_init(void)
     WARN_ON_ONCE(cpumask_empty(housekeeping_mask));
 }
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - @str format은 다음과 같은 상황이였는데
+ *   Format: [flag-list,]<cpu-list>
+ *   이전에 flag-list를 건너 뛴 상태이므로 cpu-list만 남겨져 있다.
+ *   (ex, 1,2,10-15)
+ *   이 string을 bitmap으로 만든다.
+ */
 static int __init housekeeping_setup(char *str, enum hk_flags flags)
 {
     cpumask_var_t non_housekeeping_mask;
     cpumask_var_t tmp;
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - flag가 설정된 cpu들이 non_housekeeping_mask에 설정된다.
+ */
     alloc_bootmem_cpumask_var(&non_housekeeping_mask);
     if (cpulist_parse(str, non_housekeeping_mask) < 0) {
         pr_warn("Housekeeping: nohz_full= or isolcpus= incorrect CPU range\n");
@@ -90,11 +119,26 @@ static int __init housekeeping_setup(char *str, enum hk_flags flags)
     }
 
     alloc_bootmem_cpumask_var(&tmp);
+
+/*
+ * IAMROOT, 2023.04.15:
+ * - 기존에 한번도 설정한적이 없는경우.
+ */
     if (!housekeeping_flags) {
         alloc_bootmem_cpumask_var(&housekeeping_mask);
+
+/*
+ * IAMROOT, 2023.04.15:
+ * - cpu-list 범위 밖 cpu들을 housekeeping_mask에 저장한다.
+ */
         cpumask_andnot(housekeeping_mask,
                    cpu_possible_mask, non_housekeeping_mask);
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - 전부 present된 cpu들만 flag가 set되있다면 평범하게 동작할수있는 cpu가 1개도
+ *   없는 개념이 되는 상황이다. 거기에 대한 예외처리.
+ */
         cpumask_andnot(tmp, cpu_present_mask, non_housekeeping_mask);
         if (cpumask_empty(tmp)) {
             pr_warn("Housekeeping: must include one present CPU, "
@@ -102,7 +146,19 @@ static int __init housekeeping_setup(char *str, enum hk_flags flags)
             __cpumask_set_cpu(smp_processor_id(), housekeeping_mask);
             __cpumask_clear_cpu(smp_processor_id(), non_housekeeping_mask);
         }
+
+/*
+ * IAMROOT, 2023.04.15:
+ * - 한번이라도 설정한경우, cpu 검사만을 하고 flag를 추가하는 식으로 진행한다.
+ */
     } else {
+
+/*
+ * IAMROOT, 2023.04.15:
+ * - tmp에서는 non_housekeeping_mask이 설정안된 cpu들만 남게된다.
+ *   present_mask를 통해 최소 1개의 cpu라도 있도록 예외처리를 하고,
+ *   최종적으로 non_housekeeping_mask가 설정이 안된 possible cpu만이 tmp에 남게된다.
+ */
         cpumask_andnot(tmp, cpu_present_mask, non_housekeeping_mask);
         if (cpumask_empty(tmp))
             __cpumask_clear_cpu(smp_processor_id(), non_housekeeping_mask);
@@ -145,6 +201,41 @@ static int __init housekeeping_nohz_full_setup(char *str)
 }
 __setup("nohz_full=", housekeeping_nohz_full_setup);
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - admin-guide/kernel-parameters.txt 참고 (papago)
+ *   nohz
+ *   단일 작업이 실행될 때 틱을 비활성화합니다. 
+ *
+ *   나머지 1Hz 틱은 작업 대기열로 오프로드되며, 작업 대기열은 
+ *   /sys/devices/virtual/workqueue/cpumask sysfs 파일을 통해 구성된 
+ *   전역 작업 대기열의 선호도를 통해 또는 아래에 설명된 '도메인' 플래그를 
+ *   사용하여 하우스키핑에 연결해야 합니다.
+ *
+ *   참고: 기본적으로 글로벌 작업 대기열은 모든 CPU에서 실행되므로 
+ *   개별 CPU를 보호하려면 부팅 후 'cpumask' 파일을 수동으로 구성해야 합니다. 
+ *
+ *   domain
+ *   일반 SMP 밸런싱 및 스케줄링 알고리즘에서 격리합니다.
+ *   이 방법으로 도메인 격리를 수행하는 것은 되돌릴 수 없습니다.
+ *   isolcpus를 통해 격리된 CPU를 도메인으로 다시 가져올 수 없습니다.
+ *   cpuset.sched_load_balance 파일을 통해 스케줄러 로드 밸런싱을 
+ *   비활성화하려면 대신 cpuset를 사용하는 것이 좋습니다.
+ *   CPU가 언제든지 격리된 세트 안팎으로 이동할 수 있는 훨씬 더 유연한 
+ *   인터페이스를 제공합니다.
+ *
+ *   CPU 선호도 syscalls 또는 cpuset을 통해 격리된 CPU로 프로세스를 
+ *   이동하거나 분리할 수 있습니다.
+ *   <cpu number>는 0에서 시작하고 최대값은 시스템의 CPU 수 - 1입니다. 
+ *
+ * - flags가 없으면 domain이 기본값이다.
+ *   ex) isolcpus=1,5,10-30 -> 23개의 cpu가 domain에 참여하지 않는다는뜻.
+ *
+ * - @str format은 다음과 같다.
+ *   Format: [flag-list,]<cpu-list>
+ *   flag-list에서 미리 관련 flag를 정리해서 설정한후, cpu-list만 남겨
+ *   cpu-list string으로 bitmap을 만드는 구조가 된다.
+ */
 static int __init housekeeping_isolcpus_setup(char *str)
 {
     unsigned int flags = 0;
diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
index 3801c754de2b..8bb900307334 100644
--- a/kernel/sched/topology.c
+++ b/kernel/sched/topology.c
@@ -588,6 +588,11 @@ void init_defrootdomain(void)
     atomic_set(&def_root_domain.refcount, 1);
 }
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - rootdomain에 대한 default값을 하나 할당하고 초기화해서 return한다.
+ *   isolate cpu를 제외한 모든 cpu들이 기본적으로 root domain에 참가한다.
+ */
 static struct root_domain *alloc_rootdomain(void)
 {
     struct root_domain *rd;
@@ -1309,6 +1314,16 @@ struct asym_cap_data {
  * capacity.
  * The lifespan of data is unlimited.
  */
+/*
+ * IAMROOT, 2023.04.15:
+ * - asym_cpu_capacity_update_data()참고 
+ * - ex) CPU0~3 : 1024, CPU4-7 : 436 인 경우
+ *   1024, 436에 대한 node가 존재한다.
+ *   node1->capacity = 1024;
+ *   node1->cpus = cpu bitmaps에 cpu 0~3 set.
+ *   node2->capacity = 436;
+ *   node2->cpus = cpu bitmaps에 cpu 4~7 set.
+ */
 static LIST_HEAD(asym_cap_list);
 
 #define cpu_capacity_span(asym_data) to_cpumask((asym_data)->cpus)
@@ -1317,6 +1332,21 @@ static LIST_HEAD(asym_cap_list);
  * Verify whether there is any CPU capacity asymmetry in a given sched domain.
  * Provides sd_flags reflecting the asymmetry scope.
  */
+/*
+ * IAMROOT, 2023.04.15:
+ * - papago
+ *   지정된 sched 도메인에 CPU 용량 비대칭이 있는지 확인합니다.
+ *   비대칭 범위를 반영하는 sd_flags를 제공합니다.
+ * - ex) 0,1 = 1024 capacity, 0,2 = 512 capacity, asym_cap_list에 전부있다고 가정
+ *
+ *   SMT 0,1 / 2,3 -> 0,1 : count 1, miss 1 
+ *                    2,3 : count 1, miss 1
+ *                    각각 동일한 cpu capacity의 그룹이므로 비대칭이 아니다.
+ *                    return 0.
+ *   DIE 0,1,2,3 -> count 2, miss 0
+ *                  다른 cpu capacity에 있기 때문에 비대칭이다. return 
+ *                  return SD_ASYM_CPUCAPACITY | SD_ASYM_CPUCAPACITY_FULL
+ */
 static inline int
 asym_cpu_capacity_classify(const struct cpumask *sd_span,
                const struct cpumask *cpu_map)
@@ -1330,6 +1360,15 @@ asym_cpu_capacity_classify(const struct cpumask *sd_span,
      * CPUs capacities). Take into account CPUs that might be offline:
      * skip those.
      */
+/*
+ * IAMROOT, 2023.04.15:
+ * - papago
+ *   이 도메인에 걸쳐 있는 고유한 CPU 용량의 수를 계산합니다(sched_domain 
+ *   CPU 마스크를 사용 가능한 CPU 용량을 나타내는 마스크와 비교).
+ *   오프라인일 수 있는 CPU를 고려하십시오.
+ *   건너 뛰십시오.
+ * - span이 포함되있으면 count, topology범위를 벗어난거라면 miss가 된다.
+ */
     list_for_each_entry(entry, &asym_cap_list, link) {
         if (cpumask_intersects(sd_span, cpu_capacity_span(entry)))
             ++count;
@@ -1351,16 +1390,29 @@ asym_cpu_capacity_classify(const struct cpumask *sd_span,
 
 }
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - @cpu의 capacity와 동일한게 이미 asym_cap_list에 있는지 확인하고, 없으면 
+ *   추가한다. 처리후 해당 entry의 cpu bitmap에 @cpu를 set한다.
+ */
 static inline void asym_cpu_capacity_update_data(int cpu)
 {
     unsigned long capacity = arch_scale_cpu_capacity(cpu);
     struct asym_cap_data *entry = NULL;
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - 해당 capactiy에 대해 이미 존재하면 cpu bitmap에만 cpu set..
+ */
     list_for_each_entry(entry, &asym_cap_list, link) {
         if (capacity == entry->capacity)
             goto done;
     }
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - 자료구조를 할당하고 asym_cap_list에 추가한다.
+ */
     entry = kzalloc(sizeof(*entry) + cpumask_size(), GFP_KERNEL);
     if (WARN_ONCE(!entry, "Failed to allocate memory for asymmetry data\n"))
         return;
@@ -1380,6 +1432,8 @@ static inline void asym_cpu_capacity_update_data(int cpu)
  * - google-translate
  * cpu capacities로 그룹화된 CPU의 빌드업/업데이트 목록 업데이트에는 CPU 토폴로지 변경을
  * 나타내는 상태로 sched 도메인을 재구축하라는 명시적 요청이 필요합니다.
+ *
+ * - cpu capacity별 자료구조인 asym_cap_list를 설정한다. 
  */
 static void asym_cpu_capacity_scan(void)
 {
@@ -1389,9 +1443,18 @@ static void asym_cpu_capacity_scan(void)
     list_for_each_entry(entry, &asym_cap_list, link)
         cpumask_clear(cpu_capacity_span(entry));
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - HK_FLAG_DOMAIN이 set되있다면 isolate가 안된 cpu들에 한한 iterate를 하면서,
+ *   해당 cpu capacity에 대해 asym_cap_list에 추가한다
+ */
     for_each_cpu_and(cpu, cpu_possible_mask, housekeeping_cpumask(HK_FLAG_DOMAIN))
         asym_cpu_capacity_update_data(cpu);
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - 해당 cpapcity에 대한 cpu가 한개도 없으면 그냥 entry를 지워버린다.
+ */
     list_for_each_entry_safe(entry, next, &asym_cap_list, link) {
         if (cpumask_empty(cpu_capacity_span(entry))) {
             list_del(&entry->link);
@@ -1403,6 +1466,10 @@ static void asym_cpu_capacity_scan(void)
      * Only one capacity value has been detected i.e. this system is symmetric.
      * No need to keep this data around.
      */
+/*
+ * IAMROOT, 2023.04.15:
+ * - 단일 capacity면 관리할 필요가없으므로(모든 cpu가 같다는것.) 그냥 다 지워버린다.
+ */
     if (list_is_singular(&asym_cap_list)) {
         entry = list_first_entry(&asym_cap_list, typeof(*entry), link);
         list_del(&entry->link);
@@ -1467,16 +1534,30 @@ static void __free_domain_allocs(struct s_data *d, enum s_alloc what,
     }
 }
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - sdt(schedule domain topology)별 pcpu 할당 및 초기화,
+ *   @d에 대한 schedule domain, root domain 초기화.
+ */
 static enum s_alloc
 __visit_domain_allocation_hell(struct s_data *d, const struct cpumask *cpu_map)
 {
     memset(d, 0, sizeof(*d));
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - 각 sdt별 pcp할당 및 초기화.
+ */
     if (__sdt_alloc(cpu_map))
         return sa_sd_storage;
     d->sd = alloc_percpu(struct sched_domain *);
     if (!d->sd)
         return sa_sd_storage;
+
+/*
+ * IAMROOT, 2023.04.15:
+ * - rootdomain 생성.
+ */
     d->rd = alloc_rootdomain();
     if (!d->rd)
         return sa_sd;
@@ -1510,10 +1591,21 @@ static void claim_allocations(int cpu, struct sched_domain *sd)
 enum numa_topology_type sched_numa_topology_type;
 
 static int            sched_domains_numa_levels;
+/*
+ * IAMROOT, 2023.04.15:
+ * - build중인 schedule domain 표시
+ */
 static int            sched_domains_curr_level;
 
 int                sched_max_numa_distance;
 static int            *sched_domains_numa_distance;
+
+/*
+ * IAMROOT, 2023.04.15:
+ * - sched_domains_numa_masks[distance][node id] = nodemask
+ * - sched_init_numa()에서 만들어진다.
+ * - node id를 기준으로 distance이하의 인접 node에대한 nodemask가 설정된다.
+ */
 static struct cpumask        ***sched_domains_numa_masks;
 int __read_mostly        node_reclaim_distance = RECLAIM_DISTANCE;
 
@@ -1542,6 +1634,10 @@ static unsigned long __read_mostly *sched_numa_onlined_nodes;
      SD_NUMA        |    \
      SD_ASYM_PACKING)
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - 
+ */
 static struct sched_domain *
 sd_init(struct sched_domain_topology_level *tl,
     const struct cpumask *cpu_map,
@@ -1556,13 +1652,37 @@ sd_init(struct sched_domain_topology_level *tl,
     /*
      * Ugly hack to pass state to sd_numa_mask()...
      */
+/*
+ * IAMROOT, 2023.04.15:
+ * - 현재 진행중인 sdl을 표시해놓는 개념이다.
+ */
     sched_domains_curr_level = tl->numa_level;
 #endif
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - tl별 mask함수에서 @@cpu에 맞는 mask를 가져오고, 해당 mask의 weight를 가져온다.
+ *   ex) cpu_smt_mask,
+ *       cpu_coregroup_mask,
+ *       cpu_cpu_mask,
+ *       sd_numa_mask
+ */
     sd_weight = cpumask_weight(tl->mask(cpu));
 
+
+/*
+ * IAMROOT, 2023.04.15:
+ * - cpu_numa_flags : SD_NUMA
+ *   cpu_core_flags : SD_SHARE_PKG_RESOURCES
+ *   cpu_smt_flags  : D_SHARE_CPUCAPACITY | SD_SHARE_PKG_RESOURCES
+ */
     if (tl->sd_flags)
         sd_flags = (*tl->sd_flags)();
+
+/*
+ * IAMROOT, 2023.04.15:
+ * - 검사처리.
+ */
     if (WARN_ONCE(sd_flags & ~TOPOLOGY_SD_FLAGS,
             "wrong sd_flags in topology description\n"))
         sd_flags &= TOPOLOGY_SD_FLAGS;
@@ -1671,6 +1791,11 @@ static struct sched_domain_topology_level default_topology[] = {
 static struct sched_domain_topology_level *sched_domain_topology =
     default_topology;
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - schedule domain topology level만큼을 iterate한다.
+ * - sched_domain_topology_level 참고
+ */
 #define for_each_sd_topology(tl)            \
     for (tl = sched_domain_topology; tl->mask; tl++)
 
@@ -1684,6 +1809,32 @@ void set_sched_topology(struct sched_domain_topology_level *tl)
 
 #ifdef CONFIG_NUMA
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - @sched_domains_curr_level를 기준으로 @cpu가 속한 node에 대한 
+ *   sched_domains_numa_masks를 return한다.
+ *
+ * - ex)   A, B, C, D는 node 이름.

+ *         A-- 20 -- B
+ *         |         |
+ *        15        20
+ *         |         |
+ *         C-- 20 -- D
+ *
+ *   
+ *   1. 요청한 cpu가 node A에 있고,
+ *      sched_domains_curr_level = 1(1 == 15라는 의미)인 경우.
+ *      node A, node C에 포함된 cpu들(cpumask) return.
+ *
+ *   2. 요청한 cpu가 node C에 있고,
+ *      sched_domains_curr_level = 2(2 == 20라는 의미)인 경우.
+ *      node A, node C, node D에 포함된 cpu들(cpumask) return.
+ *
+ *   3. 요청한 cpu가 node D에 있고,
+ *      sched_domains_curr_level = 2(2 == 20라는 의미)인 경우.
+ *      node C, node D, node B에 포함된 cpu들(cpumask) return.
+ */
 static const struct cpumask *sd_numa_mask(int cpu)
 {
     return sched_domains_numa_masks[sched_domains_curr_level][cpu_to_node(cpu)];
@@ -2004,10 +2155,14 @@ void sched_init_numa(void)
      *                           [0][1] -> distance 10, node 1 =  0b0010
      *                           [0][2] -> distance 10, node 2 =  0b0100
      *                           [0][3] -> distance 10, node 3 =  0b1000
-     *                           [1][0] -> distance 15, node 0 =  0b0010
-     *                           [1][1] -> distance 15, node 1 =  0b0001
-     *                           [1][2] -> distance 15, node 2 =  0b1000
-     *                           [1][3] -> distance 15, node 3 =  0b0100
+     *                           [1][0] -> distance 15, node 0 =  0b0011
+     *                           [1][1] -> distance 15, node 1 =  0b0011
+     *                           [1][2] -> distance 15, node 2 =  0b1100
+     *                           [1][3] -> distance 15, node 3 =  0b1100
+     *                           [2][0] -> distance 20, node 0 =  0b0111
+     *                           [2][1] -> distance 20, node 1 =  0b0011
+     *                           [2][2] -> distance 20, node 2 =  0b1101
+     *                           [2][3] -> distance 20, node 3 =  0b1100
      *                           ...
      */
     /* Compute default topology size */
@@ -2180,14 +2335,23 @@ int sched_numa_find_closest(const struct cpumask *cpus, int cpu)
 
 #endif /* CONFIG_NUMA */
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - sdt level만큼의 pcpu를 생성 및 초기화한다.
+ */
 static int __sdt_alloc(const struct cpumask *cpu_map)
 {
     struct sched_domain_topology_level *tl;
     int j;
 
+
     for_each_sd_topology(tl) {
         struct sd_data *sdd = &tl->data;
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - pcpu를 할당한다.
+ */
         sdd->sd = alloc_percpu(struct sched_domain *);
         if (!sdd->sd)
             return -ENOMEM;
@@ -2204,6 +2368,11 @@ static int __sdt_alloc(const struct cpumask *cpu_map)
         if (!sdd->sgc)
             return -ENOMEM;
 
+
+/*
+ * IAMROOT, 2023.04.15:
+ * - 만든 pcpu에 대해서 초기화를 수행한다.
+ */
         for_each_cpu(j, cpu_map) {
             struct sched_domain *sd;
             struct sched_domain_shared *sds;
@@ -2285,6 +2454,10 @@ static void __sdt_free(const struct cpumask *cpu_map)
     }
 }
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - 
+ */
 static struct sched_domain *build_sched_domain(struct sched_domain_topology_level *tl,
         const struct cpumask *cpu_map, struct sched_domain_attr *attr,
         struct sched_domain *child, int cpu)
@@ -2319,6 +2492,11 @@ static struct sched_domain *build_sched_domain(struct sched_domain_topology_leve
  * Ensure topology masks are sane, i.e. there are no conflicts (overlaps) for
  * any two given CPUs at this (non-NUMA) topology level.
  */
+/*
+ * IAMROOT, 2023.04.15:
+ * - sanity check. 설정이 잘못됬는지 확인한다. overlap이 없는 level인데 overlap이
+ *   된것을 확인한다.
+ */
 static bool topology_span_sane(struct sched_domain_topology_level *tl,
                   const struct cpumask *cpu_map, int cpu)
 {
@@ -2334,6 +2512,14 @@ static bool topology_span_sane(struct sched_domain_topology_level *tl,
      * breaking the sched_group lists - i.e. a later get_group() pass
      * breaks the linking done for an earlier span.
      */
+/*
+ * IAMROOT, 2023.04.15:
+ * - papago
+ *   NUMA가 아닌 수준은 부분적으로 겹칠 수 없습니다. 완전히 같거나 
+ *   완전히 분리되어야 합니다. 그렇지 않으면 sched_group 목록이 깨질 수 
+ *   있습니다. 즉, 나중에 get_group() 패스가 이전 범위에 대해 수행된 
+ *   연결을 깨뜨립니다.
+ */
     for_each_cpu(i, cpu_map) {
         if (i == cpu)
             continue;
@@ -2343,6 +2529,14 @@ static bool topology_span_sane(struct sched_domain_topology_level *tl,
          * remove CPUs, which only lessens our ability to detect
          * overlaps
          */
+/*
+ * IAMROOT, 2023.04.15:
+ * - papago
+ *   우리가 만들려는 토폴로지와 정확히 일치하도록 'cpu_map'을 사용하여 
+ *   모든 마스크를 '및' 해야 하지만 이렇게 하면 CPU만 제거할 수 있으므로 
+ *   겹침을 감지하는 능력이 줄어들 뿐입니다.
+ * - 겹치면 안된다.
+ */
         if (!cpumask_equal(tl->mask(cpu), tl->mask(i)) &&
             cpumask_intersects(tl->mask(cpu), tl->mask(i)))
             return false;
@@ -2355,6 +2549,10 @@ static bool topology_span_sane(struct sched_domain_topology_level *tl,
  * Build sched domains for a given set of CPUs and attach the sched domains
  * to the individual CPUs
  */
+/*
+ * IAMROOT, 2023.04.15:
+ * - 
+ */
 static int
 build_sched_domains(const struct cpumask *cpu_map, struct sched_domain_attr *attr)
 {
@@ -2475,6 +2673,10 @@ int __weak arch_update_cpu_topology(void)
     return 0;
 }
 
+/*
+ * IAMROOT, 2023.04.15:
+ * - @ndoms개수만큼을 만들고, 해당 ndoms에 cpumask를 생성한다.
+ */
 cpumask_var_t *alloc_sched_domains(unsigned int ndoms)
 {
     int i;
@@ -2523,11 +2725,26 @@ int sched_init_domains(const struct cpumask *cpu_map)
      * - arm64에서는 아무것도 안한다.
      */
     arch_update_cpu_topology();
+
+/*
+ * IAMROOT, 2023.04.15:
+ * - asym cpu에 대한 자료구조 설정
+ */
     asym_cpu_capacity_scan();
     ndoms_cur = 1;
+
+/*
+ * IAMROOT, 2023.04.15:
+ * - 일단 1개를 만든다. 실패할경우 fallback_doms를 사용한다.
+ */
     doms_cur = alloc_sched_domains(ndoms_cur);
     if (!doms_cur)
         doms_cur = &fallback_doms;
+
+/*
+ * IAMROOT, 2023.04.15:
+ * - @cpu_map & housekeeping를 대상으로 build를 진행한다.
+ */
     cpumask_and(doms_cur[0], cpu_map, housekeeping_cpumask(HK_FLAG_DOMAIN));
     err = build_sched_domains(doms_cur[0], NULL);
 
 

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 스터디 정리 노트 공간입니다. woos 2016.05.14 626
207 [커널20차] 7주차 이경재 2023.06.18 78
206 [커널 18차] 108주차 kkr 2023.06.17 50
205 [커널 20차] 4주차 김희찬 2023.06.12 79
204 [커널 19차] 55 주차 Min 2023.06.10 28
203 [커널 19차] 54 주차 Min 2023.06.03 34
202 [커널 18차] 106주차 kkr 2023.06.03 65
201 [커널 20차] 3주차 김희찬 2023.06.03 73
200 [커널 19차] 52 ~ 53 주차 Min 2023.05.27 55
199 [커널 20차] 2주차 김희찬 2023.05.20 139
198 [커널 19차] 51 주차 Min 2023.05.13 45
197 [커널 20차] 1주차 김희찬 2023.05.13 193
196 [커널 18차] 102주차 kkr 2023.05.07 75
195 [커널 19차] 50 주차 Min 2023.05.07 31
194 [커널 19차] 49 주차 Min 2023.04.29 55
193 [커널 19차] 48 주차 Min 2023.04.23 83
192 [커널 18차] 100주차 kkr 2023.04.22 83
» [커널 18차] 99주차 kkr 2023.04.16 77
190 [커널 19차] 47 주차 Min 2023.04.15 41
189 [커널 19차] 45, 46 주차 Min 2023.04.10 59
188 [커널 19차] 43, 44 주차 이태백 2023.03.26 184
XE Login