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 | |
| 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>
| -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 (;;) { |
