diff options
author | Arjan van de Ven <arjan@linux.intel.com> | 2008-09-07 19:08:55 -0400 |
---|---|---|
committer | Arjan van de Ven <arjan@linux.intel.com> | 2008-09-07 19:11:04 -0400 |
commit | 96d2ab484e7a9bafdab44b8c7d1ef5944319b18c (patch) | |
tree | 3938e40a4b70295d7318d6b14777d0f02004438d /fs/select.c | |
parent | 704af52bd13a5d9f3c60c496c68e752fafdfb434 (diff) |
hrtimer: fix signed/unsigned bug in slack estimator
the slack estimator used unsigned math; however for very short delay it's
possible that by the time you calculate the timeout, it's already passed and
you get a negative time/slack... in an unsigned variable... which then gets
turned into a 100 msec delay rather than zero.
This patch fixes this by using a signed typee in the right places.
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Diffstat (limited to 'fs/select.c')
-rw-r--r-- | fs/select.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/fs/select.c b/fs/select.c index fdd8584e536d..448e44001286 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -41,9 +41,9 @@ | |||
41 | * better solutions.. | 41 | * better solutions.. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | static unsigned long __estimate_accuracy(struct timespec *tv) | 44 | static long __estimate_accuracy(struct timespec *tv) |
45 | { | 45 | { |
46 | unsigned long slack; | 46 | long slack; |
47 | int divfactor = 1000; | 47 | int divfactor = 1000; |
48 | 48 | ||
49 | if (task_nice(current) > 0) | 49 | if (task_nice(current) > 0) |
@@ -54,10 +54,13 @@ static unsigned long __estimate_accuracy(struct timespec *tv) | |||
54 | 54 | ||
55 | if (slack > 100 * NSEC_PER_MSEC) | 55 | if (slack > 100 * NSEC_PER_MSEC) |
56 | slack = 100 * NSEC_PER_MSEC; | 56 | slack = 100 * NSEC_PER_MSEC; |
57 | |||
58 | if (slack < 0) | ||
59 | slack = 0; | ||
57 | return slack; | 60 | return slack; |
58 | } | 61 | } |
59 | 62 | ||
60 | static unsigned long estimate_accuracy(struct timespec *tv) | 63 | static long estimate_accuracy(struct timespec *tv) |
61 | { | 64 | { |
62 | unsigned long ret; | 65 | unsigned long ret; |
63 | struct timespec now; | 66 | struct timespec now; |
@@ -330,7 +333,7 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time) | |||
330 | timed_out = 1; | 333 | timed_out = 1; |
331 | } | 334 | } |
332 | 335 | ||
333 | if (end_time) | 336 | if (end_time && !timed_out) |
334 | slack = estimate_accuracy(end_time); | 337 | slack = estimate_accuracy(end_time); |
335 | 338 | ||
336 | retval = 0; | 339 | retval = 0; |
@@ -656,7 +659,7 @@ static int do_poll(unsigned int nfds, struct poll_list *list, | |||
656 | timed_out = 1; | 659 | timed_out = 1; |
657 | } | 660 | } |
658 | 661 | ||
659 | if (end_time) | 662 | if (end_time && !timed_out) |
660 | slack = estimate_accuracy(end_time); | 663 | slack = estimate_accuracy(end_time); |
661 | 664 | ||
662 | for (;;) { | 665 | for (;;) { |