Bug in kernel code?
Quoted 10 lines · David S. Miller
From: "Stephen C. Biggs" <[email protected]>
Date: Tue, 27 Aug 2002 17:24:19 -0700........... Notice the --order >=0 in the do while test... since order is declared as an unsigned long, this test is a pointless comparison and never fails, causing an infinite loop if the hashtable is empty.
My fix to this is to change the test to have while (
dentry_hashtable== NULL && order-- != 0);
Quoted 9 lines
Could someone check me on this?
Your analysis is right but the fix is wrong, we do want to try order == 0 on very small memory systems, and you should not decrement the order at the beginning of the loop. We want to use the "order" calculated.
Just make 'order' signed long to fix this bug.
NO! That won't work either. This is a "do while" loop so the first test is always done and if order is 0, the check will be done AFTER the decrement, so this works. Changing it to a signed long loses you a bit.
From: "Stephen C. Biggs" <[email protected]>
Date: Tue, 27 Aug 2002 17:32:58 -0700
This is a "do while" loop so the first test is always done
No, a "do while" loop always executes the first iteration. What version of the C language do you think we are using?
Quoted 8 lines · David S. Miller
From: "Stephen C. Biggs" <[email protected]>
Date: Tue, 27 Aug 2002 17:32:58 -0700This is a "do while" loop so the first test is always done
No, a "do while" loop always executes the first iteration. What version of the C language do you think we are using?
You're misunderstanding me, I meant that the first test is done AFTER the first iteration is executed, so my fix is correct since, even if order is 0 because at least one iteration of the loop is done, and the post decrement makes sure that the test succeeds if order was 0 going into the loop.
Changing order to a signed long loses half of the cache entries due to the number being divided by 2.
From: "Stephen C. Biggs" <[email protected]>
Date: Tue, 27 Aug 2002 17:40:41 -0700
You're misunderstanding me, I meant that the first test is done
AFTER the first iteration is executed, so my fix is correct
since, even if order is 0 because at least one iteration of the loop is done, and the post decrement makes sure that the test succeeds if order was 0 going into the loop.
Order is always >= 0 when we enter the loop.
If we actually get the table allocated then the decrement of 'order' is not executed if we allocate the table successfully.
I don't understand what the problem is with my fix.
Quoted 9 lines · David S. Miller
From: "Stephen C. Biggs" <[email protected]>
Date: Tue, 27 Aug 2002 17:40:41 -0700You're misunderstanding me, I meant that the first test is done
AFTER the first iteration is executed, so my fix is correct
since, even if order is 0 because at least one iteration of the loop is done, and the post decrement makes sure that the test succeeds if order was 0 going into the loop.
Quoted 7 lines
Order is always >= 0 when we enter the loop.
If we actually get the table allocated then the decrement of 'order' is not executed if we allocate the table successfully.
I don't understand what the problem is with my fix.
[Trying again - my mail client is messing up/sending empty posts]
As I look at it, it can only be 0 <= order < 32, so your fix works, as mine does. Yours is simpler and doesn't involve changing code, just declarations.
There need to be some sanity checks in this code: what if mempages is passed as some insanely huge number, e.g.
From: "Stephen C. Biggs" <[email protected]>
Date: Tue, 27 Aug 2002 18:09:46 -0700
There need to be some sanity checks in this code: what if mempages is passed as some insanely huge number, e.g.
And then your mail ends.... let us know when you've fixed your email client, this isn't rocket science :-)
Quoted 9 lines · David S. Miller
From: "Stephen C. Biggs" <[email protected]>
Date: Tue, 27 Aug 2002 18:09:46 -0700There need to be some sanity checks in this code: what if mempages is passed as some insanely huge number, e.g.
And then your mail ends.... let us know when you've fixed your email client, this isn't rocket science :-)
What are you talking about "And then your mail ends..." That's all I wanted to say...
Oh, you want me to post a complete patch.... I get it.
From: "Stephen C. Biggs" <[email protected]>
Date: Tue, 27 Aug 2002 18:24:13 -0700
Quoted 3 lines · David S. Miller
And then your mail ends.... let us know when you've fixed your email client, this isn't rocket science :-)
What are you talking about "And then your mail ends..." That's all I wanted to say...
No, I thought you were going to give an example of a huge number. :-)
Quoted 5 lines · David S. Miller
From: "Stephen C. Biggs" <[email protected]>
Date: Tue, 27 Aug 2002 18:24:13 -0700On 27 Aug 2002 at 18:09, David S. Miller wrote:
Quoted 9 lines
Quoted 3 lines
And then your mail ends.... let us know when you've fixed your email client, this isn't rocket science :-)
What are you talking about "And then your mail ends..." That's all I wanted to say...
No, I thought you were going to give an example of a huge number. :-)
How about (unsigned long)(~0)?
This code never finishes:
#include <stdio.h>
#define PAGE_SHIFT 12
struct list_head {
struct list_head *next, *prev;
};int main(void)
{
unsigned long order;
unsigned long mempages = ~0;#if PAGE_SHIFT < 13
mempages >>= (13 - PAGE_SHIFT);
#endif
mempages *= sizeof(struct list_head);
for (order = 0; ((1UL << order) << PAGE_SHIFT) < mempages; order++)
;
printf("%d\n",order);
return 0;
}Quoted 11 lines · David S. Miller
From: "Stephen C. Biggs" <[email protected]>
Date: Tue, 27 Aug 2002 18:24:13 -0700Quoted 3 lines · David S. Miller
And then your mail ends.... let us know when you've fixed your email client, this isn't rocket science :-)
What are you talking about "And then your mail ends..." That's all I wanted to say...
Quoted 9 lines
No, I thought you were going to give an example of a huge number. :-)
-
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/
Argh. I meant to post THIS code:
#include <stdio.h>
#define PAGE_SHIFT 12
struct list_head {
struct list_head *next, *prev;
};int main(void)
{
unsigned long order;
unsigned long mempages = ~0;#if PAGE_SHIFT < 13
mempages >>= (13 - PAGE_SHIFT);
#endif
mempages *= sizeof(struct list_head);
printf("mempages: %lu\n", mempages);
for (order = 0; ((1UL << order) << PAGE_SHIFT) < mempages; order++)
;
printf("%lu\n",order);
return 0;
} From: "Stephen C. Biggs" <[email protected]>
Date: Tue, 27 Aug 2002 19:42:36 -0700
How about (unsigned long)(~0)?
Realistically possible with any known configuration?
Quoted 6 lines · David S. Miller
From: "Stephen C. Biggs" <[email protected]>
Date: Tue, 27 Aug 2002 19:42:36 -0700How about (unsigned long)(~0)?
Realistically possible with any known configuration?
How about replacing the loop with ffs/__ffs that would be more elegant, shorter and avoid any problem or doubt?
From: Luca Barbieri <[email protected]>
Date: 28 Aug 2002 05:57:50 +0200
Quoted 1 line · David S. Miller
Realistically possible with any known configuration?
How about replacing the loop with ffs/__ffs that would be more elegant, shorter and avoid any problem or doubt?
This is getting rediculious. You can pursue this further if you want, but I think we've wasted enough time with this non-bug.
Who is getting bootup failures due to this problem?
Answer: nobody
Quoted 9 lines · David S. Miller
From: Luca Barbieri <[email protected]>
Date: 28 Aug 2002 05:57:50 +0200Quoted 1 line · David S. Miller
Realistically possible with any known configuration?
How about replacing the loop with ffs/__ffs that would be more elegant, shorter and avoid any problem or doubt?
Quoted 6 lines
This is getting rediculious. You can pursue this further if you want, but I think we've wasted enough time with this non-bug.
Who is getting bootup failures due to this problem?
Answer: nobody
I'm not saying that it's serious bug, just that using __ffs is more appropriate than reimplementing it incorrectly and inefficiently.
From: Luca Barbieri <[email protected]>
Date: 28 Aug 2002 06:10:39 +0200
I'm not saying that it's serious bug, just that using __ffs is more appropriate than reimplementing it incorrectly and inefficiently.
ffs won't find the smallest power of 2 >= some_arbitrary_value. That is what this code is doing.
I've personally wasted enough typing on this thread, so enough....
Quoted 4 lines · David S. Miller
How about (unsigned long)(~0)?
Realistically possible with any known configuration?
You tell me. You're saying a billion pages (((unsigned long)(~0)) >> 2) also crashes) is never going to be realistically possible? Sounds like Bill Gates when he said (and I don't know the word- for-word quote) "Who's ever going to need more than 640K??" What if we get into 64 bit addressing? What if there is some sort of bug that passes all 1s on the stack for just this one instance? Never could "realistically" happen? Yeah, right; I've seen weirder things than that.
It's a question of mandatory paranoid sanity checking in an OS wherever possible. Linux is trying to be known as robust. Are you saying that a supposedly robust kernel should have a chance to crash in an infinite loop during initialization because there isn't code doing input validation when there isn't an optimization or speed issue?
Quoted 8 lines · David S. Miller
From: Luca Barbieri <[email protected]>
Date: 28 Aug 2002 06:10:39 +0200I'm not saying that it's serious bug, just that using
__ffsis more appropriate than reimplementing it incorrectly and inefficiently.ffs won't find the smallest power of 2 >=
some_arbitrary_value. That is what this code is doing.
Yes you are right, fls should be used there, not ffs.
From: "Stephen Biggs" <[email protected]>
Date: Tue, 27 Aug 2002 21:29:06 -0700
You tell me. You're saying a billion pages (((unsigned long)(~0)) >> 2) also crashes) is never going to be realistically possible?
On a 32-bit system? No. x86 cpus are architectually limited to 64GB of memory, shift that right by PAGE_SIZE (13) and we're still within bounds.
Larger memory will be then be found on 64-bit systems, and hey then the limit becomes significantly higher.
So that is exactly what I am saying, it is not realistically possible.
Followup to: <[email protected]> By author: "David S. Miller" <[email protected]> In newsgroup: linux.dev.kernel
Quoted 11 lines
From: "Stephen Biggs" <[email protected]>
Date: Tue, 27 Aug 2002 21:29:06 -0700You tell me. You're saying a billion pages (((unsigned long)(~0)) >> 2) also crashes) is never going to be realistically possible?
On a 32-bit system? No. x86 cpus are architectually limited to 64GB of memory, shift that right by
PAGE_SIZE(13) and we're
still within bounds. ^^^^^^^^^^^^^^
PAGE_SHIFT, 12.
The maximum possible page count of any known 32-bit system (64 GB @ 4K for x86) is 2^24 pages.
-hpa
Signature · 3 lines
<[email protected]> at work, <[email protected]> in private! "Unix gives you enough rope to shoot yourself in the foot." http://www.zytor.com/~hpa/puzzle.txt <[email protected]>