From owner-svn-src-head@FreeBSD.ORG Wed Mar 6 19:37:39 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id D257AF6B; Wed, 6 Mar 2013 19:37:39 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id C026B1B4; Wed, 6 Mar 2013 19:37:39 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r26JbdKn044061; Wed, 6 Mar 2013 19:37:39 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r26JbdNR044058; Wed, 6 Mar 2013 19:37:39 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201303061937.r26JbdNR044058@svn.freebsd.org> From: Alexander Motin Date: Wed, 6 Mar 2013 19:37:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r247898 - head/sys/kern X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 06 Mar 2013 19:37:39 -0000 Author: mav Date: Wed Mar 6 19:37:38 2013 New Revision: 247898 URL: http://svnweb.freebsd.org/changeset/base/247898 Log: Fix time math overflows and improve zero intervals handling in poll(), select(), nanosleep() and kevent() functions after calloutng changes. Reported by: bde Modified: head/sys/kern/kern_event.c head/sys/kern/kern_time.c head/sys/kern/sys_generic.c Modified: head/sys/kern/kern_event.c ============================================================================== --- head/sys/kern/kern_event.c Wed Mar 6 18:45:11 2013 (r247897) +++ head/sys/kern/kern_event.c Wed Mar 6 19:37:38 2013 (r247898) @@ -1329,11 +1329,16 @@ kqueue_scan(struct kqueue *kq, int maxev goto done_nl; } if (timespecisset(tsp)) { - rsbt = tstosbt(*tsp); - if (TIMESEL(&asbt, rsbt)) - asbt += tc_tick_sbt; - asbt += rsbt; - rsbt >>= tc_precexp; + if (tsp->tv_sec < INT32_MAX) { + rsbt = tstosbt(*tsp); + if (TIMESEL(&asbt, rsbt)) + asbt += tc_tick_sbt; + asbt += rsbt; + if (asbt < rsbt) + asbt = 0; + rsbt >>= tc_precexp; + } else + asbt = 0; } else asbt = -1; } else Modified: head/sys/kern/kern_time.c ============================================================================== --- head/sys/kern/kern_time.c Wed Mar 6 18:45:11 2013 (r247897) +++ head/sys/kern/kern_time.c Wed Mar 6 19:37:38 2013 (r247898) @@ -484,13 +484,20 @@ kern_nanosleep(struct thread *td, struct { struct timespec ts; sbintime_t sbt, sbtt, prec, tmp; + time_t over; int error; if (rqt->tv_nsec < 0 || rqt->tv_nsec >= 1000000000) return (EINVAL); if (rqt->tv_sec < 0 || (rqt->tv_sec == 0 && rqt->tv_nsec == 0)) return (0); - tmp = tstosbt(*rqt); + ts = *rqt; + if (ts.tv_sec > INT32_MAX / 2) { + over = ts.tv_sec - INT32_MAX / 2; + ts.tv_sec -= over; + } else + over = 0; + tmp = tstosbt(ts); prec = tmp; prec >>= tc_precexp; if (TIMESEL(&sbt, tmp)) @@ -504,6 +511,7 @@ kern_nanosleep(struct thread *td, struct TIMESEL(&sbtt, tmp); if (rmt != NULL) { ts = sbttots(sbt - sbtt); + ts.tv_sec += over; if (ts.tv_sec < 0) timespecclear(&ts); *rmt = ts; Modified: head/sys/kern/sys_generic.c ============================================================================== --- head/sys/kern/sys_generic.c Wed Mar 6 18:45:11 2013 (r247897) +++ head/sys/kern/sys_generic.c Wed Mar 6 19:37:38 2013 (r247898) @@ -1051,12 +1051,19 @@ kern_select(struct thread *td, int nd, f error = EINVAL; goto done; } - rsbt = tvtosbt(rtv); - precision = rsbt; - precision >>= tc_precexp; - if (TIMESEL(&asbt, rsbt)) - asbt += tc_tick_sbt; - asbt += rsbt; + if (rtv.tv_sec == 0 && rtv.tv_usec == 0) + asbt = 0; + else if (rtv.tv_sec < INT32_MAX) { + rsbt = tvtosbt(rtv); + precision = rsbt; + precision >>= tc_precexp; + if (TIMESEL(&asbt, rsbt)) + asbt += tc_tick_sbt; + asbt += rsbt; + if (asbt < rsbt) + asbt = -1; + } else + asbt = -1; } else asbt = -1; seltdinit(td); @@ -1295,12 +1302,16 @@ sys_poll(td, uap) error = EINVAL; goto done; } - rsbt = SBT_1MS * uap->timeout; - precision = rsbt; - precision >>= tc_precexp; - if (TIMESEL(&asbt, rsbt)) - asbt += tc_tick_sbt; - asbt += rsbt; + if (uap->timeout == 0) + asbt = 0; + else { + rsbt = SBT_1MS * uap->timeout; + precision = rsbt; + precision >>= tc_precexp; + if (TIMESEL(&asbt, rsbt)) + asbt += tc_tick_sbt; + asbt += rsbt; + } } else asbt = -1; seltdinit(td);