Date: Thu, 26 Sep 2013 10:06:51 +0000 (UTC) From: Davide Italiano <davide@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r255877 - head/sys/kern Message-ID: <201309261006.r8QA6poc071285@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: davide Date: Thu Sep 26 10:06:50 2013 New Revision: 255877 URL: http://svnweb.freebsd.org/changeset/base/255877 Log: Make the callout arithmetic more robust adding checks for overflow. Without these, if the timeout value passed is "large enough", the value of the sum of it and other factors (e.g. current time as returned by sbinuptime() or 'precision' argument) might result in a negative number. This negative number is then passed to eventtimers(4), which causes et_start() routine to load et_min_period into eventtimer, making the CPU where the thread is stuck forever in timer interrupt handler routine. This is now avoided rounding to INT64_MAX the timeout period in case of overflow. Reported by: kib, pho Discussed with: kib, mav Tested by: pho (stress2 suite, kevent7.sh scenario) Approved by: re (kib) Modified: head/sys/kern/kern_timeout.c Modified: head/sys/kern/kern_timeout.c ============================================================================== --- head/sys/kern/kern_timeout.c Thu Sep 26 09:16:57 2013 (r255876) +++ head/sys/kern/kern_timeout.c Thu Sep 26 10:06:50 2013 (r255877) @@ -572,6 +572,8 @@ callout_cc_add(struct callout *c, struct * Inform the eventtimers(4) subsystem there's a new callout * that has been inserted, but only if really required. */ + if (INT64_MAX - c->c_time < c->c_precision) + c->c_precision = INT64_MAX - c->c_time; sbt = c->c_time + c->c_precision; if (sbt < cc->cc_firstevent) { cc->cc_firstevent = sbt; @@ -949,7 +951,10 @@ callout_reset_sbt_on(struct callout *c, to_sbt += tick_sbt; } else to_sbt = sbinuptime(); - to_sbt += sbt; + if (INT64_MAX - to_sbt < sbt) + to_sbt = INT64_MAX; + else + to_sbt += sbt; pr = ((C_PRELGET(flags) < 0) ? sbt >> tc_precexp : sbt >> C_PRELGET(flags)); if (pr > precision)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201309261006.r8QA6poc071285>