From owner-svn-src-all@freebsd.org Tue Jul 21 07:58:40 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 46E9937AF93; Tue, 21 Jul 2020 07:58:40 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4B9rZS18LCz4HLB; Tue, 21 Jul 2020 07:58:40 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 0B8E71AFB7; Tue, 21 Jul 2020 07:58:40 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 06L7wdZ4070053; Tue, 21 Jul 2020 07:58:39 GMT (envelope-from avg@FreeBSD.org) Received: (from avg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 06L7wdct070052; Tue, 21 Jul 2020 07:58:39 GMT (envelope-from avg@FreeBSD.org) Message-Id: <202007210758.06L7wdct070052@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: avg set sender to avg@FreeBSD.org using -f From: Andriy Gapon Date: Tue, 21 Jul 2020 07:58:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r363384 - stable/12/sys/sys X-SVN-Group: stable-12 X-SVN-Commit-Author: avg X-SVN-Commit-Paths: stable/12/sys/sys X-SVN-Commit-Revision: 363384 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 21 Jul 2020 07:58:40 -0000 Author: avg Date: Tue Jul 21 07:58:39 2020 New Revision: 363384 URL: https://svnweb.freebsd.org/changeset/base/363384 Log: MFC r340450,r340664,r346176 by imp: fix time conversions to and from sbt Note that the PR is for a change elsewhere (ZFS) that expected the sane behavior of nstosbt(). PR: 247829 Reported by: gbe, others Tested by: gbe, others Modified: stable/12/sys/sys/time.h Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/sys/time.h ============================================================================== --- stable/12/sys/sys/time.h Tue Jul 21 07:41:36 2020 (r363383) +++ stable/12/sys/sys/time.h Tue Jul 21 07:58:39 2020 (r363384) @@ -161,19 +161,58 @@ sbttobt(sbintime_t _sbt) * Decimal<->sbt conversions. Multiplying or dividing by SBT_1NS results in * large roundoff errors which sbttons() and nstosbt() avoid. Millisecond and * microsecond functions are also provided for completeness. + * + * These functions return the smallest sbt larger or equal to the + * number of seconds requested so that sbttoX(Xtosbt(y)) == y. Unlike + * top of second computations below, which require that we tick at the + * top of second, these need to be rounded up so we do whatever for at + * least as long as requested. + * + * The naive computation we'd do is this + * ((unit * 2^64 / SIFACTOR) + 2^32-1) >> 32 + * However, that overflows. Instead, we compute + * ((unit * 2^63 / SIFACTOR) + 2^31-1) >> 32 + * and use pre-computed constants that are the ceil of the 2^63 / SIFACTOR + * term to ensure we are using exactly the right constant. We use the lesser + * evil of ull rather than a uint64_t cast to ensure we have well defined + * right shift semantics. With these changes, we get all the ns, us and ms + * conversions back and forth right. + * Note: This file is used for both kernel and userland includes, so we can't + * rely on KASSERT being defined, nor can we pollute the namespace by including + * assert.h. */ static __inline int64_t sbttons(sbintime_t _sbt) { + uint64_t ns; - return ((1000000000 * _sbt) >> 32); +#ifdef KASSERT + KASSERT(_sbt >= 0, ("Negative values illegal for sbttons: %jx", _sbt)); +#endif + ns = _sbt; + if (ns >= SBT_1S) + ns = (ns >> 32) * 1000000000; + else + ns = 0; + + return (ns + (1000000000 * (_sbt & 0xffffffffu) >> 32)); } static __inline sbintime_t nstosbt(int64_t _ns) { + sbintime_t sb = 0; - return ((_ns * (((uint64_t)1 << 63) / 500000000)) >> 32); +#ifdef KASSERT + KASSERT(_ns >= 0, ("Negative values illegal for nstosbt: %jd", _ns)); +#endif + if (_ns >= SBT_1S) { + sb = (_ns / 1000000000) * SBT_1S; + _ns = _ns % 1000000000; + } + /* 9223372037 = ceil(2^63 / 1000000000) */ + sb += ((_ns * 9223372037ull) + 0x7fffffff) >> 31; + return (sb); } static __inline int64_t @@ -186,8 +225,18 @@ sbttous(sbintime_t _sbt) static __inline sbintime_t ustosbt(int64_t _us) { + sbintime_t sb = 0; - return ((_us * (((uint64_t)1 << 63) / 500000)) >> 32); +#ifdef KASSERT + KASSERT(_us >= 0, ("Negative values illegal for ustosbt: %jd", _us)); +#endif + if (_us >= SBT_1S) { + sb = (_us / 1000000) * SBT_1S; + _us = _us % 1000000; + } + /* 9223372036855 = ceil(2^63 / 1000000) */ + sb += ((_us * 9223372036855ull) + 0x7fffffff) >> 31; + return (sb); } static __inline int64_t @@ -200,8 +249,18 @@ sbttoms(sbintime_t _sbt) static __inline sbintime_t mstosbt(int64_t _ms) { + sbintime_t sb = 0; - return ((_ms * (((uint64_t)1 << 63) / 500)) >> 32); +#ifdef KASSERT + KASSERT(_ms >= 0, ("Negative values illegal for mstosbt: %jd", _ms)); +#endif + if (_ms >= SBT_1S) { + sb = (_ms / 1000) * SBT_1S; + _ms = _ms % 1000; + } + /* 9223372036854776 = ceil(2^63 / 1000) */ + sb += ((_ms * 9223372036854776ull) + 0x7fffffff) >> 31; + return (sb); } /*-