[커널 18차] 73주차

2022.10.15 22:18

kkr 조회 수:44

gic 등록 진행중

 

git : https://github.com/iamroot18/5.10/commit/976847b3c293d4a555b50c594b2e88a3b712c8c9

 

diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
index 9b010ee29b42..1771cd2e5d38 100644
--- a/arch/arm64/include/asm/arch_gicv3.h
+++ b/arch/arm64/include/asm/arch_gicv3.h
@@ -77,6 +77,19 @@ static inline u32 gic_read_ctlr(void)
     return read_sysreg_s(SYS_ICC_CTLR_EL1);
 }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - @val을 write한다.
+ *   group1 interrupts are en/disable for the current security state.
+ *
+ * --- group1 interrupt은 security state 따라 다음과 같이 동작한다.
+ *
+ * - single security
+ *   irq로써 kernel이 받게된다.
+ *
+ * - two security
+ *   fiq로써 secure os가 받은후 el3를 통해서 kernel이 받게된다.
+ */
 static inline void gic_write_grpen1(u32 val)
 {
     write_sysreg_s(val, SYS_ICC_IGRPEN1_EL1);
@@ -114,6 +127,12 @@ static __always_inline void gic_write_pmr(u32 val)
     write_sysreg_s(val, SYS_ICC_PMR_EL1);
 }
 
+
+/*
+ * IAMROOT, 2022.10.15:
+ * - Interrupt Controller Running Priority Register
+ *   rpr은 64bits register지만 [7:0] priority만을 사용하기 위해 32bits로 가져온다.
+ */
 static inline u32 gic_read_rpr(void)
 {
     return read_sysreg_s(SYS_ICC_RPR_EL1);
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index fcb08da5b6e9..5993d900f862 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -436,6 +436,12 @@
 #define SYS_ICC_CTLR_EL1        sys_reg(3, 0, 12, 12, 4)
 #define SYS_ICC_SRE_EL1            sys_reg(3, 0, 12, 12, 5)
 #define SYS_ICC_IGRPEN0_EL1        sys_reg(3, 0, 12, 12, 6)
+
+/*
+ * IAMROOT, 2022.10.15:
+ * - Interrupt Controller Interrupt Group 1 Enable register
+ *   Controls whether Group 1 interrupts are enabled for the current Security state.
+ */
 #define SYS_ICC_IGRPEN1_EL1        sys_reg(3, 0, 12, 12, 7)
 
 #define SYS_CONTEXTIDR_EL1        sys_reg(3, 0, 13, 0, 1)
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index b872dee5bd75..8bbc189bf622 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -85,6 +85,11 @@ enum ipi_msg_type {
 
 static int ipi_irq_base __read_mostly;
 static int nr_ipi __read_mostly = NR_IPI;
+
+/*
+ * IAMROOT, 2022.10.15:
+ * - set_smp_ipi_range()에서 설정된다.
+ */
 static struct irq_desc *ipi_desc[NR_IPI] __read_mostly;
 
 static void ipi_setup(int cpu);
@@ -1047,11 +1052,20 @@ static void ipi_teardown(int cpu)
 }
 #endif
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - 
+ */
 void __init set_smp_ipi_range(int ipi_base, int n)
 {
     int i;
 
     WARN_ON(n < NR_IPI);
+
+/*
+ * IAMROOT, 2022.10.15:
+ * - gic_smp_init()에서 @n은 8개로 왔다. kernel은 7개까지만 사용하는듯 하다.
+ */
     nr_ipi = min(n, NR_IPI);
 
     for (i = 0; i < nr_ipi; i++) {
@@ -1062,6 +1076,10 @@ void __init set_smp_ipi_range(int ipi_base, int n)
         WARN_ON(err);
 
         ipi_desc[i] = irq_to_desc(ipi_base + i);
+/*
+ * IAMROOT, 2022.10.15:
+ * - ipi는 내부용이기 때문에 proc에서 보여줄 필요가 없다.
+ */
         irq_set_status_flags(ipi_base + i, IRQ_HIDDEN);
     }
 
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index d9eebd1d9073..96d3ee0d8cec 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -31,6 +31,11 @@
 
 #include "irq-gic-common.h"
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - GICD_INT_DEF_PRI == 0xA0
+ *   GICD_INT_NMI_PRI = (0xA0 & ~0x80) = 0x20
+ */
 #define GICD_INT_NMI_PRI    (GICD_INT_DEF_PRI & ~0x80)
 
 #define FLAGS_WORKAROUND_GICR_WAKER_MSM8996    (1ULL << 0)
@@ -129,6 +134,20 @@ EXPORT_SYMBOL(gic_nonsecure_priorities);
  * we need to shift down the priority programmed by software to match it
  * against the value returned by ICC_RPR_EL1.
  */
+/*
+ * IAMROOT, 2022.10.15:
+ * - papago
+ *   non-secure world가 group 0 인터럽트에 액세스할 때(SCR_EL3.FIQ == 0의 결과로),
+ *   ICC_RPR_EL1 레지스터를 읽으면 인터럽트 우선순위에 대한 distributor의 view가
+ *   반환됩니다.
+ *
+ *   GIC 보안이 활성화되면(GICD_CTLR.DS == 0) 소프트웨어에 의해 작성된 인터럽트
+ *   우선 순위가 distributor에 의해 non-secure 범위로 이동됩니다.
+ *
+ *   둘 다 true인 경우(gic_nonsecure_priorities가 활성화된 경우) ICC_RPR_EL1에서
+ *   반환된 값과 일치하도록 소프트웨어에 의해 프로그래밍된 우선 순위를 낮추어야
+ *   합니다.
+ */
 #define GICD_INT_RPR_PRI(priority)                    \
     ({                                \
         u32 __priority = (priority);                \
@@ -985,6 +1004,8 @@ static bool gic_has_group0(void)
 /*
  * IAMROOT, 2022.10.08:
  * - GICD류를 초기값으로 설정한다.
+ * - GICv3 Software Overview Official 의 4. Configuring the GIC참고
+ *   register 초기화 방법이 있다.
  */
 static void __init gic_dist_init(void)
 {
@@ -1021,9 +1042,40 @@ static void __init gic_dist_init(void)
  *   group1 - non-secure 
  *          - secure
  * - all bits set
- * - 현재 상태(GICD_CTLR.DS==0)
- *   0b1 When GICD_CTLR.DS==0, the corresponding interrupt is Non-secure Group 1.
- *   non secure group1로 가게 한다.
+ *
+ * - GICD_CTLR.DS 상태에서 따라 아래 초기화하는 레지스터의 기능이 바뀐다.
+ *
+ * --- GICD_CTLR는 다음 상태에 따라 register가 바뀐다. (Bank register)
+ *  - When access is Secure, in a system that supports two Security states:
+ *    EL3를 제외하고 나머지 EL에서 secure 상태를 나눠서 운영을 할지 말지.
+ *    secure가 접근하게되는 GICD_CTLR.
+ *
+ *  - When access is Non-secure, in a system that supports two Security states:
+ *    secure가 있는상태. kernel이 DS를 조작할이유가 없으므로 아에 DS bit가 없다.
+ *
+ *  - When in a system that supports only a single Security state:
+ *    secure가 없는상태.(kernel만 있는 상태) 무조건 disable security이므로
+ *    DS가 RAO/WI.
+ *
+ * --- GICD_CTLR.DS(disable security)
+
+ *  0b0 Non-secure accesses are not permitted to access and modify registers
+ *  that control Group 0 interrupts.
+ *  0b1 Non-secure accesses are permitted to access and modify registers
+ *  that control Group 0 interrupts.
+ *
+ *  If DS is written from 0 to 1 when GICD_CTLR.ARE_S == 1, then GICD_CTLR.ARE
+ *  for the single Security state is RAO/WI.
+ *  If the Distributor only supports a single Security state, this bit is RAO/WI.
+ *  If the Distributor supports two Security states, it IMPLEMENTATION
+ *  whether this bit is programmable or implemented as RAZ/WI.
+ *  When this field is set to 1, all accesses to GICD_CTLR access the single
+ *  Security state view, and all bits are accessible.
+ *
+ *  - DS가 RAO/WI(read as one / write ignore) 인 경우
+ *    1. ARE_S set인 경우
+ *    2. Distributor가 single security state만을 지원하는 경우
+ *
  */
     for (i = 32; i < GIC_LINE_NR; i += 32)
         writel_relaxed(~0, base + GICD_IGROUPR + i / 8);
@@ -1272,7 +1324,7 @@ static inline bool gic_dist_security_disabled(void)
 
 /*
  * IAMROOT, 2022.10.08:
- * - 
+ * -  group0, group1 int에 대한 설정 및 group1 int enable.
  */
 static void gic_cpu_sys_reg_init(void)
 {
@@ -1359,11 +1411,35 @@ static void gic_cpu_sys_reg_init(void)
  *   일부 펌웨어는 리셋 값에서 변경된 BPR(선점형 인터럽트가 전혀 작동하지 않도록
  *   충분히 큰 값)과 함께 커널로 전달합니다. BPR 복원에 0을 쓰는 것은 값을
  *   재설정하는 것입니다.
+ * - BPR(Binary Point Register)
  */
     gic_write_bpr1(0);
 
 /*
  * IAMROOT, 2022.10.08:
+ * - eoimode 설명(GICv3 Software Overview Official 참고)
+ *   EOImode = 0
+ *   A write to ICC_EOIR0_EL1 for Group 0 interrupts, or ICC_EOIR1_EL1 for Group 1
+ *   interrupts, performs both the priority drop and deactivation. This is the
+ *   model typically used for a simple bare metal environment.
+ *
+ *   EOImode = 1
+ *   A write to ICC_EOIR_EL10 for Group 0 interrupts, or ICC_EOIR1_EL1
+ *   for Group 1 interrupts results in a priority drop. A separate write to
+ *   ICC_DIR_EL1 is required for deactivation. This mode is often used for
+ *   virtualization purposes.
+ *
+ * --- eoimode example,  guest os한테 int50이 들어오는 상황
+ *  1. eoimode0
+ *    guest os한테 넘겨줌. drop / inactivate 둘다 발생. 
+ *    guest of가 다 처리할때까지 in50을 못받음.
+ *
+ *  1. eoimode1
+ *    guest os한테 넘겨줌. drop 발생. 
+ *    guest os가 처리중이여도 int50을 다시 받을수 있는 상태. 다른 guest os한테도
+ *    넘길수있음.
+ * ---
+ *
  * - eoimode 1로 할지, mode 0로 할지 결정.
  */
     if (static_branch_likely(&supports_deactivate_key)) {
@@ -1424,12 +1500,20 @@ static void gic_cpu_sys_reg_init(void)
     isb();
 
     /* ... and let's hit the road... */
+/*
+ * IAMROOT, 2022.10.15:
+ * - group1 int enable
+ */
     gic_write_grpen1(1);
 
     /* Keep the RSS capability status in per_cpu variable */
     per_cpu(has_rss, cpu) = !!(gic_read_ctlr() & ICC_CTLR_EL1_RSS);
 
     /* Check all the CPUs have capable of sending SGIs to other CPUs */
+/*
+ * IAMROOT, 2022.10.15:
+ * - 현재 cpu가 다른 cpu에 대해서 rss가 필요한데 rss가 없는 경우를 확인한다.
+ */
     for_each_online_cpu(i) {
         bool have_rss = per_cpu(has_rss, i) && per_cpu(has_rss, cpu);
 
@@ -1468,7 +1552,7 @@ static int gic_dist_supports_lpis(void)
 
 /*
  * IAMROOT, 2022.10.08:
- * - 
+ * - redist, group0/1등에 대한 설정.
  */
 static void gic_cpu_init(void)
 {
@@ -1516,6 +1600,10 @@ static void gic_cpu_init(void)
 #define MPIDR_TO_SGI_RS(mpidr)    (MPIDR_RS(mpidr) << ICC_SGI1R_RS_SHIFT)
 #define MPIDR_TO_SGI_CLUSTER_ID(mpidr)    ((mpidr) & ~0xFUL)
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - secondary cpu들의 gic초기화.
+ */
 static int gic_starting_cpu(unsigned int cpu)
 {
     gic_cpu_init();
@@ -1597,6 +1685,10 @@ static void gic_ipi_send_mask(struct irq_data *d, const struct cpumask *mask)
     isb();
 }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - 
+ */
 static void __init gic_smp_init(void)
 {
     struct irq_fwspec sgi_fwspec = {
@@ -1610,12 +1702,20 @@ static void __init gic_smp_init(void)
                   gic_starting_cpu, NULL);
 
     /* Register all 8 non-secure SGIs */
+/*
+ * IAMROOT, 2022.10.15:
+ * - 8개만큼(non-secure SGI개수)의 virq를 할당한다.
+ */
     base_sgi = __irq_domain_alloc_irqs(gic_data.domain, -1, 8,
                        NUMA_NO_NODE, &sgi_fwspec,
                        false, NULL);
     if (WARN_ON(base_sgi <= 0))
         return;
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - 위에서 구해온 start sgi virq번호로 set.
+ */
     set_smp_ipi_range(base_sgi, 8);
 }
 
@@ -1936,7 +2036,7 @@ static int gic_irq_domain_translate(struct irq_domain *d,
 
 /*
  * IAMROOT, 2022.10.01:
- * - @virq 부터 @nr_irqs개 까지 virq를 할당한다.
+ * - @virq 부터 @nr_irqs개 까지 hwirq를 찾아 @domain과 함께 mapping한다.
  */
 static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
                 unsigned int nr_irqs, void *arg)
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 7fbf8a85c90a..d6813947a0b9 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -83,6 +83,12 @@
 #define IRQF_NO_AUTOEN        0x00080000
 #define IRQF_NO_DEBUG        0x00100000
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - timer방식으로 동작.
+ * - suspend 금지.
+ * - hardirq로 동작
+ */
 #define IRQF_TIMER        (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD)
 
 /*
@@ -122,6 +128,11 @@ struct irqaction {
     struct irqaction    *next;
     irq_handler_t        thread_fn;
     struct task_struct    *thread;
+/*
+ * IAMROOT, 2022.10.15:
+ * - force threading에서는 secondary로 thread_fn을 설정한다.
+ *   (irq_setup_forced_threading() 참고)
+ */
     struct irqaction    *secondary;
     unsigned int        irq;
     unsigned int        flags;
@@ -181,6 +192,10 @@ extern int __must_check
 request_nmi(unsigned int irq, irq_handler_t handler, unsigned long flags,
         const char *name, void *dev);
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - ppi류의 int를 위한 request irq.
+ */
 static inline int __must_check
 request_percpu_irq(unsigned int irq, irq_handler_t handler,
            const char *devname, void __percpu *percpu_dev_id)
@@ -473,6 +488,17 @@ extern int irq_get_irqchip_state(unsigned int irq, enum irqchip_irq_state which,
 extern int irq_set_irqchip_state(unsigned int irq, enum irqchip_irq_state which,
                  bool state);
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - forced threading 지원 안함 -> false
+ * - force thread 지원시
+ *   preempt rt -> true
+ *   일반 kernel -> force_irqthreads_key. 
+ *
+ * - force_irqthreads_key
+ *   rt kernel 아니지만 force thread를 해볼려고 하는 기능.
+ *   setup_forced_irqthreads() 참고. early param(threadirqs)
+ */
 #ifdef CONFIG_IRQ_FORCED_THREADING
 # ifdef CONFIG_PREEMPT_RT
 #  define force_irqthreads()    (true)
diff --git a/include/linux/irq.h b/include/linux/irq.h
index f2a25fe0db6f..056bc42ad034 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -90,6 +90,10 @@ enum {
     IRQ_LEVEL        = (1 <<  8),
     IRQ_PER_CPU        = (1 <<  9),
     IRQ_NOPROBE        = (1 << 10),
+/*
+ * IAMROOT, 2022.10.15:
+ * - 사용자가 실제 irq를 사용한다고 설정을하면(request_irq) set된다.
+ */
     IRQ_NOREQUEST        = (1 << 11),
     IRQ_NOAUTOEN        = (1 << 12),
     IRQ_NO_BALANCING    = (1 << 13),
@@ -107,6 +111,10 @@ enum {
     IRQ_PER_CPU_DEVID    = (1 << 17),
     IRQ_IS_POLLED        = (1 << 18),
     IRQ_DISABLE_UNLAZY    = (1 << 19),
+/*
+ * IAMROOT, 2022.10.15:
+ * - Don't show up in /proc/interrupts
+ */
     IRQ_HIDDEN        = (1 << 20),
     IRQ_NO_DEBUG        = (1 << 21),
 };
@@ -191,6 +199,10 @@ struct irq_common_data {
  * - 계층구조를 지원할려고 irq_desc에서 irq_data만 빼놓았다.
  * - chip으로 해당 irq의 소속 hw와 연결된다.
  * - domain을 통해서 해당 irq가 소속된 domain(tree, linear...)과 연결된다.
+ *
+ * - domain이 계층구조인경우 다음의 값들이  child irq_data와 동일하게 유지된다.
+ *   (irq_domain_insert_irq_data() 참고)
+ *   irq, common
  */
 struct irq_data {
     u32            mask;
@@ -244,6 +256,9 @@ enum {
 /*
  * IAMROOT, 2022.10.01:
  * - IRQ_TYPE_SENSE_MASK
+ * - IRQD_AFFINITY_MANAGED, IRQD_MANAGED_SHUTDOWN (alloc_descs() 참고)
+ *   affinity->is_managed가 되있는경우 irq desc할당에서 flag로 사용한다.
+ *
  */
     IRQD_TRIGGER_MASK        = 0xf,
     IRQD_SETAFFINITY_PENDING    = (1 <<  8),
diff --git a/include/linux/irqchip/arm-gic-common.h b/include/linux/irqchip/arm-gic-common.h
index 5be9cf6325f3..d8e9a9b1609e 100644
--- a/include/linux/irqchip/arm-gic-common.h
+++ b/include/linux/irqchip/arm-gic-common.h
@@ -12,7 +12,8 @@
 /*
  * IAMROOT, 2022.10.08:
  * - default priority.
- *   일반 interrupt용 우선순위.
+ *   일반 interrupt용 우선순위. local_irq_disable(), arch_local_irq_disable(),
+ *   GIC_PRIO_IRQOFF참고
  */
 #define GICD_INT_DEF_PRI        0xa0
 
diff --git a/include/linux/kthread.h b/include/linux/kthread.h
index 346b0f269161..fecc34ac97d5 100644
--- a/include/linux/kthread.h
+++ b/include/linux/kthread.h
@@ -24,6 +24,10 @@ struct task_struct *kthread_create_on_node(int (*threadfn)(void *data),
  * the stopped state.  This is just a helper for kthread_create_on_node();
  * see the documentation there for more details.
  */
+/*
+ * IAMROOT, 2022.10.15:
+ * - TODO
+ */
 #define kthread_create(threadfn, data, namefmt, arg...) \
     kthread_create_on_node(threadfn, data, NUMA_NO_NODE, namefmt, ##arg)
 
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
index 222da43b7096..a6dea3788ad8 100644
--- a/include/linux/pm_runtime.h
+++ b/include/linux/pm_runtime.h
@@ -388,6 +388,10 @@ static inline int pm_runtime_get(struct device *dev)
  * if its return value is checked by the caller, as this is likely to result
  * in cleaner code.
  */
+/*
+ * IAMROOT, 2022.10.15:
+ * - 기다리면서 깨운다. driver쪽에 pm등이 존재하는 경우가 있다. 이런 api로 깨운다.
+ */
 static inline int pm_runtime_get_sync(struct device *dev)
 {
     return __pm_runtime_resume(dev, RPM_GET_PUT);
diff --git a/include/linux/task_work.h b/include/linux/task_work.h
index 5b8a93f288bb..609774133244 100644
--- a/include/linux/task_work.h
+++ b/include/linux/task_work.h
@@ -7,6 +7,10 @@
 
 typedef void (*task_work_func_t)(struct callback_head *);
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - @twork에 @func를 등록한다.
+ */
 static inline void
 init_task_work(struct callback_head *twork, task_work_func_t func)
 {
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index f2be3c7459b9..c7576c164db3 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -1709,11 +1709,20 @@ int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
  * Enable the power to the IRQ chip referenced by the interrupt data
  * structure.
  */
+/*
+ * IAMROOT, 2022.10.15:
+ * - chip control를 절전상태라면 깨운다.
+ */
 int irq_chip_pm_get(struct irq_data *data)
 {
     int retval;
 
     if (IS_ENABLED(CONFIG_PM) && data->chip->parent_device) {
+
+/*
+ * IAMROOT, 2022.10.15:
+ * - 동기화(기다리면서) 깨운다 라는것.
+ */
         retval = pm_runtime_get_sync(data->chip->parent_device);
         if (retval < 0) {
             pm_runtime_put_noidle(data->chip->parent_device);
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index ef0107a65db1..b4674c379965 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -52,6 +52,11 @@ static void __init init_irq_default_affinity(void)
 #endif
 
 #ifdef CONFIG_SMP
+/*
+ * IAMROOT, 2022.10.15:
+ * - mask들을 @node 할당해온다. cpu가 많을경우 동적으로 mask를 할당해와야 될수도
+ *   있다.
+ */
 static int alloc_masks(struct irq_desc *desc, int node)
 {
     if (!zalloc_cpumask_var_node(&desc->irq_common_data.affinity,
@@ -78,6 +83,11 @@ static int alloc_masks(struct irq_desc *desc, int node)
     return 0;
 }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - smp(cpumask) 에 대한 값설정.
+ * - @affinity 요청이 없으면 default로 irq_default_affinity를 사용한다.
+ */
 static void desc_smp_init(struct irq_desc *desc, int node,
               const struct cpumask *affinity)
 {
@@ -100,6 +110,10 @@ static inline void
 desc_smp_init(struct irq_desc *desc, int node, const struct cpumask *affinity) { }
 #endif
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - 초기값들 + cpumask 설정.
+ */
 static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
                   const struct cpumask *affinity, struct module *owner)
 {
@@ -347,6 +361,10 @@ static void irq_sysfs_del(struct irq_desc *desc) {}
 
 static RADIX_TREE(irq_desc_tree, GFP_KERNEL);
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - irq_desc_tree에 irq desc를 추가한다.
+ */
 static void irq_insert_desc(unsigned int irq, struct irq_desc *desc)
 {
     radix_tree_insert(&irq_desc_tree, irq, desc);
@@ -394,6 +412,11 @@ void irq_unlock_sparse(void)
     mutex_unlock(&sparse_irq_lock);
 }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - struct irq_desc를 인자에 따라 할당하고 초기화한다.
+ * - @flags는 irq_data에 set된다.
+ */
 static struct irq_desc *alloc_desc(int irq, int node, unsigned int flags,
                    const struct cpumask *affinity,
                    struct module *owner)
@@ -408,6 +431,10 @@ static struct irq_desc *alloc_desc(int irq, int node, unsigned int flags,
     if (!desc->kstat_irqs)
         goto err_desc;
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - desc에 필요한 mask들을 할당한다.
+ */
     if (alloc_masks(desc, node))
         goto err_kstat;
 
@@ -473,6 +500,12 @@ static void free_desc(unsigned int irq)
     call_rcu(&desc->rcu, delayed_free_desc);
 }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - @start 에서 @cnt만큼 virq 할당시도.
+ *   virq desc를 실제로 할당하고 초기화 한다.
+ *   sysfs, debugfs에 등록한다.
+ */
 static int alloc_descs(unsigned int start, unsigned int cnt, int node,
                const struct irq_affinity_desc *affinity,
                struct module *owner)
@@ -492,16 +525,30 @@ static int alloc_descs(unsigned int start, unsigned int cnt, int node,
         const struct cpumask *mask = NULL;
         unsigned int flags = 0;
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - affinity가 있으면 해당 affinity의 is_managed를 확인한다.
+ */
         if (affinity) {
             if (affinity->is_managed) {
                 flags = IRQD_AFFINITY_MANAGED |
                     IRQD_MANAGED_SHUTDOWN;
             }
             mask = &affinity->mask;
+
+/*
+ * IAMROOT, 2022.10.15:
+ * - affinity mask로 포함되있는 cpu가 위치한 node로 node를 고친다.
+ */
             node = cpu_to_node(cpumask_first(mask));
             affinity++;
         }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - start + i에 해당하는 desc를 할당해오고 초기화한다.
+ *   irq_data에 flags가 set된다.
+ */
         desc = alloc_desc(start + i, node, flags, mask, owner);
         if (!desc)
             goto err;
@@ -790,6 +837,20 @@ EXPORT_SYMBOL_GPL(irq_free_descs);
  *
  * Returns the first irq number or error code
  */
+/*
+ * IAMROOT, 2022.10.15:
+ * @irq 사용자가 원하는 virq번호
+ * @from 시작번호. @irq가 존재하면(>=0) @irq부터 시작. 그게 아니라면 주어진 from
+ *                부터 시작한다.
+ * - @cnt개수 만큼 irq desc자료구조가 실제로 할당되고 초기화된다.
+ *   생성된 virq는 sysfs, debugfs에 등록된다.
+ * --- virq 시작번호 설정.
+ * 1. irq가 주어진경우 (>=0)
+ *    주어진 irq부터 virq할당을 시도한다. cnt만큼 연속된 bitmap을 못찾으면
+ *    할당 실패한다.
+ * 2. irq가 주어지지 않은 경우
+ *    hwirq번호로 virq시작번호를 설정한다. 단 hwirq가 0번이면 1번부터 시작한다.
+ */
 int __ref
 __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
           struct module *owner, const struct irq_affinity_desc *affinity)
@@ -800,6 +861,10 @@ __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
         return -EINVAL;
 
     if (irq >= 0) {
+/*
+ * IAMROOT, 2022.10.15:
+ * - 원하는 irq번호가 시작범위보다 작으면 말이안된다.
+ */
         if (from > irq)
             return -EINVAL;
         from = irq;
@@ -814,17 +879,36 @@ __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
 
     mutex_lock(&sparse_irq_lock);
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - cnt 개만큼 0으로 연속된 bit들의 start 번호를 찾는다.
+ */
     start = bitmap_find_next_zero_area(allocated_irqs, IRQ_BITMAP_BITS,
                        from, cnt, 0);
     ret = -EEXIST;
+
+/*
+ * IAMROOT, 2022.10.15:
+ * - irq번호 요청이 있는 상태에서, start가 요청 irq번호랑 다르면 실패처리.
+ *   요청 irq번호랑 다르게 구한경우가 된다.
+ */
     if (irq >=0 && start != irq)
         goto unlock;
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - 총 irq수보다 많은 범위를 준 경우. 확장을 시도한다. 너무너무 많으면 실패.
+ */
     if (start + cnt > nr_irqs) {
         ret = irq_expand_nr_irqs(start + cnt);
         if (ret)
             goto unlock;
     }
+
+/*
+ * IAMROOT, 2022.10.15:
+ * - start ~ start + cnt - 1까지 번호를 할당한다.
+ */
     ret = alloc_descs(start, cnt, node, affinity, owner);
 unlock:
     mutex_unlock(&sparse_irq_lock);
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 3e8ac8cedab8..53462699c3b6 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -575,6 +575,10 @@ static void irq_domain_clear_mapping(struct irq_domain *domain,
     mutex_unlock(&domain->revmap_mutex);
 }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - @domain에 hwirq번호를 key로 irq_data를 mapping한다.
+ */
 static void irq_domain_set_mapping(struct irq_domain *domain,
                    irq_hw_number_t hwirq,
                    struct irq_data *irq_data)
@@ -1101,20 +1105,45 @@ int irq_domain_translate_twocell(struct irq_domain *d,
 }
 EXPORT_SYMBOL_GPL(irq_domain_translate_twocell);
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - @virq 번호가 있는경우 @virq부터 @cnt만큼 할당시도를 한다,.
+ * - 그게 아니라면 hwirq로 virq start번호를 만들어 시도를 한다.
+ */
 int irq_domain_alloc_descs(int virq, unsigned int cnt, irq_hw_number_t hwirq,
                int node, const struct irq_affinity_desc *affinity)
 {
     unsigned int hint;
 
     if (virq >= 0) {
+/*
+ * IAMROOT, 2022.10.15:
+ * - 특정 번호의 virq요청이있으면, 해당 번호로 시작해서, cnt만큼 구해오는걸
+ *   시도한다.
+ */
         virq = __irq_alloc_descs(virq, virq, cnt, node, THIS_MODULE,
                      affinity);
     } else {
+/*
+ * IAMROOT, 2022.10.15:
+ * - 시작번호를 선정한다. 가능하면 virq번호를 hwirq와 맞추고 싶어한다.
+ */
         hint = hwirq % nr_irqs;
+
+/*
+ * IAMROOT, 2022.10.15:
+ * - virq는 0번부터 시작할수없다. 예외처리.
+ */
         if (hint == 0)
             hint++;
         virq = __irq_alloc_descs(-1, hint, cnt, node, THIS_MODULE,
                      affinity);
+
+/*
+ * IAMROOT, 2022.10.15:
+ * - hint ~ hint + cnt - 1에서 실패를 했다면, 1번부터로 범위를 바꿔 다시 한번
+ *   시도한다.
+ */
         if (virq <= 0 && hint > 1) {
             virq = __irq_alloc_descs(-1, 1, cnt, node, THIS_MODULE,
                          affinity);
@@ -1174,6 +1203,10 @@ struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent,
 }
 EXPORT_SYMBOL_GPL(irq_domain_create_hierarchy);
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - @domain에 virq의 hwirq를 key로 irq_data를 mapping한다.
+ */
 static void irq_domain_insert_irq(int virq)
 {
     struct irq_data *data;
@@ -1189,6 +1222,10 @@ static void irq_domain_insert_irq(int virq)
             domain->name = data->chip->name;
     }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - 자료구조가 완성됬고, 이제 사용자 요청만을 기다리면 되는 상태.
+ */
     irq_clear_status_flags(virq, IRQ_NOREQUEST);
 }
 
@@ -1210,6 +1247,13 @@ static void irq_domain_remove_irq(int virq)
     }
 }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * @domain parent domain
+ *
+ * - @child의 parent irq_data를 생성한다.
+ *   child의 irq, common을 동일한 값을 가져간다.
+ */
 static struct irq_data *irq_domain_insert_irq_data(struct irq_domain *domain,
                            struct irq_data *child)
 {
@@ -1227,6 +1271,10 @@ static struct irq_data *irq_domain_insert_irq_data(struct irq_domain *domain,
     return irq_data;
 }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - irq_data 부터 모든 parent를 free한다.
+ */
 static void __irq_domain_free_hierarchy(struct irq_data *irq_data)
 {
     struct irq_data *tmp;
@@ -1266,6 +1314,12 @@ static void irq_domain_free_irq_data(unsigned int virq, unsigned int nr_irqs)
  * have any real meaning for this interrupt, and that the driver marks
  * as such from its .alloc() callback.
  */
+/*
+ * IAMROOT, 2022.10.15:
+ * - 일부 hwirq가 cascade처리를 안하는 경우가 있다. 이 경우 empty function등을
+ *   해서 fake 계층 처리를 해도 되지만, 이렇게 복잡하게 안하고 ENOTCONN을
+ *   사용해 계층을 축소 시키는 방법이 추가 됬다.
+ */
 int irq_domain_disconnect_hierarchy(struct irq_domain *domain,
                     unsigned int virq)
 {
@@ -1280,6 +1334,10 @@ int irq_domain_disconnect_hierarchy(struct irq_domain *domain,
 }
 EXPORT_SYMBOL_GPL(irq_domain_disconnect_hierarchy);
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - ENOTCONN된 parent irq_data을 찾아서 trim(free) 시킨다.
+ */
 static int irq_domain_trim_hierarchy(unsigned int virq)
 {
     struct irq_data *tail, *irqd, *irq_data;
@@ -1309,6 +1367,10 @@ static int irq_domain_trim_hierarchy(unsigned int virq)
             if (PTR_ERR(irqd->chip) != -ENOTCONN)
                 return -EINVAL;
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - irqd->chip ENOTCONN가 있는 마지막 irq_data를 찾는다.
+ */
             tail = irq_data;
         }
     }
@@ -1317,6 +1379,10 @@ static int irq_domain_trim_hierarchy(unsigned int virq)
     if (!tail)
         return 0;
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - ENOTCONN가 된 irqd에서 trim을 시키고 trim된 irqd의 parent들을 전부 free.
+ */
     pr_info("IRQ%d: trimming hierarchy from %s\n",
         virq, tail->parent_data->domain->name);
 
@@ -1324,11 +1390,17 @@ static int irq_domain_trim_hierarchy(unsigned int virq)
     irqd = tail;
     tail = tail->parent_data;
     irqd->parent_data = NULL;
+
     __irq_domain_free_hierarchy(tail);
 
     return 0;
 }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - @virq부터 nr_irqs수의 irq data에 @domain을 등록한다. @domain이 계층 구조인경우
+ *   타고 올라가면서 irq_data를 할당해준다.(부분적 설정. 일단 할당만 하는 개념)
+ */
 static int irq_domain_alloc_irq_data(struct irq_domain *domain,
                      unsigned int virq, unsigned int nr_irqs)
 {
@@ -1336,11 +1408,21 @@ static int irq_domain_alloc_irq_data(struct irq_domain *domain,
     struct irq_domain *parent;
     int i;
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - 첫번째 desc에는 irq_data가 이미 embed 되있다. 도메인이 계층구조인 경우엔
+ *   irq_data도 동일하게 parent 구조로 등록시켜준다.
+ */
     /* The outermost irq_data is embedded in struct irq_desc */
     for (i = 0; i < nr_irqs; i++) {
         irq_data = irq_get_irq_data(virq + i);
         irq_data->domain = domain;
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - 계층구조라면 위로 올라가면서 등록시켜준다.
+ *   irq_data는 domain, common, irq만을 일당 할당해준다.
+ */
         for (parent = domain->parent; parent; parent = parent->parent) {
             irq_data = irq_domain_insert_irq_data(parent, irq_data);
             if (!irq_data) {
@@ -1490,6 +1572,12 @@ static void irq_domain_free_irqs_hierarchy(struct irq_domain *domain,
     }
 }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - @domain의 alloc ops를 호출해서 mapping한다.
+ * - ex)
+ *   gic_irq_domain_alloc
+ */
 int irq_domain_alloc_irqs_hierarchy(struct irq_domain *domain,
                     unsigned int irq_base,
                     unsigned int nr_irqs, void *arg)
@@ -1524,6 +1612,25 @@ int irq_domain_alloc_irqs_hierarchy(struct irq_domain *domain,
  * resources. In this way, it's easier to rollback when failing to
  * allocate resources.
  */
+/*
+ * IAMROOT, 2022.10.15:
+ * - papago
+ *   계층 구조 IRQ 도메인을 지원하기 위해 IRQ 번호를 할당하고 모든 데이터 구조를
+ *   초기화합니다.
+ *   @realloc 매개변수는 주로 레거시 IRQ를 지원하기 위한 것입니다.
+ *   오류 코드 또는 할당된 IRQ 번호를 반환합니다. IRQ를 설정하는 전체 프로세스는
+ *   두 단계로 분할되었습니다.
+ *   첫 번째 단계인 __irq_domain_alloc_irqs()는 IRQ 설명자와 필요한 하드웨어
+ *   리소스를 할당하는 것입니다. 두 번째 단계인 irq_domain_activate_irq()는 미리
+ *   할당된 리소스로 하드웨어를 프로그래밍하는 것입니다. 이런 식으로 리소스 할당에
+ *   실패했을 때 롤백하기가 더 쉽습니다.
+ *
+ * - irq_desc 할당(irq_desc radix에 virq로 insert)(realloc == false인경우)
+ *   -> irq data를 domain 에 맞게 할당
+ *   -> domain alloc ops로 virq mapping
+ *   -> ENOTCONN된 parent irq_data trim
+ *   -> domain에 irq_data추가(domain revmap에 hwirq를 key로 irq_data mapping.)
+ */
 int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
                 unsigned int nr_irqs, int node, void *arg,
                 bool realloc, const struct irq_affinity_desc *affinity)
@@ -1536,9 +1643,25 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
             return -EINVAL;
     }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - realloc == true 
+ *   @irq_base가 이미 할당되 있다고 생각하고 있는경우. irq_desc가 생성되있기
+ *   때문에 desc 자체는 생성할 필요가없다.
+ * - realloc == false, irq_base >= 0
+ *   irq_base에 해당하는 irq desc가 없다고 생각해서, irq_base에 해당하는 desc도
+ *   만들어야 된다.
+ * - irq_base < 0
+ *   0번부터 @nr_irqs개수만큼 virq를 만들어서 desc부터 만들어야된다.
+ */
     if (realloc && irq_base >= 0) {
         virq = irq_base;
     } else {
+
+/*
+ * IAMROOT, 2022.10.15:
+ * - irq desc를 만든다.
+ */
         virq = irq_domain_alloc_descs(irq_base, nr_irqs, 0, node,
                           affinity);
         if (virq < 0) {
@@ -1548,6 +1671,11 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
         }
     }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - 위에서 만들어진 or 이미 존재하던 irq desc의 irq_data들을 domain 계층 구조에 맞게
+ *   할당한다.
+ */
     if (irq_domain_alloc_irq_data(domain, virq, nr_irqs)) {
         pr_debug("cannot allocate memory for IRQ%d\n", virq);
         ret = -ENOMEM;
@@ -1555,12 +1683,21 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
     }
 
     mutex_lock(&irq_domain_mutex);
+
+/*
+ * IAMROOT, 2022.10.15:
+ * - domain alloc ops로 domain에 mapping한다. (hwirq가 mapping된다.)
+ */
     ret = irq_domain_alloc_irqs_hierarchy(domain, virq, nr_irqs, arg);
     if (ret < 0) {
         mutex_unlock(&irq_domain_mutex);
         goto out_free_irq_data;
     }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - ENOTCONN된 parent irq_data가 있는지 한번 검색하고, 있으면 trim
+ */
     for (i = 0; i < nr_irqs; i++) {
         ret = irq_domain_trim_hierarchy(virq + i);
         if (ret) {
@@ -1569,6 +1706,10 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
         }
     }
     
+/*
+ * IAMROOT, 2022.10.15:
+ * - domain에 virq를 mapping한다.
+ */
     for (i = 0; i < nr_irqs; i++)
         irq_domain_insert_irq(virq + i);
     mutex_unlock(&irq_domain_mutex);
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index cd1a6d244df9..2cf142fb5b51 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -27,6 +27,10 @@
 #if defined(CONFIG_IRQ_FORCED_THREADING) && !defined(CONFIG_PREEMPT_RT)
 DEFINE_STATIC_KEY_FALSE(force_irqthreads_key);
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - threaded irq가 가능하게 한다.
+ */
 static int __init setup_forced_irqthreads(char *arg)
 {
     static_branch_enable(&force_irqthreads_key);
@@ -1139,6 +1143,10 @@ EXPORT_SYMBOL_GPL(irq_set_parent);
  * assigned as primary handler when request_threaded_irq is called
  * with handler == NULL. Useful for oneshot interrupts.
  */
+/*
+ * IAMROOT, 2022.10.15:
+ * - irq_setup_forced_threading() 참고.
+ */
 static irqreturn_t irq_default_primary_handler(int irq, void *dev_id)
 {
     return IRQ_WAKE_THREAD;
@@ -1244,6 +1252,11 @@ static void irq_finalize_oneshot(struct irq_desc *desc,
 /*
  * Check whether we need to change the affinity of the interrupt thread.
  */
+/*
+ * IAMROOT, 2022.10.15:
+ * - @action의 affinity IRQTF_AFFINITY를 확인한다.
+ *   존재하면 current task에 해당 affinity mask를 설정해놓는다.
+ */
 static void
 irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action)
 {
@@ -1257,6 +1270,10 @@ irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action)
      * In case we are out of memory we set IRQTF_AFFINITY again and
      * try again next time
      */
+/*
+ * IAMROOT, 2022.10.15:
+ * - oom처리.
+ */
     if (!alloc_cpumask_var(&mask, GFP_KERNEL)) {
         set_bit(IRQTF_AFFINITY, &action->thread_flags);
         return;
@@ -1292,6 +1309,12 @@ irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action) { }
  * context. So we need to disable bh here to avoid deadlocks and other
  * side effects.
  */
+/*
+ * IAMROOT, 2022.10.15:
+ * - threaded irq(bottom half thread fn)
+ * - @action->thread_fn 호출.
+ * - TODO
+ */
 static irqreturn_t
 irq_forced_thread_fn(struct irq_desc *desc, struct irqaction *action)
 {
@@ -1316,6 +1339,10 @@ irq_forced_thread_fn(struct irq_desc *desc, struct irqaction *action)
  * preemptible - many of them need to sleep and wait for slow busses to
  * complete.
  */
+/*
+ * IAMROOT, 2022.10.15:
+ * - irq_forced_thread_fn()의 lock없는 버전.
+ */
 static irqreturn_t irq_thread_fn(struct irq_desc *desc,
         struct irqaction *action)
 {
@@ -1335,6 +1362,10 @@ static void wake_threads_waitq(struct irq_desc *desc)
         wake_up(&desc->wait_for_threads);
 }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - TODO
+ */
 static void irq_thread_dtor(struct callback_head *unused)
 {
     struct task_struct *tsk = current;
@@ -1377,6 +1408,10 @@ static void irq_wake_secondary(struct irq_desc *desc, struct irqaction *action)
 /*
  * Interrupt handler thread
  */
+/*
+ * IAMROOT, 2022.10.15:
+ * - TODO
+ */
 static int irq_thread(void *data)
 {
     struct callback_head on_exit_work;
@@ -1385,6 +1420,10 @@ static int irq_thread(void *data)
     irqreturn_t (*handler_fn)(struct irq_desc *desc,
             struct irqaction *action);
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - irq가 forced 방식동작 여부에 따라 handler_fn을 선택한다.
+ */
     if (force_irqthreads() && test_bit(IRQTF_FORCED_THREAD,
                        &action->thread_flags))
         handler_fn = irq_forced_thread_fn;
@@ -1394,6 +1433,10 @@ static int irq_thread(void *data)
     init_task_work(&on_exit_work, irq_thread_dtor);
     task_work_add(current, &on_exit_work, TWA_NONE);
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - @action의 affinity를 current task에 set.
+ */
     irq_thread_check_affinity(desc, action);
 
     while (!irq_wait_for_interrupt(action)) {
@@ -1445,10 +1488,24 @@ void irq_wake_thread(unsigned int irq, void *dev_id)
 }
 EXPORT_SYMBOL_GPL(irq_wake_thread);
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - @new를 forced thread로 사용하도록 등록한다.
+ */
 static int irq_setup_forced_threading(struct irqaction *new)
 {
+
+/*
+ * IAMROOT, 2022.10.15:
+ * - setup_forced_irqthreads() 참고. early param(threadirqs)
+ */
     if (!force_irqthreads())
         return 0;
+
+/*
+ * IAMROOT, 2022.10.15:
+ * - SPI류들만 들어올수 있을 것이다.
+ */
     if (new->flags & (IRQF_NO_THREAD | IRQF_PERCPU | IRQF_ONESHOT))
         return 0;
 
@@ -1456,9 +1513,18 @@ static int irq_setup_forced_threading(struct irqaction *new)
      * No further action required for interrupts which are requested as
      * threaded interrupts already
      */
+
+/*
+ * IAMROOT, 2022.10.15:
+ * - 이미 threaded irq가 설정됬다는 간접적인 의미.
+ */
     if (new->handler == irq_default_primary_handler)
         return 0;
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - threaded이므로 oneshot.
+ */
     new->flags |= IRQF_ONESHOT;
 
     /*
@@ -1466,6 +1532,10 @@ static int irq_setup_forced_threading(struct irqaction *new)
      * thread handler. We force thread them as well by creating a
      * secondary action.
      */
+/*
+ * IAMROOT, 2022.10.15:
+ * - 두개다 있는 경우엔 secondary를 만들어서 거기에 thread_fn을 설정한다.
+ */
     if (new->handler && new->thread_fn) {
         /* Allocate the secondary action */
         new->secondary = kzalloc(sizeof(struct irqaction), GFP_KERNEL);
@@ -1484,6 +1554,11 @@ static int irq_setup_forced_threading(struct irqaction *new)
     return 0;
 }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - irq_request_resources callback.
+ * - gic에는 구현되있지 않다.
+ */
 static int irq_request_resources(struct irq_desc *desc)
 {
     struct irq_data *d = &desc->irq_data;
@@ -1534,6 +1609,12 @@ static void irq_nmi_teardown(struct irq_desc *desc)
         c->irq_nmi_teardown(d);
 }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * @return 0. thread 생성 성공.
+ *         not 0. 생성실패.
+ * - thread를 생성한다.
+ */
 static int
 setup_irq_thread(struct irqaction *new, unsigned int irq, bool secondary)
 {
@@ -1550,6 +1631,10 @@ setup_irq_thread(struct irqaction *new, unsigned int irq, bool secondary)
     if (IS_ERR(t))
         return PTR_ERR(t);
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - t를 rt sched로 설정한다.
+ */
     sched_set_fifo(t);
 
     /*
@@ -1567,6 +1652,15 @@ setup_irq_thread(struct irqaction *new, unsigned int irq, bool secondary)
      * correct as we want the thread to move to the cpu(s)
      * on which the requesting code placed the interrupt.
      */
+/*
+ * IAMROOT, 2022.10.15:
+ * - papago
+ *   스레드에게 affinity를 설정하도록 지시합니다. 이것은 모든 것이 이미 설정되어
+ *   있으므로 secondary handler에 대해 setup_affinity()를 호출하지 않기 때문에
+ *   shared interrupt handler에 중요합니다.
+ *   IRQF_NO_BALANCE로 표시된 인터럽트의 경우에도 요청 코드가 인터럽트를 배치한
+ *   CPU로 스레드를 이동하기를 원하므로 이는 정확합니다.
+ */
     set_bit(IRQTF_AFFINITY, &new->thread_flags);
     return 0;
 }
@@ -1585,6 +1679,10 @@ setup_irq_thread(struct irqaction *new, unsigned int irq, bool secondary)
  * interrupt related functions. desc->request_mutex solely serializes
  * request/free_irq().
  */
+/*
+ * IAMROOT, 2022.10.15:
+ * - 
+ */
 static int
 __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 {
@@ -1606,6 +1704,10 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
      * If the trigger type is not specified by the caller,
      * then use the default for this interrupt.
      */
+/*
+ * IAMROOT, 2022.10.15:
+ * - flags에 IRQF_TRIGGER_MASK가 없으면 한번 irq_data에서 확인해서 있으면 가져온다.
+ */
     if (!(new->flags & IRQF_TRIGGER_MASK))
         new->flags |= irqd_get_trigger_type(&desc->irq_data);
 
@@ -1613,6 +1715,10 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
      * Check whether the interrupt nests into another interrupt
      * thread.
      */
+/*
+ * IAMROOT, 2022.10.15:
+ * - virq가 nested된 경우가 있다. 그런 경우에 대한 처리.
+ */
     nested = irq_settings_is_nested_thread(desc);
     if (nested) {
         if (!new->thread_fn) {
@@ -1626,6 +1732,12 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
          */
         new->handler = irq_nested_primary_handler;
     } else {
+
+/*
+ * IAMROOT, 2022.10.15:
+ * - threaded irq가능하면. PPI류들은 안한다.(ex). request_percpu_irq()등.)
+ *   SPI류들만 해당될것이다.
+ */
         if (irq_settings_can_thread(desc)) {
             ret = irq_setup_forced_threading(new);
             if (ret)
@@ -1638,6 +1750,10 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
      * and the interrupt does not nest into another interrupt
      * thread.
      */
+/*
+ * IAMROOT, 2022.10.15:
+ * - action에 thread_fn이 있고, not nested라면
+ */
     if (new->thread_fn && !nested) {
         ret = setup_irq_thread(new, irq, false);
         if (ret)
@@ -1658,6 +1774,17 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
      * chip flags, so we can avoid the unmask dance at the end of
      * the threaded handler for those.
      */
+/*
+ * IAMROOT, 2022.10.15:
+ * - papago
+ *   드라이버는 기본 irq 칩 구현에 대한 지식 없이 작동하도록 작성되는 경우가
+ *   많으므로 기본 hard irq 컨텍스트 핸들러가 없는 스레드된 irq에 대한 요청은
+ *   ONESHOT 플래그를 설정해야 합니다. MSI 기반 인터럽트와 같은 일부 irq 칩은
+ *   그 자체로 one shot safe 입니다. 칩 플래그를 확인하여 스레드 처리기 끝에서 마스크
+ *   해제 춤을 피할 수 있습니다.
+ * - chip handler에 대한 IRQCHIP_ONESHOT_SAFE이 있으면 chip handler단에서 oneshot
+ *   처리를 할것이므로 action handelr에선 불필요하므로 빼준다.
+ */
     if (desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE)
         new->flags &= ~IRQF_ONESHOT;
 
@@ -1668,6 +1795,14 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
      * a recycled oneshot thread_mask bit while it's still in use by
      * its previous owner.
      */
+/*
+ * IAMROOT, 2022.10.15:
+ * - papago
+ *   선택적 칩 버스 잠금 및 desc->lock을 유지하지 않고 synchronize_hardirq()가
+ *   완료될 때까지 기다릴 수 있는 동시 __free_irq() 호출로부터 보호합니다.
+ *   또한 이전 소유자가 아직 사용 중인 동안 재활용된 oneshot thread_mask 비트를
+ *   배포하는 것을 방지합니다.
+ */
     mutex_lock(&desc->request_mutex);
 
     /*
@@ -1675,6 +1810,12 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
      * might rely on the serialization or the magic power management
      * functions which are abusing the irq_bus_lock() callback,
      */
+/*
+ * IAMROOT, 2022.10.15:
+ * - papago
+ *  *아래의 irq_request_resources() 콜백이 직렬화 또는 irq_bus_lock() 콜백을 남용하는 
+ *  마법의 전원 관리 기능에 의존할 수 있으므로 버스 잠금을 획득하십시오.
+ */
     chip_bus_lock(desc);
 
     /* First installed action requests resources. */
@@ -1693,9 +1834,20 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
      * management calls which are not serialized via
      * desc->request_mutex or the optional bus lock.
      */
+/*
+ * IAMROOT, 2022.10.15:
+ * - papago
+ *   다음 코드 블록은 동시 인터럽트 및 desc->request_mutex 또는 선택적 버스 잠금을 통해
+ *   직렬화되지 않은 다른 관리 호출에 대해 원자적으로 보호되어 실행되어야 합니다.
+ */
     raw_spin_lock_irqsave(&desc->lock, flags);
     old_ptr = &desc->action;
     old = *old_ptr;
+
+/*
+ * IAMROOT, 2022.10.15:
+ * - 이전 action이 있다.
+ */
     if (old) {
         /*
          * Can't share interrupts unless both agree to and are
@@ -1705,8 +1857,20 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
          * agree on ONESHOT.
          * Interrupt lines used for NMIs cannot be shared.
          */
+/*
+ * IAMROOT, 2022.10.15:
+ * - papago
+ *   둘 다 동의하고 동일한 유형(레벨, 에지, 극성)이 아니면 인터럽트를 공유할 수 없습니다.
+ *   따라서 두 플래그 필드 모두 IRQF_SHARED가 설정되어야 하고 트리거 유형을 설정하는 비트가
+ *   일치해야 합니다. 또한 모두 ONESHOT에 동의해야 합니다.
+ *   NMI에 사용되는 인터럽트 라인은 공유할 수 없습니다.
+ */
         unsigned int oldtype;
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - NMI는 공유할수없다.
+ */
         if (desc->istate & IRQS_NMI) {
             pr_err("Invalid attempt to share NMI for %s (irq %d) on irqchip %s.\n",
                 new->name, irq, desc->irq_data.chip->name);
@@ -1718,10 +1882,23 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
          * If nobody did set the configuration before, inherit
          * the one provided by the requester.
          */
+/*
+ * IAMROOT, 2022.10.15:
+ * - papago
+ *   아무도 이전에 구성을 설정하지 않은 경우 요청자가 제공한 구성을 상속합니다.
+ */
         if (irqd_trigger_type_was_set(&desc->irq_data)) {
+/*
+ * IAMROOT, 2022.10.15:
+ * - 이전에 trigger설정이였다면 desc의 type을 가져온다.
+ */
             oldtype = irqd_get_trigger_type(&desc->irq_data);
         } else {
             oldtype = new->flags & IRQF_TRIGGER_MASK;
+/*
+ * IAMROOT, 2022.10.15:
+ * - irq_desc를 new flags의 trigger로 설정한다.
+ */
             irqd_set_trigger_type(&desc->irq_data, oldtype);
         }
 
@@ -2689,6 +2866,22 @@ int setup_percpu_irq(unsigned int irq, struct irqaction *act)
  *    the handler gets called with the interrupted CPU's instance of
  *    that variable.
  */
+/*
+ * IAMROOT, 2022.10.15:
+ * - papago
+ *   이 호출은 인터럽트 리소스를 할당하고 로컬 CPU에서 인터럽트를 활성화합니다.
+ *   인터럽트가 다른 CPU에서 활성화되어야 하는 경우 enable_percpu_irq()를 사용하여
+ *   각 CPU에서 인터럽트를 수행해야 합니다. 
+ *
+ *   Dev_id는 전역적으로 고유해야 합니다. 이것은 CPU당 변수이며 핸들러는
+ *   해당 변수의 인터럽트된 CPU 인스턴스와 함께 호출됩니다.
+ *
+ * - ex) ipi의 경우 ipi_handler()
+ *
+ * - irq 흐름.
+ *   vector -> chip handler -> flow handler -> irq_handler(현재) ->
+ *   action handler(option)
+ */
 int __request_percpu_irq(unsigned int irq, irq_handler_t handler,
              unsigned long flags, const char *devname,
              void __percpu *dev_id)
@@ -2701,10 +2894,22 @@ int __request_percpu_irq(unsigned int irq, irq_handler_t handler,
         return -EINVAL;
 
     desc = irq_to_desc(irq);
+
+/*
+ * IAMROOT, 2022.10.15:
+ * - !irq_settings_can_request
+ *   다른데서 request됬는지 확인.
+ * - !irq_settings_is_per_cpu_devid(desc)
+ *   percpu용인지 확인.
+ */
     if (!desc || !irq_settings_can_request(desc) ||
         !irq_settings_is_per_cpu_devid(desc))
         return -EINVAL;
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - flags가 있다면, IRQF_TIMER인것만 허락한다.
+ */
     if (flags && flags != IRQF_TIMER)
         return -EINVAL;
 
@@ -2713,10 +2918,19 @@ int __request_percpu_irq(unsigned int irq, irq_handler_t handler,
         return -ENOMEM;
 
     action->handler = handler;
+
+/*
+ * IAMROOT, 2022.10.15:
+ * - percpu용이라 percpu가 추가된다.
+ */
     action->flags = flags | IRQF_PERCPU | IRQF_NO_SUSPEND;
     action->name = devname;
     action->percpu_dev_id = dev_id;
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - chip이 절전인 경우에 대비해서 한번 wakeup시도를 한다.
+ */
     retval = irq_chip_pm_get(&desc->irq_data);
     if (retval < 0) {
         kfree(action);
diff --git a/kernel/irq/settings.h b/kernel/irq/settings.h
index 7b7efb1a114b..1d86bdec7203 100644
--- a/kernel/irq/settings.h
+++ b/kernel/irq/settings.h
@@ -50,6 +50,10 @@ static inline bool irq_settings_is_per_cpu(struct irq_desc *desc)
     return desc->status_use_accessors & _IRQ_PER_CPU;
 }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - percpu용인지 확인.
+ */
 static inline bool irq_settings_is_per_cpu_devid(struct irq_desc *desc)
 {
     return desc->status_use_accessors & _IRQ_PER_CPU_DEVID;
@@ -97,6 +101,12 @@ static inline void irq_settings_set_level(struct irq_desc *desc)
     desc->status_use_accessors |= _IRQ_LEVEL;
 }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * @return false. 다른데서 사용중.
+ *         true. 사용중인곳 없음.
+ * - 다른데서 request를 했는지에 대한 여부.
+ */
 static inline bool irq_settings_can_request(struct irq_desc *desc)
 {
     return !(desc->status_use_accessors & _IRQ_NOREQUEST);
@@ -112,6 +122,11 @@ static inline void irq_settings_set_norequest(struct irq_desc *desc)
     desc->status_use_accessors |= _IRQ_NOREQUEST;
 }
 
+/*
+ * IAMROOT, 2022.10.15:
+ * @return false. nothread만으로만 동작.(hardirq로만 동작)
+ *         true.  thread방식으로 동작가능.
+ */
 static inline bool irq_settings_can_thread(struct irq_desc *desc)
 {
     return !(desc->status_use_accessors & _IRQ_NOTHREAD);
diff --git a/kernel/task_work.c b/kernel/task_work.c
index 1698fbe6f0e1..bfa21513b10b 100644
--- a/kernel/task_work.c
+++ b/kernel/task_work.c
@@ -29,6 +29,10 @@ static struct callback_head work_exited; /* all we need is ->next == NULL */
  * RETURNS:
  * 0 if succeeds or -ESRCH.
  */
+/*
+ * IAMROOT, 2022.10.15:
+ * - TODO
+ */
 int task_work_add(struct task_struct *task, struct callback_head *work,
           enum task_work_notify_mode notify)
 {
diff --git a/lib/cpumask.c b/lib/cpumask.c
index 2d56bc31bdd2..a0434997fd0e 100644
--- a/lib/cpumask.c
+++ b/lib/cpumask.c
@@ -114,6 +114,11 @@ EXPORT_SYMBOL(cpumask_next_wrap);
  * CONFIG_CPUMASK_OFFSTACK=n, so does code elimination in that case
  * too.
  */
+
+/*
+ * IAMROOT, 2022.10.15:
+ * - cpumask로 쓸것을 @node에서 할당해온다.
+ */
 bool alloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags, int node)
 {
     *mask = kmalloc_node(cpumask_size(), flags, node);
@@ -129,6 +134,10 @@ bool alloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags, int node)
 }
 EXPORT_SYMBOL(alloc_cpumask_var_node);
 
+/*
+ * IAMROOT, 2022.10.15:
+ * - cpumask로 쓸것을 @node에서 할당해온다.
+ */
 bool zalloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags, int node)
 {
     return alloc_cpumask_var_node(mask, flags | __GFP_ZERO, node);
 

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 스터디 정리 노트 공간입니다. woos 2016.05.14 623
165 [커널 19차] 27 주차 Min 2022.11.22 82
164 [커널 18차] 78주차 kkr 2022.11.19 186
163 [커널 19차] 25 ~ 26 주차 Min 2022.11.14 71
162 [커널 18차] 76-77주차 kkr 2022.11.12 385
161 [커널 19차] 24주차 Min 2022.10.31 108
160 [커널 17차] 112주차 ㅇㅇㅇ 2022.10.30 81
159 [커널 18차] 75주차 kkr 2022.10.29 40
158 [커널 17차] 107 ~ 111주차 ㅇㅇㅇ 2022.10.23 71
157 [커널 19차] 22주차 Min 2022.10.17 76
» [커널 18차] 73주차 kkr 2022.10.15 44
155 [커널 18차] 72주차 kkr 2022.10.09 182
154 [커널 18차] 71주차 kkr 2022.10.01 74
153 [커널 18차] 70주차 kkr 2022.09.24 76
152 [커널 18차] 69주차 kkr 2022.09.22 57
151 [커널 17차] 105~106주차 ㅇㅇㅇ 2022.09.18 50
150 [커널 17차] 104주차 ㅇㅇㅇ 2022.09.04 87
149 [커널 18차] 67주차 kkr 2022.09.03 138
148 [커널 17차] 103주차 ㅇㅇㅇ 2022.08.28 35
147 [커널 18차] 66주차 kkr 2022.08.27 75
146 [커널 17차] 101~102주차 ㅇㅇㅇ 2022.08.21 45
XE Login