for_each_online_cpu得到一个指向cpuinfo_x86的指针

linux内核的cpuinfo模块使用这段代码来获取一个指向cpu的指针:

ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) { // (...) struct seq_file *m = file->private_data; void *p; // (...) p = m->op->start(m, &pos); 

启动方法可以在proc.c中find:

 static void *c_start(struct seq_file *m, loff_t *pos) { *pos = cpumask_next(*pos - 1, cpu_online_mask); if ((*pos) < nr_cpu_ids) return &cpu_data(*pos); return NULL; } 

void*的指针已经从它返回之后,接下来传给show方法:

 err = m->op->show(m, p); 

将指针指向cpuinfo_x86的指针:

 static int show_cpuinfo(struct seq_file *m, void *v) { struct cpuinfo_x86 *c = v; unsigned int cpu; int i; cpu = c->cpu_index; 

但是如果我在我的代码(linux内核模块)中做了类似的事情:

  get_online_cpus(); pos = kmalloc( sizeof( loff_t), GFP_KERNEL); *pos = 0; *pos = cpumask_next(*pos - 1, cpu_online_mask); if ( (*pos) < nr_cpu_ids) { c = &cpu_data(*pos); cpu = c->cpu_index; // SIGSEGV ! } 

指针是不正确的(它指向的东西可能是有效的地址,但我不能访问它指向什么)。 同样的事情发生,如果我使用for_each_online_cpumacros:

 for_each_online_cpu( cpuid) { c = &cpu_data(cpuid); 

我为什么得到SIGSEGV? 我知道由vfs传递给cpuinfo的文件是特殊的顺序文件,但是它似乎与cpu_datamacros没有关系。 到目前为止,我唯一可以看到的区别是,在第一种情况下,指针被传递给函数,然后它被分配在函数内部,所以我们有一个堆栈框架等。这与优化有关吗?

如果我在单独的函数中进行赋值,

 static void* mpsrv_get_cpu_ptr( loff_t *pos) { *pos = cpumask_next(*pos - 1, cpu_possible_mask); if ( (*pos) < nr_cpu_ids) return &cpu_data(*pos); return NULL; } static void mpsrv_stat_cpu( struct mpsrv_cpu_info *cpu_info, void *v) { struct cpuinfo_x86 *c = v; // OK unsigned int cpu; cpu = c->cpu_index; // OK // (...) } // code get_online_cpus(); pos = cpu_n = 0; while ( ( p = mpsrv_get_cpu_ptr( &pos))) { mpsrv_stat_cpu( cpu_info, p); ++cpu_n; ++pos; } put_online_cpus(); 

cpuinfo.c中的内核代码还会返回一个指向cpuinfo_x86的指针,该指针是在单独的函数c_start()中获得的 。 请让我知道是否需要一些额外的信息。 谢谢。

Solutions Collecting From Web of "for_each_online_cpu得到一个指向cpuinfo_x86的指针"