From 8bf4bbe390af3f370e7e95d9237572ff750047a8 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 12 May 2010 10:56:45 -0700 Subject: [PATCH] poll-loop: Change poll_timer_wait() parameter from "int" to "long long". Every so often I get concerned because OVS does most of its time arithmetic in "long long int" but poll_timer_wait() takes an "int", so there is potential for truncating a large value to a small value or a positive value to a negative value. That would cause excessive wakeups and possibly 100% CPU usage. This commit therefore changes poll_timer_wait()'s parameter type from "int" to "long long int". The file-scope 'timeout' variable remains type "int" because that is the type of poll()'s timeout argument. Factoring poll_timer_wait() into two functions is not necessary here but it comes in handy in the following patch. --- lib/learning-switch.c | 7 +------ lib/poll-loop.c | 23 ++++++++++++++++------- lib/poll-loop.h | 4 ++-- ovsdb/trigger.c | 4 ++-- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/lib/learning-switch.c b/lib/learning-switch.c index 126cc6b89..91f8f0527 100644 --- a/lib/learning-switch.c +++ b/lib/learning-switch.c @@ -221,12 +221,7 @@ static void wait_timeout(long long int started) { long long int now = time_msec(); - long long int timeout = 10000 - (now - started); - if (timeout <= 0) { - poll_immediate_wake(); - } else { - poll_timer_wait(timeout); - } + poll_timer_wait(10000 - (now - started)); } void diff --git a/lib/poll-loop.c b/lib/poll-loop.c index 8f65f9402..29931f785 100644 --- a/lib/poll-loop.c +++ b/lib/poll-loop.c @@ -73,6 +73,18 @@ poll_fd_wait(int fd, short int events) return new_waiter(fd, events); } +/* The caller must ensure that 'msec' is not negative. */ +static void +poll_timer_wait__(int msec) +{ + if (timeout < 0 || msec < timeout) { + timeout = msec; + if (VLOG_IS_DBG_ENABLED()) { + backtrace_capture(&timeout_backtrace); + } + } +} + /* Causes the following call to poll_block() to block for no more than 'msec' * milliseconds. If 'msec' is nonpositive, the following call to poll_block() * will not block at all. @@ -81,14 +93,11 @@ poll_fd_wait(int fd, short int events) * is affected. The timer will need to be re-registered after poll_block() is * called if it is to persist. */ void -poll_timer_wait(int msec) +poll_timer_wait(long long int msec) { - if (timeout < 0 || msec < timeout) { - timeout = MAX(0, msec); - if (VLOG_IS_DBG_ENABLED()) { - backtrace_capture(&timeout_backtrace); - } - } + poll_timer_wait__(msec < 0 ? 0 + : msec > INT_MAX ? INT_MAX + : msec); } /* Causes the following call to poll_block() to wake up immediately, without diff --git a/lib/poll-loop.h b/lib/poll-loop.h index adb88d482..eaeca2be5 100644 --- a/lib/poll-loop.h +++ b/lib/poll-loop.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009 Nicira Networks. + * Copyright (c) 2008, 2009, 2010 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,7 +42,7 @@ struct poll_waiter; /* Schedule events to wake up the following poll_block(). */ struct poll_waiter *poll_fd_wait(int fd, short int events); -void poll_timer_wait(int msec); +void poll_timer_wait(long long int msec); void poll_immediate_wake(void); /* Wait until an event occurs. */ diff --git a/ovsdb/trigger.c b/ovsdb/trigger.c index 1ecfdcac1..8f18291f4 100644 --- a/ovsdb/trigger.c +++ b/ovsdb/trigger.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009 Nicira Networks +/* Copyright (c) 2009, 2010 Nicira Networks * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -102,7 +102,7 @@ ovsdb_trigger_wait(struct ovsdb *db, long long int now) } if (deadline < LLONG_MAX) { - poll_timer_wait(MIN(deadline - now, INT_MAX)); + poll_timer_wait(deadline - now); } } } -- 2.39.5