x86/proc: fix /proc/cpuinfo cpu offline bug
PATCH 1/1 x86/proc: fix /proc/cpuinfo cpu offline bug
In my test, I found that if a cpu has been offline, the next cpus may not be shown in the /proc/cpuinfo.
trivially reproduce this bug:
1) add these lines in the end of show_cpuinfo()
if (m->size - m->count - 20 > 0) seq_printf(m, "%*s", (int)(m->size - m->count - 20), "show bug\n");
2) rebuilt kernel & reboot
3) offline cpu#1
4) cat /proc/cpuinfo
cpu#2 and cpu#3 .... cannot be shown in /proc/cpuinfo
---
arch/x86/kernel/cpu/proc.c +4 -2
@@ -160,14 +160,16 @@ static void *c_start(struct seq_file *m, loff_t *pos) {if (*pos ==0 )/* just in case, cpu 0 is not the first */ *pos =first_cpu (cpu_online_map); -if ((*pos) < nr_cpu_ids &&cpu_online (*pos)) +else + *pos =next_cpu_nr (*pos -1 , cpu_online_map); +if ((*pos) < nr_cpu_ids)return &cpu_data (*pos);return NULL ; }static void *c_next (struct seq_file *m,void *v,loff_t *pos) { - *pos =next_cpu (*pos, cpu_online_map); + (*pos)++;return c_start (m, pos); }
Quoted 8 lines · Lai Jiangshan
In my test, I found that if a cpu has been offline, the next cpus may not be shown in the
/proc/cpuinfo.trivially reproduce this bug:
1) add these lines in the end of
show_cpuinfo()if (m->size - m->count - 20 > 0) seq_printf(m, "%*s", (int)(m->size - m->count - 20), "show bug\n");
What is it?
Can you just show wrong /proc/cpuinfo ?
Can someone with at least 4-way box please do so?
Quoted 24 lines
3) offline cpu#1
4) cat/proc/cpuinfo
cpu#2 and cpu#3 .... cannot be shown in/proc/cpuinfoarch/x86/kernel/cpu/proc.c +4
-2@@ -160,14 +160,16 @@ static void *c_start(struct seq_file *m, loff_t *pos) {if (*pos ==0 )/* just in case, cpu 0 is not the first */ *pos =first_cpu (cpu_online_map); -if ((*pos) < nr_cpu_ids &&cpu_online (*pos)) +else + *pos =next_cpu_nr (*pos -1 , cpu_online_map); +if ((*pos) < nr_cpu_ids)return &cpu_data (*pos);return NULL ; }static void *c_next (struct seq_file *m,void *v,loff_t *pos) { - *pos =next_cpu (*pos, cpu_online_map); + (*pos)++;return c_start (m, pos); }
Quoted 10 lines · Alexey Dobriyan
Quoted 8 lines · Lai Jiangshan
In my test, I found that if a cpu has been offline, the next cpus may not be shown in the
/proc/cpuinfo.trivially reproduce this bug:
1) add these lines in the end of
show_cpuinfo()if (m->size - m->count - 20 > 0) seq_printf(m, "%*s", (int)(m->size - m->count - 20), "show bug\n");
Quoted 5 lines
What is it?
Can you just show wrong
/proc/cpuinfo?Can someone with at least 4-way box please do so?
this is not wrong /proc/cpuinfo, this is an enlarged /proc/cpuinfo this trivial example just use "show bug\n" as the enlarged content.
if you boot your machine with enough cpu, your /proc/cpuinfo have been enlarged too, please use this:
#!/bin/sh
nr_cpus=16 # i386
for ((i=1; i<nr_cpus; i++))
do
echo 0 > /sys/devices/system/cpu/cpu$i/online cpus=$(grep processor /proc/cpuinfo | wc -l) (( cpus == nr_cpus -1 )) || break; # bug eccur echo 1 > /sys/devices/system/cpu/cpu$i/online
done
cat /proc/cpuinfo # it shows this bug.
Lai
Quoted 31 lines
Quoted 15 lines
3) offline cpu#1
4) cat/proc/cpuinfo
cpu#2 and cpu#3 .... cannot be shown in/proc/cpuinfoarch/x86/kernel/cpu/proc.c +3
-1@@ -160,14 +160,16 @@ static void *c_start(struct seq_file *m, loff_t *pos) {if (*pos ==0 )/* just in case, cpu 0 is not the first */ *pos =first_cpu (cpu_online_map); -if ((*pos) < nr_cpu_ids &&cpu_online (*pos)) +else + *pos =next_cpu_nr (*pos -1 , cpu_online_map); +if ((*pos) < nr_cpu_ids)arch/x86/kernel/cpu/proc.c static void *c_start(struct seq_file *m, loff_t *pos) · line 174
Quoted 10 lines
arch/x86/kernel/cpu/proc.c +1
-1return &cpu_data (*pos);return NULL ; }static void *c_next (struct seq_file *m,void *v,loff_t *pos) { - *pos =next_cpu (*pos, cpu_online_map); + (*pos)++;return c_start (m, pos); }--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Hi, Ingo and Alexey,
I have changed my changelog. please review again.
Thanks, Lai.
Quoted 67 lines · Lai Jiangshan
Quoted 6 lines · Alexey Dobriyan
Quoted 5 lines · Lai Jiangshan
In my test, I found that if a cpu has been offline, the next cpus may not be shown in the
/proc/cpuinfo.trivially reproduce this bug:
Quoted 8 lines
Quoted 3 lines
1) add these lines in the end of
show_cpuinfo()if (m->size - m->count - 20 > 0) seq_printf(m, "%*s", (int)(m->size - m->count - 20), "show bug\n");What is it?
Can you just show wrong
/proc/cpuinfo?Can someone with at least 4-way box please do so?
this is not wrong
/proc/cpuinfo, this is an enlarged/proc/cpuinfothis trivial example just use "show bug\n" as the enlarged content.if you boot your machine with enough cpu, your
/proc/cpuinfohave been enlarged too, please use this:#!/bin/sh
nr_cpus=16 # i386
for ((i=1; i<nr_cpus; i++))
do
echo 0 >/sys/devices/system/cpu/cpu$i/onlinecpus=$(grep processor/proc/cpuinfo| wc -l) (( cpus ==nr_cpus-1 )) || break; # bug eccur echo 1 >/sys/devices/system/cpu/cpu$i/online
done
cat/proc/cpuinfo# it shows this bug.Lai
Quoted 29 lines
Quoted 13 lines
3) offline cpu#1
4) cat/proc/cpuinfo
cpu#2 and cpu#3 .... cannot be shown in/proc/cpuinfoarch/x86/kernel/cpu/proc.c +3
-1@@ -160,14 +160,16 @@ static void *c_start(struct seq_file *m, loff_t *pos) {if (*pos ==0 )/* just in case, cpu 0 is not the first */ *pos =first_cpu (cpu_online_map); -if ((*pos) < nr_cpu_ids &&cpu_online (*pos)) +else + *pos =next_cpu_nr (*pos -1 , cpu_online_map); +if ((*pos) < nr_cpu_ids)arch/x86/kernel/cpu/proc.c static void *c_start(struct seq_file *m, loff_t *pos) · line 174
Quoted 10 lines
arch/x86/kernel/cpu/proc.c +1
-1return &cpu_data (*pos);return NULL ; }static void *c_next (struct seq_file *m,void *v,loff_t *pos) { - *pos =next_cpu (*pos, cpu_online_map); + (*pos)++;return c_start (m, pos); }--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Quoted 6 lines · Lai Jiangshan
Hi, Ingo and Alexey,
I have changed my changelog. please review again.
Thanks, Lai.
In my test, I found that if a cpu has been offline, the next cpus may not be shown in the /proc/cpuinfo.
if one read() cannot consume the whole /proc/cpuinfo, c_start() will be called again in the next read() calls. And *pos has been increased by 1 by the caller(seq_read()). if this time the cpu#*pos is offline, c_start() will return NULL, and the next cpus can not be shown.
this fix use next_cpu_nr(*pos - 1, cpu_online_map) to search the next unshown cpu.
the most easy way to reproduce this bug:
1) offline cpu#1 (cpu#0 is online)
2) dd ibs=2 if=/proc/cpuinfo
the result is that only cpu#0 is shown. cpu#2 and cpu#3 .... cannot be shown in /proc/cpuinfo it's bug.
---
arch/x86/kernel/cpu/proc.c +4 -2
@@ -160,14 +160,16 @@ static void *c_start(struct seq_file *m, loff_t *pos) {if (*pos ==0 )/* just in case, cpu 0 is not the first */ *pos =first_cpu (cpu_online_map); -if ((*pos) < nr_cpu_ids &&cpu_online (*pos)) +else + *pos =next_cpu_nr (*pos -1 , cpu_online_map); +if ((*pos) < nr_cpu_ids)return &cpu_data (*pos);return NULL ; }static void *c_next (struct seq_file *m,void *v,loff_t *pos) { - *pos =next_cpu (*pos, cpu_online_map); + (*pos)++;return c_start (m, pos); }