欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Linux cpu topology

程序员文章站 2024-03-19 09:42:46
...

CPU topology

 

代码结构

arch/arm/kernel/topology.c

init/main.c
start_kernel
    rest_init
        kernel_init
            kernel_init_freeable
                smp_prepare_cpus


arch/arm/kernel/smp.c
smp_prepare_cpus
    init_cpu_topology


arch/arm/kernel/topology.c
init_cpu_topology

451 void __init init_cpu_topology(void)
452 {       
453     reset_cpu_topology();  //topology初始化
454         
455     smp_wmb();
456         
457     /*  
458      * Discard anything that was parsed if we hit an error so we
459      * don't use partial information.     
460      */ 
461     if (of_have_populated_dt() && parse_dt_topology()) // parse_dt_topology解析dt
462         reset_cpu_topology();
463     else                                                                                                                                                                                                 
464         set_sched_topology(arm_topology); //设置调度策略
465 }                          
  16     cpus {
  17         #address-cells = <2>;
  18         #size-cells = <0>;
  19     
  20         cpu-map {
  21             cluster0 {
  22                 core0 {
  23                     cpu = <&CPU0>;
  24                 };
  25                 core1 {
  26                     cpu = <&CPU1>;
  27                 };
  28                 core2 {
  29                     cpu = <&CPU2>;
  30                 };
  31             };                                                                                                                                                                                          
  32             cluster1 {
  33                 core0 {
  34                     cpu = <&CPU3>;
  35                 };
  36             };
  37         };

 

237 static int __init parse_dt_topology(void)                                                                                                                                                                
238 {                  
239     struct device_node *cn, *map;
240     int ret = 0;   
241     int cpu;       
242                    
243     cn = of_find_node_by_path("/cpus"); //获取cpus节点信息
244     if (!cn) {     
245         pr_err("No CPU information found in DT\n");
246         return 0;  
247     }              
248                    
249     /*             
250      * When topology is provided cpu-map is essentially a root
251      * cluster with restricted subnodes.
252      */            
253     map = of_get_child_by_name(cn, "cpu-map"); //获取cpu-map节点信息
254     if (!map)      
255         goto out;  
256                    
257     ret = parse_cluster(map, 0); //重要函数,通过map信息获取cluster
258     if (ret != 0)  
259         goto out_map;
260                    
261     topology_normalize_cpu_scale();
262                    
263     /*             
264      * Check that all cores are in the topology; the SMP code will
265      * only mark cores described in the DT as possible.
266      */            
267     for_each_possible_cpu(cpu)
268         if (cpu_topology[cpu].socket_id == -1)
269             ret = -EINVAL;
270                    
271 out_map:           
272     of_node_put(map);
273 out:               
274     of_node_put(cn);
275     return ret;    
276 }                  
parse_cluster
    parse_core
        get_cpu_for_node
            topology_parse_cpu_capacity
                

 

161 static int __init parse_cluster(struct device_node *cluster, int depth)
162 {   
163     char name[10];
164     bool leaf = true;
165     bool has_cores = false;
166     struct device_node *c;
167     static int socket_id __initdata;
168     int core_id = 0;
169     int i, ret;
170     
171     /*
172      * First check for child clusters; we currently ignore any
173      * information about the nesting of clusters and present the
174      * scheduler with a flat list of them.
175      */
176     i = 0;
177     do {
178         snprintf(name, sizeof(name), "cluster%d", i);
179         c = of_get_child_by_name(cluster, name);
180         if (c) {
181             leaf = false;
182             ret = parse_cluster(c, depth + 1);
183             of_node_put(c);
184             if (ret != 0)
185                 return ret;                                                                                                                                                                              
186         }
187         i++;
188     } while (c);
189     
190     /* Now check for cores */
191     i = 0;
192     do {
193         snprintf(name, sizeof(name), "core%d", i);
194         c = of_get_child_by_name(cluster, name);
195         if (c) {
196             has_cores = true;
197     
198             if (depth == 0) {
199                 pr_err("%pOF: cpu-map children should be clusters\n",
200                        c);
201                 of_node_put(c);
202                 return -EINVAL;
203             }
204    
205             if (leaf) {
206                 ret = parse_core(c, socket_id, core_id++);
207             } else {
208                 pr_err("%pOF: Non-leaf cluster with core %s\n",
209                        cluster, name);
210                 ret = -EINVAL;
211             }
212    
213             of_node_put(c);
214             if (ret != 0)
215                 return ret;
216         }
217         i++;
218     } while (c);
219    
220     if (leaf && !has_cores)
221         pr_warn("%pOF: empty cluster\n", cluster);
222    
223     if (leaf)
224         socket_id++;
225    
226     return 0;
227 }

113 static int __init parse_core(struct device_node *core, int socket_id,                                                                                                                                    
114                  int core_id)
115 {
116     char name[10];
117     bool leaf = true; 
118     int i = 0;
119     int cpu;
120     struct device_node *t;
121  
122     do {
123         snprintf(name, sizeof(name), "thread%d", i);
124         t = of_get_child_by_name(core, name);
125         if (t) {      
126             leaf = false;
127             cpu = get_cpu_for_node(t);
128             if (cpu >= 0) {
129                 cpu_topology[cpu].socket_id = socket_id;
130                 cpu_topology[cpu].core_id = core_id;
131                 cpu_topology[cpu].thread_id = i;
132             } else {
133                 pr_err("%pOF: Can't get CPU for thread\n",
134                        t);
135                 of_node_put(t);
136                 return -EINVAL;
137             }
138             of_node_put(t);
139         }
140         i++;
141     } while (t);
142  
143     cpu = get_cpu_for_node(core);
144     if (cpu >= 0) {
145         if (!leaf) {
146             pr_err("%pOF: Core has both threads and CPU\n",
147                    core);
148             return -EINVAL;
149         }
150  
151         cpu_topology[cpu].socket_id = socket_id;
152         cpu_topology[cpu].core_id = core_id;
153     } else if (leaf) {
154         pr_err("%pOF: Can't get CPU for leaf core\n", core);
155         return -EINVAL;
156     }
157  
158     return 0;
159 }

 

相关标签: topology