Skip to contentSkip to conversation

Revert "perf: Remove the extra validity check on nr_pages"

PATCH In review [email protected] 4 participants 8 messages Mar 2, 2015 – Mar 4, 2015 perf events

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Revert "perf: Remove the extra validity check on nr_pages"

From: Kan Liang <[email protected]>

This reverts commit 74390aa55678 ("perf: Remove the extra validity check on nr_pages")

nr_pages equals to number of pages - 1 in perf_mmap. So nr_pages = 0 is valide. So the nr_pages != 0 && !is_power_of_2(nr_pages) are all needed for checking. Otherwise, for example, perf test 6 failed. perf test 6
6: x86 rdpmc test :Error:
mmap() syscall returned with (Invalid argument)
FAILED!

---
 kernel/events/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/events/core.c +1 -1
index 89f0f16..a83581c 100644
@@ -4423,7 +4423,7 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
 	 * If we have rb pages ensure they're a power-of-two number, so we
 	 * can do bitmasks instead of modulo.
 	 */
-	if (!is_power_of_2(nr_pages))
+	if (nr_pages != 0 && !is_power_of_2(nr_pages))
 		return -EINVAL;
 
 	if (vma_size != PAGE_SIZE * (1 + nr_pages))
Signature · 1 line
1.8.3.1
#1 lore raw

Em Mon, Mar 02, 2015 at 02:14:26AM -0500, [email protected] escreveu:

Quoted 5 lines

From: Kan Liang <[email protected]>

This reverts commit 74390aa55678 ("perf: Remove the extra validity check on nr_pages")

Quoted 7 lines

nr_pages equals to number of pages - 1 in perf_mmap. So nr_pages = 0 is valide. So the nr_pages != 0 && !is_power_of_2(nr_pages) are all needed for checking. Otherwise, for example, perf test 6 failed. perf test 6
6: x86 rdpmc test :Error:
mmap() syscall returned with (Invalid argument)
FAILED!

Yeah, my bad, we need to revert this, its just on tip/perf/core, will put the revert in my next pull request, thanks for spotting this!

- Arnaldo

Quoted 20 lines
---
 kernel/events/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/events/core.c +1 -1
index 89f0f16..a83581c 100644
@@ -4423,7 +4423,7 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
 	 * If we have rb pages ensure they're a power-of-two number, so we
 	 * can do bitmasks instead of modulo.
 	 */
-	if (!is_power_of_2(nr_pages))
+	if (nr_pages != 0 && !is_power_of_2(nr_pages))
 		return -EINVAL;
 
 	if (vma_size != PAGE_SIZE * (1 + nr_pages))
Signature · 1 line
1.8.3.1
#2 lore raw
In reply to [email protected]
Revert "perf: Remove the extra validity check on nr_pages"
Commit-ID:  2ed11312eb19506c027e7cac039994ad42a9cb2c
Gitweb:     http://git.kernel.org/tip/2ed11312eb19506c027e7cac039994ad42a9cb2c
Author:     Kan Liang <[email protected]>
AuthorDate: Mon, 2 Mar 2015 02:14:26 -0500
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 2 Mar 2015 18:25:38 -0300

Revert "perf: Remove the extra validity check on nr_pages"

This reverts commit 74390aa55678 ("perf: Remove the extra validity check on nr_pages")

nr_pages equals to number of pages - 1 in perf_mmap. So nr_pages = 0 is valid.

So the nr_pages != 0 && !is_power_of_2(nr_pages) are all needed for checking. Otherwise, for example, perf test 6 failed.

 # perf test 6
  6: x86 rdpmc test                                         :Error:
 mmap() syscall returned with (Invalid argument)
 FAILED!
---
 kernel/events/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/events/core.c +1 -1
index af924bc..8bb20cc 100644
@@ -4446,7 +4446,7 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
 	 * If we have rb pages ensure they're a power-of-two number, so we
 	 * can do bitmasks instead of modulo.
 	 */
-	if (!is_power_of_2(nr_pages))
+	if (nr_pages != 0 && !is_power_of_2(nr_pages))
 		return -EINVAL;
 
 	if (vma_size != PAGE_SIZE * (1 + nr_pages))
#3 lore raw

kernel/events/core.c static int perf_mmap(struct file *file, struct vm_area_struct *vma) · line 4450

Quoted 9 lines · tip-bot for Kan Liang
kernel/events/core.c +1 -1
@@ -4446,7 +4446,7 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
 	 * If we have rb pages ensure they're a power-of-two number, so we
 	 * can do bitmasks instead of modulo.
 	 */
-	if (!is_power_of_2(nr_pages))
+	if (nr_pages != 0 && !is_power_of_2(nr_pages))
 		return -EINVAL;

Hm, what does is_power_of_2(0) return? It should return 0, because 0 is not a power of 2!

and if it's fixed to return 0, then the check should properly be something like:

	if (!nr_pages || !is_power_of_2(nr_pages))

or so?

Thanks,

Ingo

author
#4 lore raw
Quoted 21 lines · tip-bot for Kan Liang

kernel/events/core.c static int perf_mmap(struct file *file, struct

Quoted 4 lines
kernel/events/core.c +0 -0
@@ -4446,7 +4446,7 @@ static int perf_mmap(struct file *file, struct

vm_area_struct *vma)

kernel/events/core.c static int perf_mmap(struct file *file, struct · line 4446

Quoted 1 line
kernel/events/core.c +0 -0
 	 * If we have rb pages ensure they're a power-of-two number, so

we

kernel/events/core.c static int perf_mmap(struct file *file, struct vm_area_struct *vma) · line 4450

Quoted 5 lines
kernel/events/core.c +1 -1
 	 * can do bitmasks instead of modulo.
 	 */
-	if (!is_power_of_2(nr_pages))
+	if (nr_pages != 0 && !is_power_of_2(nr_pages))
 		return -EINVAL;

Hm, what does is_power_of_2(0) return? It should return 0, because 0 is not a power of 2!

Quoted 6 lines

and if it's fixed to return 0, then the check should properly be something like:

	if (!nr_pages || !is_power_of_2(nr_pages))

or so?

nr_pages == 0 is valid, we cannot return -EINVAL. Because

	vma_size = vma->vm_end - vma->vm_start;
	nr_pages = (vma_size / PAGE_SIZE) - 1;

So here we only want to check is_power_of_2
when the pages > 1 (or nr_pages > 0).

Thanks,
Kan

Quoted 4 lines

Thanks,

Ingo

#5 lore raw
Quoted 22 lines · Liang, Kan
Quoted 22 lines · tip-bot for Kan Liang

kernel/events/core.c static int perf_mmap(struct file *file, struct

Quoted 4 lines
kernel/events/core.c +0 -0
@@ -4446,7 +4446,7 @@ static int perf_mmap(struct file *file, struct

vm_area_struct *vma)

kernel/events/core.c static int perf_mmap(struct file *file, struct · line 4446

Quoted 1 line
kernel/events/core.c +0 -0
 	 * If we have rb pages ensure they're a power-of-two number, so

we

kernel/events/core.c static int perf_mmap(struct file *file, struct vm_area_struct *vma) · line 4450

Quoted 5 lines
kernel/events/core.c +1 -1
 	 * can do bitmasks instead of modulo.
 	 */
-	if (!is_power_of_2(nr_pages))
+	if (nr_pages != 0 && !is_power_of_2(nr_pages))
 		return -EINVAL;

Hm, what does is_power_of_2(0) return? It should return 0, because 0 is not a power of 2!

and if it's fixed to return 0, then the check should properly be something like:

	if (!nr_pages || !is_power_of_2(nr_pages))
Quoted 8 lines
Quoted 1 line

or so?

nr_pages == 0 is valid, we cannot return -EINVAL. Because

	vma_size = vma->vm_end - vma->vm_start;
	nr_pages = (vma_size / PAGE_SIZE) - 1;

So here we only want to check is_power_of_2
when the pages > 1 (or nr_pages > 0).

I don't think you answered my first question, on which my later comments rely:

Quoted 2 lines
Quoted 2 lines

Hm, what does is_power_of_2(0) return? It should return 0, because 0 is not a power of 2!

Thanks,

Ingo

author
#6 lore raw
Quoted 36 lines · Liang, Kan
Quoted 8 lines
Quoted 8 lines · tip-bot for Kan Liang

kernel/events/core.c static int perf_mmap(struct file *file, struct

Quoted 4 lines
kernel/events/core.c +0 -0
@@ -4446,7 +4446,7 @@ static int perf_mmap(struct file *file, struct

vm_area_struct *vma)

Quoted 1 line
kernel/events/core.c +0 -0
 	 * If we have rb pages ensure they're a power-of-two number, so
Quoted 8 lines
Quoted 8 lines

we

kernel/events/core.c static int perf_mmap(struct file *file, struct vm_area_struct *vma) · line 4450

Quoted 5 lines
kernel/events/core.c +1 -1
 	 * can do bitmasks instead of modulo.
 	 */
-	if (!is_power_of_2(nr_pages))
+	if (nr_pages != 0 && !is_power_of_2(nr_pages))
 		return -EINVAL;

Hm, what does is_power_of_2(0) return? It should return 0, because 0

is

Quoted 3 lines
Quoted 3 lines

not a power of 2!

and if it's fixed to return 0, then the check should properly be

something

Quoted 10 lines
Quoted 5 lines

like:

	if (!nr_pages || !is_power_of_2(nr_pages))

or so?

nr_pages == 0 is valid, we cannot return -EINVAL. Because

	vma_size = vma->vm_end - vma->vm_start;
	nr_pages = (vma_size / PAGE_SIZE) - 1;
Quoted 9 lines
Quoted 2 lines

So here we only want to check is_power_of_2
when the pages > 1 (or nr_pages > 0).

I don't think you answered my first question, on which my later comments rely:

Quoted 1 line
Quoted 1 line

Hm, what does is_power_of_2(0) return? It should return 0, because 0

is

Quoted 1 line
Quoted 1 line

not a power of 2!

Yes, is_power_of_2(0) returns 0.

Thanks,
Kan

Quoted 4 lines

Thanks,

Ingo

#7 lore raw
Quoted 34 lines · Liang, Kan
Quoted 34 lines · Liang, Kan
Quoted 32 lines
Quoted 18 lines · tip-bot for Kan Liang

kernel/events/core.c static int perf_mmap(struct file *file, struct

Quoted 4 lines
kernel/events/core.c +0 -0
@@ -4446,7 +4446,7 @@ static int perf_mmap(struct file *file, struct

vm_area_struct *vma)

kernel/events/core.c static int perf_mmap(struct file *file, struct · line 4446

Quoted 1 line
kernel/events/core.c +0 -0
 	 * If we have rb pages ensure they're a power-of-two number, so

we

kernel/events/core.c static int perf_mmap(struct file *file, struct vm_area_struct *vma) · line 4450

Quoted 5 lines
kernel/events/core.c +1 -1
 	 * can do bitmasks instead of modulo.
 	 */
-	if (!is_power_of_2(nr_pages))
+	if (nr_pages != 0 && !is_power_of_2(nr_pages))
 		return -EINVAL;

Hm, what does is_power_of_2(0) return? It should return 0, because 0 is not a power of 2!

Quoted 7 lines

and if it's fixed to return 0, then the check should properly be something like:

	if (!nr_pages || !is_power_of_2(nr_pages))

return -EINVAL;

or so?

nr_pages == 0 is valid, we cannot return -EINVAL. Because

	vma_size = vma->vm_end - vma->vm_start;
	nr_pages = (vma_size / PAGE_SIZE) - 1;

So here we only want to check is_power_of_2
when the pages > 1 (or nr_pages > 0).

Quoted 8 lines
Quoted 6 lines

I don't think you answered my first question, on which my later comments rely:

Quoted 1 line
Quoted 1 line

Hm, what does is_power_of_2(0) return? It should return 0, because 0

is

Quoted 1 line
Quoted 1 line

not a power of 2!

Yes, is_power_of_2(0) returns 0.

Oh, indeed, and I clearly cannot read code: your original argument and the revert is correct, sorry about the confusion!

Thanks,

Ingo