diff --git "a/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\345\206\205\346\240\270preempt.md" "b/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\345\206\205\346\240\270preempt.md" index cbaa003..f4ff3cc 100644 --- "a/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\345\206\205\346\240\270preempt.md" +++ "b/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\345\206\205\346\240\270preempt.md" @@ -88,3 +88,4 @@ static __always_inline int preempt_count(void) } ``` ![alt text](../../../../medias/images_0/内核preempt_image-1.png) +![alt text](../../../../medias/images_0/内核preempt_image-2.png) \ No newline at end of file diff --git "a/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--irq_domain\347\232\204\345\210\235\345\247\213\345\214\226.md" "b/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--irq_domain\347\232\204\345\210\235\345\247\213\345\214\226.md" index 906357a..d357b43 100755 --- "a/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--irq_domain\347\232\204\345\210\235\345\247\213\345\214\226.md" +++ "b/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--irq_domain\347\232\204\345\210\235\345\247\213\345\214\226.md" @@ -1,6 +1,8 @@ ```c -[__gic_init_bases() -> irq_domain_add_linear() -> __irq_domain_add()] +# x86 初始化 +对于x86来说__irq_domain_add在arch_early_irq_init中调用 +## 初始化核心函数 [kernel/irq/irqdomain.c] struct irq_domain *__irq_domain_add(struct device_node *of_node, int size, irq_hw_number_t hwirq_max, int direct_max, @@ -31,12 +33,27 @@ struct irq_domain *__irq_domain_add(struct device_node *of_node, int size, } EXPORT_SYMBOL_GPL(__irq_domain_add); ``` -# x86 初始化 + +domain->ops 为: +```c +static const struct irq_domain_ops x86_vector_domain_ops = { + .select = x86_vector_select, + .alloc = x86_vector_alloc_irqs, + .free = x86_vector_free_irqs, + .activate = x86_vector_activate, + .deactivate = x86_vector_deactivate, +#ifdef CONFIG_GENERIC_IRQ_DEBUGFS + .debug_show = x86_vector_debug_show, +#endif +}; +``` + +## 调用堆栈 ```c [ 0.000000] dump_stack_lvl+0x45/0x63 [ 0.000000] dump_stack+0x10/0x12 [ 0.000000] __irq_domain_add+0x1a8/0x290 -[ 0.000000] ? __irq_domain_alloc_fwnode+0xb9/0xf0 +[ 0.000000] irq_domain_create_tree+0xb9/0xf0 [ 0.000000] arch_early_irq_init+0x3a/0x79 [ 0.000000] early_irq_init+0xe5/0xec [ 0.000000] start_kernel+0x449/0x661 diff --git "a/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--\344\270\255\346\226\255\345\217\267\346\230\240\345\260\204.md" "b/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--\344\270\255\346\226\255\345\217\267\346\230\240\345\260\204.md" index 864a81b..a11dfc2 100755 --- "a/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--\344\270\255\346\226\255\345\217\267\346\230\240\345\260\204.md" +++ "b/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--\344\270\255\346\226\255\345\217\267\346\230\240\345\260\204.md" @@ -189,7 +189,6 @@ unsigned int irq_create_mapping_affinity(struct irq_domain *domain, } /* Allocate a virtual interrupt number */ - //映射的核心函数,内部调用__irq_domain_alloc_irqs()函数 virq = irq_domain_alloc_descs(-1, 1, hwirq, of_node_to_nid(of_node), affinity); if (virq <= 0) { @@ -197,6 +196,7 @@ unsigned int irq_create_mapping_affinity(struct irq_domain *domain, return 0; } + //映射的核心函数,内部调用__irq_domain_alloc_irqs()函数 if (irq_domain_associate(domain, virq, hwirq)) { irq_free_desc(virq); return 0; @@ -263,6 +263,7 @@ int irq_domain_associate(struct irq_domain *domain, unsigned int virq, } domain->mapcount++; + // 根据hwirq反向索引到irq_data irq_domain_set_mapping(domain, hwirq, irq_data); mutex_unlock(&irq_domain_mutex); diff --git "a/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--\345\210\235\345\247\213\345\214\226.md" "b/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--\345\210\235\345\247\213\345\214\226.md" index e2edf9d..318280b 100755 --- "a/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--\345\210\235\345\247\213\345\214\226.md" +++ "b/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--\345\210\235\345\247\213\345\214\226.md" @@ -77,4 +77,40 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node, desc_smp_init(desc, node); } +static const struct irq_domain_ops x86_vector_domain_ops = { + .select = x86_vector_select, + .alloc = x86_vector_alloc_irqs, + .free = x86_vector_free_irqs, + .activate = x86_vector_activate, + .deactivate = x86_vector_deactivate, +#ifdef CONFIG_GENERIC_IRQ_DEBUGFS + .debug_show = x86_vector_debug_show, +#endif +}; + +//根据x86_vector_domain_ops 初始化domain_ops +int __init arch_early_irq_init(void) +{ + struct fwnode_handle *fn; + + fn = irq_domain_alloc_named_fwnode("VECTOR"); + BUG_ON(!fn); + x86_vector_domain = irq_domain_create_tree(fn, &x86_vector_domain_ops, + NULL); + BUG_ON(x86_vector_domain == NULL); + irq_set_default_host(x86_vector_domain); + + BUG_ON(!alloc_cpumask_var(&vector_searchmask, GFP_KERNEL)); + + /* + * Allocate the vector matrix allocator data structure and limit the + * search area. + */ + vector_matrix = irq_alloc_matrix(NR_VECTORS, FIRST_EXTERNAL_VECTOR, + FIRST_SYSTEM_VECTOR); + BUG_ON(!vector_matrix); + + return arch_early_ioapic_init(); +} + ``` \ No newline at end of file diff --git "a/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--\347\241\254\344\270\255\346\226\255\345\217\267\347\232\204\350\247\243\346\236\220.md" "b/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--\347\241\254\344\270\255\346\226\255\345\217\267\347\232\204\350\247\243\346\236\220.md" new file mode 100755 index 0000000..d05a220 --- /dev/null +++ "b/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--\347\241\254\344\270\255\346\226\255\345\217\267\347\232\204\350\247\243\346\236\220.md" @@ -0,0 +1,33 @@ +irq_of_parse_and_map +irq_create_of_mapping +```c +struct of_phandle_args { + struct device_node *np; + int args_count; + uint32_t args[MAX_PHANDLE_ARGS]; +}; + +static void of_phandle_args_to_fwspec(struct device_node *np, const u32 *args, + unsigned int count, + struct irq_fwspec *fwspec) +{ + int i; + + fwspec->fwnode = of_node_to_fwnode(np); + fwspec->param_count = count; + + for (i = 0; i < count; i++) + fwspec->param[i] = args[i]; +} + +unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data) +{ + struct irq_fwspec fwspec; + + of_phandle_args_to_fwspec(irq_data->np, irq_data->args, + irq_data->args_count, &fwspec); + + return irq_create_fwspec_mapping(&fwspec); +} +EXPORT_SYMBOL_GPL(irq_create_of_mapping); +``` \ No newline at end of file