From nobody Mon Mar 21 13:34:09 2022 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 0A3191A14294; Mon, 21 Mar 2022 13:34:10 +0000 (UTC) (envelope-from git@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 "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4KMbDx6PBrz4XZp; Mon, 21 Mar 2022 13:34:09 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1647869649; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=PthBOmg1XahTGvTnycU2CnL44vapkzykw94Cjvpyd54=; b=d8Fu+6qlugd0nTRWZ+62ciqUt83AFwBM82li/1boXXHmXPZFzuNeh2iUr8vtCBR/cr7Fh/ 3zO6F9p35x5ZFLl1IHABpDIl/pHm9802omk7Yb8MotVRe0MHAzAoG4zGZSS0Mi4++lq7gw HVqXr8zHrVqnnpCdd6JAQ0MUCAUdTIAg3qhWeMmaAJhULjIABg4JdQqlSfJzMkVTw27Iwr 5nSRgRRApE4U2ZHpq+MVIhGrM+eUdW/4PhfC+8FqIdb8+bX3VLTFKnJ1rErywHBLQ7T82O 6icgk7lfFKfzNGbdwt8VdElEtECl5QjBsNsDCwAFXmiKRWm5SRABKOvzbUp52w== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (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 did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id BBA041C0C7; Mon, 21 Mar 2022 13:34:09 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 22LDY9bd029581; Mon, 21 Mar 2022 13:34:09 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 22LDY9da029580; Mon, 21 Mar 2022 13:34:09 GMT (envelope-from git) Date: Mon, 21 Mar 2022 13:34:09 GMT Message-Id: <202203211334.22LDY9da029580@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: "George V. Neville-Neil" Subject: git: bb53dd56c30c - main - kern_tc.c/cputick2usec() (which is used to calculate cputime from cpu ticks) has some imprecision and, worse, huge timestep (about 20 minutes on 4GHz CPU) near 53.4 days of elapsed time. List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: gnn X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: bb53dd56c30c6360fc82be762ed98b0af6b9f69f Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1647869649; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=PthBOmg1XahTGvTnycU2CnL44vapkzykw94Cjvpyd54=; b=Jp/r0CsrCeTk5xtqtwu9X6YwdyzJfzdJOu7fVqfUTE2OQYqedVeKzq0TyGo4asIZ5OgF8c 6qMizd9bmbD27pH5T+SxV61Rs/tQvxF9jWFQE1H6On41kDtnNOK4QQAQu2IwlxuT2j9WOF 7tbNhJVstObpdPPvPMge9z29FQjyTaRGpAfVwqriX2DA5VFLiRnhtx7MEblXccrSnVTUNP MwnLfXpXEHfDGoeEe++dIQQUEgL1bf8u/aljqOAk0qDMLQHEtmEdq7bWc8GEP96m1IBT5i 21awcnWXPS83XfSmHXtCensbNVRQ/JGgImvGlCPosaBtoNaWrbX3x+nbIVztlg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1647869649; a=rsa-sha256; cv=none; b=w7ObdKAsAHKr/Wcm9WBMalKyzDMeykKt6bKponYUsoJop64XAydm4evL7W6redM5YJzgrb c22MCvHVuQ3WqFd/LJncmypOi5iLQn8FPg/8lFBCCc6jY1UPGRYG6b7PLWqFGYU980+zZg 6sl0TjsdlNaMKBMxzWWVRHrwXs7PljyZfQpmYZMxhrcFPyzNNmhJx9qbsH/xM0vAjHMo/L GCKpM9hVdPL5X7nhpOV9z5Mig6oV8df0/dUWtayfTBqX9EMEGsDboAFpKa9P7BaKzFlV2+ 8dApM0rl7m1djuV1GW/RTsxbl9OiRIgb6tnSYH3QaXCoGv/CGIQdDFvmM0M+OA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by gnn: URL: https://cgit.FreeBSD.org/src/commit/?id=bb53dd56c30c6360fc82be762ed98b0af6b9f69f commit bb53dd56c30c6360fc82be762ed98b0af6b9f69f Author: firk AuthorDate: 2022-03-21 13:33:11 +0000 Commit: George V. Neville-Neil CommitDate: 2022-03-21 13:33:46 +0000 kern_tc.c/cputick2usec() (which is used to calculate cputime from cpu ticks) has some imprecision and, worse, huge timestep (about 20 minutes on 4GHz CPU) near 53.4 days of elapsed time. kern_time.c/cputick2timespec() (it is used for clock_gettime() for querying process or thread consumed cpu time) Uses cputick2usec() and then needlessly converting usec to nsec, obviously losing precision even with fixed cputick2usec(). kern_time.c/kern_clock_getres() uses some weird (anyway wrong) formula for getting cputick resolution. PR: 262215 Reviewed by: gnn Differential Revision: https://reviews.freebsd.org/D34558 --- lib/libkvm/kvm_proc.c | 9 ++------- sys/kern/kern_tc.c | 12 +++--------- sys/kern/kern_time.c | 12 +++++------- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c index 5058e86a645b..1af4ce38615f 100644 --- a/lib/libkvm/kvm_proc.c +++ b/lib/libkvm/kvm_proc.c @@ -94,15 +94,10 @@ static uint64_t cpu_tick_frequency; static uint64_t cputick2usec(uint64_t tick) { - if (cpu_tick_frequency == 0) return (0); - if (tick > 18446744073709551) /* floor(2^64 / 1000) */ - return (tick / (cpu_tick_frequency / 1000000)); - else if (tick > 18446744073709) /* floor(2^64 / 1000000) */ - return ((tick * 1000) / (cpu_tick_frequency / 1000)); - else - return ((tick * 1000000) / cpu_tick_frequency); + return ((tick / cpu_tick_frequency) * 1000000ULL) + + ((tick % cpu_tick_frequency) * 1000000ULL) / cpu_tick_frequency; } /* diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c index 01b4e8656090..fcdec7a58200 100644 --- a/sys/kern/kern_tc.c +++ b/sys/kern/kern_tc.c @@ -2155,20 +2155,14 @@ cpu_tickrate(void) * years) and in 64 bits at 4 GHz (146 years), but if we do a multiply * before divide conversion (to retain precision) we find that the * margin shrinks to 1.5 hours (one millionth of 146y). - * With a three prong approach we never lose significant bits, no - * matter what the cputick rate and length of timeinterval is. */ uint64_t cputick2usec(uint64_t tick) { - - if (tick > 18446744073709551LL) /* floor(2^64 / 1000) */ - return (tick / (cpu_tickrate() / 1000000LL)); - else if (tick > 18446744073709LL) /* floor(2^64 / 1000000) */ - return ((tick * 1000LL) / (cpu_tickrate() / 1000LL)); - else - return ((tick * 1000000LL) / cpu_tickrate()); + uint64_t tr; + tr = cpu_tickrate(); + return ((tick / tr) * 1000000ULL) + ((tick % tr) * 1000000ULL) / tr; } cpu_tick_f *cpu_ticks = tc_cpu_ticks; diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index 0bab05c65ffc..194a23fdc9e8 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -245,9 +245,10 @@ sys_clock_gettime(struct thread *td, struct clock_gettime_args *uap) static inline void cputick2timespec(uint64_t runtime, struct timespec *ats) { - runtime = cputick2usec(runtime); - ats->tv_sec = runtime / 1000000; - ats->tv_nsec = runtime % 1000000 * 1000; + uint64_t tr; + tr = cpu_tickrate(); + ats->tv_sec = runtime / tr; + ats->tv_nsec = ((runtime % tr) * 1000000000ULL) / tr; } void @@ -477,10 +478,7 @@ kern_clock_getres(struct thread *td, clockid_t clock_id, struct timespec *ts) case CLOCK_THREAD_CPUTIME_ID: case CLOCK_PROCESS_CPUTIME_ID: cputime: - /* sync with cputick2usec */ - ts->tv_nsec = 1000000 / cpu_tickrate(); - if (ts->tv_nsec == 0) - ts->tv_nsec = 1000; + ts->tv_nsec = 1000000000 / cpu_tickrate() + 1; break; default: if ((int)clock_id < 0)