Commit 41cf54455da5e5dc847a9733d49ca23b5e7dd59e
Committed by
Linus Torvalds
1 parent
8b9365d753
Exists in
master
and in
39 other branches
[PATCH] Fix multiple conversion bugs in msecs_to_jiffies
Fix multiple conversion bugs in msecs_to_jiffies(). The main problem is that this condition: if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET)) overflows if HZ is smaller than 1000! This change is user-visible: for HZ=250 SUS-compliant poll()-timeout value of -20 is mistakenly converted to 'immediate timeout'. (The new dyntick code also triggered this, that's how we noticed.) Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: john stultz <johnstul@us.ibm.com> Cc: Roman Zippel <zippel@linux-m68k.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 42 additions and 1 deletions Side-by-side Diff
kernel/time.c
... | ... | @@ -500,15 +500,56 @@ |
500 | 500 | } |
501 | 501 | EXPORT_SYMBOL(jiffies_to_usecs); |
502 | 502 | |
503 | +/* | |
504 | + * When we convert to jiffies then we interpret incoming values | |
505 | + * the following way: | |
506 | + * | |
507 | + * - negative values mean 'infinite timeout' (MAX_JIFFY_OFFSET) | |
508 | + * | |
509 | + * - 'too large' values [that would result in larger than | |
510 | + * MAX_JIFFY_OFFSET values] mean 'infinite timeout' too. | |
511 | + * | |
512 | + * - all other values are converted to jiffies by either multiplying | |
513 | + * the input value by a factor or dividing it with a factor | |
514 | + * | |
515 | + * We must also be careful about 32-bit overflows. | |
516 | + */ | |
503 | 517 | unsigned long msecs_to_jiffies(const unsigned int m) |
504 | 518 | { |
505 | - if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET)) | |
519 | + /* | |
520 | + * Negative value, means infinite timeout: | |
521 | + */ | |
522 | + if ((int)m < 0) | |
506 | 523 | return MAX_JIFFY_OFFSET; |
524 | + | |
507 | 525 | #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) |
526 | + /* | |
527 | + * HZ is equal to or smaller than 1000, and 1000 is a nice | |
528 | + * round multiple of HZ, divide with the factor between them, | |
529 | + * but round upwards: | |
530 | + */ | |
508 | 531 | return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ); |
509 | 532 | #elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC) |
533 | + /* | |
534 | + * HZ is larger than 1000, and HZ is a nice round multiple of | |
535 | + * 1000 - simply multiply with the factor between them. | |
536 | + * | |
537 | + * But first make sure the multiplication result cannot | |
538 | + * overflow: | |
539 | + */ | |
540 | + if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET)) | |
541 | + return MAX_JIFFY_OFFSET; | |
542 | + | |
510 | 543 | return m * (HZ / MSEC_PER_SEC); |
511 | 544 | #else |
545 | + /* | |
546 | + * Generic case - multiply, round and divide. But first | |
547 | + * check that if we are doing a net multiplication, that | |
548 | + * we wouldnt overflow: | |
549 | + */ | |
550 | + if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET)) | |
551 | + return MAX_JIFFY_OFFSET; | |
552 | + | |
512 | 553 | return (m * HZ + MSEC_PER_SEC - 1) / MSEC_PER_SEC; |
513 | 554 | #endif |
514 | 555 | } |