summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArjan van de Ven <arjan@linux.intel.com>2008-09-07 16:08:55 -0700
committerArjan van de Ven <arjan@linux.intel.com>2008-09-07 16:11:04 -0700
commit96d2ab484e7a9bafdab44b8c7d1ef5944319b18c (patch)
tree3938e40a4b70295d7318d6b14777d0f02004438d
parent704af52bd13a5d9f3c60c496c68e752fafdfb434 (diff)
downloadlwn-96d2ab484e7a9bafdab44b8c7d1ef5944319b18c.tar.gz
lwn-96d2ab484e7a9bafdab44b8c7d1ef5944319b18c.zip
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.c13
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 @@
* better solutions..
*/
-static unsigned long __estimate_accuracy(struct timespec *tv)
+static long __estimate_accuracy(struct timespec *tv)
{
- unsigned long slack;
+ long slack;
int divfactor = 1000;
if (task_nice(current) > 0)
@@ -54,10 +54,13 @@ static unsigned long __estimate_accuracy(struct timespec *tv)
if (slack > 100 * NSEC_PER_MSEC)
slack = 100 * NSEC_PER_MSEC;
+
+ if (slack < 0)
+ slack = 0;
return slack;
}
-static unsigned long estimate_accuracy(struct timespec *tv)
+static long estimate_accuracy(struct timespec *tv)
{
unsigned long ret;
struct timespec now;
@@ -330,7 +333,7 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
timed_out = 1;
}
- if (end_time)
+ if (end_time && !timed_out)
slack = estimate_accuracy(end_time);
retval = 0;
@@ -656,7 +659,7 @@ static int do_poll(unsigned int nfds, struct poll_list *list,
timed_out = 1;
}
- if (end_time)
+ if (end_time && !timed_out)
slack = estimate_accuracy(end_time);
for (;;) {