From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 20DD845A9E; Wed, 2 Oct 2024 18:59:01 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id B9CFB402CF; Wed, 2 Oct 2024 18:58:54 +0200 (CEST) Received: from mail-ej1-f54.google.com (mail-ej1-f54.google.com [209.85.218.54]) by mails.dpdk.org (Postfix) with ESMTP id A7ECB40656 for ; Wed, 2 Oct 2024 18:58:53 +0200 (CEST) Received: by mail-ej1-f54.google.com with SMTP id a640c23a62f3a-a86e9db75b9so1263015066b.1 for ; Wed, 02 Oct 2024 09:58:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727888333; x=1728493133; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=IaG/HqZxbhkkh8jG/2WtgX5UFsEUwpagsTGYvwVqqzQ=; b=SacV4yjY0tBm7yEaZMA3IZ0+mwECHqwYmqw6oiXQOXObmE5gQK2y8MIAk2AgGbHpcY vXI8CBuQaF3dTkWlIir0TFniGIAVAccAnEID9W9MR+dYmztlEE/4dm+oQGIL7PbQ7GAE QdC/6C1W9UyV1Xd0Pl4rYlh3YYtcoihLKvTvXE4QHRqw2vaNQLJTVWPLC8uqkxe/0PMH tKfG/u3W5PtnaRaHacqxf/vDj3Z6pTYWKsKKyLIRQJ1UBtWzh/k10k2kH5yRu6ViEOzI qxr+TfPx+OLzVLeUA4LlUlStVUPNgSYRIlzN0zePNbZeX1ir15jWkzgZFMXoYQ0L8iDj BcKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727888333; x=1728493133; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=IaG/HqZxbhkkh8jG/2WtgX5UFsEUwpagsTGYvwVqqzQ=; b=frox7wicrRSiKTx/lOTu5/2U8nJ+zf08HfeWU1NcgfcUNIw42XjUIO7/6UiF/6k/cF p1FljTFf55+Kt/lZacZMq7ytX/vCPuEHpOSicd2J49vNk4c4AGt9lo58uk/si8RsFa93 xIDjXVThr916P6ZEHoaWI4Tvsk3YkpmGBEH1iWnhb3tac5p5TAZDZJOw1DMQ7FRG5zn1 uDvzJ5Rt8uh9G5lpAcCLuw8SCJFEuwwl4KR2HXdIoM0XhAS6iGE8ZzV8EfMAX99dyGtg TuOGUoykTW53Q+B0XwIh1xKXU0Dcono4L0ohUfNxrnQnYjWndY3oxa5BZxijdpi5+rZR MJzw== X-Gm-Message-State: AOJu0Yz3MNhkTf5NicuM/xxkD5utIF1cefXJiptSNH7FD/ukDB7Q9IFE uzK4qP3zFE1lo/vJg+11ZBRkmeH9+k2xwDqcl+gvpMFOlEGedg7As3B7XdzR X-Google-Smtp-Source: AGHT+IFg1YrTVdPcdl0dL4wzbmW0eOavV1iMz+QOsS1e0z+bCNyzOFOFPE6LVHVTLJlk77IWv2SRMA== X-Received: by 2002:a17:907:e88:b0:a86:9776:ef40 with SMTP id a640c23a62f3a-a98f8257e9bmr329742266b.36.1727888332469; Wed, 02 Oct 2024 09:58:52 -0700 (PDT) Received: from localhost.localdomain (85-250-29-188.bb.netvision.net.il. [85.250.29.188]) by smtp.googlemail.com with ESMTPSA id a640c23a62f3a-a93c2777254sm889947166b.9.2024.10.02.09.58.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Oct 2024 09:58:51 -0700 (PDT) From: Isaac Boukris To: dev@dpdk.org Cc: stephen@networkplumber.org, bruce.richardson@intel.com, roretzla@linux.microsoft.com, dmitry.kozliuk@gmail.com, david.marchand@redhat.com, Isaac Boukris Subject: [PATCH v4 2/2] timer: allow platform to override cpu TSC frequency Date: Wed, 2 Oct 2024 19:56:36 +0300 Message-ID: <20241002165840.341116-3-iboukris@gmail.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: <20241002165840.341116-1-iboukris@gmail.com> References: <20240921140022.107239-1-iboukris@gmail.com> <20241002165840.341116-1-iboukris@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org The CPU value is often not accurate, allow overriding it based on info from the host OS. On Linux X86, if the tsc_known_freq cpu flag is missing, it means the kernel doesn't trust it and calculates its own. We should do the same to avoid drift. On freebsd we have access to the kernel tsc_hz value, just use it. Signed-off-by: Isaac Boukris --- lib/eal/common/eal_common_timer.c | 3 +- lib/eal/common/eal_private.h | 2 +- lib/eal/freebsd/eal_timer.c | 8 +++-- lib/eal/linux/eal_timer.c | 53 +++++++++++++++++++++++++++++-- lib/eal/windows/eal_timer.c | 5 ++- 5 files changed, 62 insertions(+), 9 deletions(-) diff --git a/lib/eal/common/eal_common_timer.c b/lib/eal/common/eal_common_timer.c index c5c4703f15..e00be0a5c8 100644 --- a/lib/eal/common/eal_common_timer.c +++ b/lib/eal/common/eal_common_timer.c @@ -66,8 +66,7 @@ set_tsc_freq(void) } freq = get_tsc_freq_arch(); - if (!freq) - freq = get_tsc_freq(); + freq = get_tsc_freq(freq); if (!freq) freq = estimate_tsc_freq(); diff --git a/lib/eal/common/eal_private.h b/lib/eal/common/eal_private.h index af09620426..bb315dab04 100644 --- a/lib/eal/common/eal_private.h +++ b/lib/eal/common/eal_private.h @@ -374,7 +374,7 @@ void set_tsc_freq(void); * * This function is private to the EAL. */ -uint64_t get_tsc_freq(void); +uint64_t get_tsc_freq(uint64_t arch_hz); /** * Get TSC frequency if the architecture supports. diff --git a/lib/eal/freebsd/eal_timer.c b/lib/eal/freebsd/eal_timer.c index 3dd70e24ba..19fc9a7228 100644 --- a/lib/eal/freebsd/eal_timer.c +++ b/lib/eal/freebsd/eal_timer.c @@ -26,7 +26,7 @@ enum timer_source eal_timer_source = EAL_TIMER_TSC; uint64_t -get_tsc_freq(void) +get_tsc_freq(uint64_t arch_hz) { size_t sz; int tmp; @@ -50,9 +50,13 @@ get_tsc_freq(void) sz = sizeof(tsc_hz); if (sysctlbyname("machdep.tsc_freq", &tsc_hz, &sz, NULL, 0)) { EAL_LOG(WARNING, "%s", strerror(errno)); - return 0; + return arch_hz; } + if (arch_hz && arch_hz - tsc_hz > arch_hz / 100) + EAL_LOG(WARNING, "Host tsc_freq %"PRIu64" at odds with cpu value %"PRIu64, + tsc_hz, arch_hz); + return tsc_hz; } diff --git a/lib/eal/linux/eal_timer.c b/lib/eal/linux/eal_timer.c index f56a7ae15b..2c5fc9ff3e 100644 --- a/lib/eal/linux/eal_timer.c +++ b/lib/eal/linux/eal_timer.c @@ -5,9 +5,9 @@ #include #include +#include #ifdef RTE_LIBEAL_USE_HPET #include -#include #include #include #endif @@ -187,8 +187,41 @@ rte_eal_hpet_init(int make_default) } #endif +/* Check if the kernel deems the arch provided TSC frequency trustworthy. */ + +static bool +is_tsc_known_freq(void) +{ + bool ret = true; /* Assume tsc_known_freq */ + +#if defined(RTE_ARCH_X86) + char line[2048]; + FILE *stream; + + stream = fopen("/proc/cpuinfo", "r"); + if (!stream) { + EAL_LOG(WARNING, "Unable to open /proc/cpuinfo"); + return ret; + } + + while (fgets(line, sizeof(line), stream)) { + if (strncmp(line, "flags", 5) != 0) + continue; + + if (!strstr(line, "tsc_known_freq")) + ret = false; + + break; + } + + fclose(stream); +#endif + + return ret; +} + uint64_t -get_tsc_freq(void) +get_tsc_freq(uint64_t arch_hz) { #ifdef CLOCK_MONOTONIC_RAW #define NS_PER_SEC 1E9 @@ -199,6 +232,9 @@ get_tsc_freq(void) struct timespec t_start, t_end; uint64_t tsc_hz; + if (arch_hz && is_tsc_known_freq()) + return arch_hz; + if (clock_gettime(CLOCK_MONOTONIC_RAW, &t_start) == 0) { uint64_t ns, end, start = rte_rdtsc(); nanosleep(&sleeptime,NULL); @@ -209,11 +245,22 @@ get_tsc_freq(void) double secs = (double)ns/NS_PER_SEC; tsc_hz = (uint64_t)((end - start)/secs); + + if (arch_hz) { + /* Make sure we're within 1% for sanity check */ + if (arch_hz - tsc_hz > arch_hz / 100) + return arch_hz; + + EAL_LOG(DEBUG, + "Refined arch frequency %"PRIu64" to measured frequency %"PRIu64, + arch_hz, tsc_hz); + } + /* Round up to 100Khz. 1E5 ~ 100Khz */ return RTE_ALIGN_MUL_NEAR(tsc_hz, CYC_PER_100KHZ); } #endif - return 0; + return arch_hz; } int diff --git a/lib/eal/windows/eal_timer.c b/lib/eal/windows/eal_timer.c index 4003541b08..020035c4cc 100644 --- a/lib/eal/windows/eal_timer.c +++ b/lib/eal/windows/eal_timer.c @@ -49,13 +49,16 @@ rte_delay_us_sleep(unsigned int us) } uint64_t -get_tsc_freq(void) +get_tsc_freq(uint64_t arch_hz) { LARGE_INTEGER t_start, t_end, elapsed_us; LARGE_INTEGER frequency; uint64_t tsc_hz; uint64_t end, start; + if (arch_hz) + return arch_hz; + QueryPerformanceFrequency(&frequency); QueryPerformanceCounter(&t_start); -- 2.45.0