From patchwork Mon Jul 27 00:56:33 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Monjalon X-Patchwork-Id: 6600 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 4EC84C4FE; Mon, 27 Jul 2015 02:57:59 +0200 (CEST) Received: from mail-wi0-f175.google.com (mail-wi0-f175.google.com [209.85.212.175]) by dpdk.org (Postfix) with ESMTP id 3E77BC4FA for ; Mon, 27 Jul 2015 02:57:57 +0200 (CEST) Received: by wicmv11 with SMTP id mv11so119776836wic.0 for ; Sun, 26 Jul 2015 17:57:57 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=8PdQ3sxx1YRbgV2SvjTjgjiLgmaAdHNLN6hsEMpbL+o=; b=Jy5UuLa2SkKJRCBWhJJUT9Anzn2r3b0dAy9dUJMI2xlVAedoB0dnwXnk3UjB+9vu7P C7LgGtJqgJXZZcGVbYhjhRQClnOBOkFGKGBINdsUnboj46RJu5dP5xIT+nsqJeOHQy9U 14H4y3gy46K33JNQGx2myA11JB4jUe9tVtZDbQbsBMeEhAhJ/sr2XDor+0VXvrLRyEio jw01HyQZVWh12tf8TTYDCAdAx3b1EaRxHn8yLcZH9YdgpqPplAp3CplYOgl1LZGhnRRZ sJjEHxIPIeI31h9ve5cCM0TurVOhz3Nm4rfRDEyzV5qO++q4Op0pnDZxYopcul819sn1 Dhmw== X-Gm-Message-State: ALoCoQmrorQFgrCWPdiyd5DEV5vuOHlitRaiV6Z6Ncil4lbF3suB5W078R2f/X4teTRdJs4oM3OH X-Received: by 10.194.184.140 with SMTP id eu12mr48022783wjc.78.1437958677022; Sun, 26 Jul 2015 17:57:57 -0700 (PDT) Received: from localhost.localdomain (136-92-190-109.dsl.ovh.fr. [109.190.92.136]) by smtp.gmail.com with ESMTPSA id dz4sm10733801wib.17.2015.07.26.17.57.55 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 26 Jul 2015 17:57:56 -0700 (PDT) From: Thomas Monjalon To: david.marchand@6wind.com Date: Mon, 27 Jul 2015 02:56:33 +0200 Message-Id: <1437958594-29468-3-git-send-email-thomas.monjalon@6wind.com> X-Mailer: git-send-email 2.4.2 In-Reply-To: <1437958594-29468-1-git-send-email-thomas.monjalon@6wind.com> References: <1437852868-6031-1-git-send-email-rkerur@gmail.com> <1437958594-29468-1-git-send-email-thomas.monjalon@6wind.com> Cc: dev@dpdk.org Subject: [dpdk-dev] [PATCH v10 2/3] eal: deduplicate timer functions X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Ravi Kerur Move common functions from BSD/Linux to eal_common_timer.c. BSD uses sysctl and Linux uses CLOCK_MONOTIC_RAW to calibrate TSC. HPET is specific to Linux and not integrated in the common init. Signed-off-by: Ravi Kerur Signed-off-by: Thomas Monjalon --- lib/librte_eal/bsdapp/eal/Makefile | 1 + lib/librte_eal/bsdapp/eal/eal_timer.c | 58 ++-------------- .../eal/eal_timer.c => common/eal_common_timer.c} | 79 +++------------------- lib/librte_eal/common/eal_private.h | 14 ++++ lib/librte_eal/linuxapp/eal/Makefile | 1 + lib/librte_eal/linuxapp/eal/eal_timer.c | 60 ++-------------- 6 files changed, 39 insertions(+), 174 deletions(-) copy lib/librte_eal/{bsdapp/eal/eal_timer.c => common/eal_common_timer.c} (57%) diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile index 24733ae..a969435 100644 --- a/lib/librte_eal/bsdapp/eal/Makefile +++ b/lib/librte_eal/bsdapp/eal/Makefile @@ -61,6 +61,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_alarm.c # from common dir SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_lcore.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_timer.c SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_memzone.c SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_log.c SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_launch.c diff --git a/lib/librte_eal/bsdapp/eal/eal_timer.c b/lib/librte_eal/bsdapp/eal/eal_timer.c index 7147abe..f12d9bd 100644 --- a/lib/librte_eal/bsdapp/eal/eal_timer.c +++ b/lib/librte_eal/bsdapp/eal/eal_timer.c @@ -55,29 +55,12 @@ enum timer_source eal_timer_source = EAL_TIMER_TSC; -/* The frequency of the RDTSC timer resolution */ -static uint64_t eal_tsc_resolution_hz = 0; - -void -rte_delay_us(unsigned us) -{ - const uint64_t start = rte_get_timer_cycles(); - const uint64_t ticks = (uint64_t)us * rte_get_timer_hz() / 1E6; - while ((rte_get_timer_cycles() - start) < ticks) - rte_pause(); -} - uint64_t -rte_get_tsc_hz(void) -{ - return eal_tsc_resolution_hz; -} - -static int -set_tsc_freq_from_sysctl(void) +get_tsc_freq(void) { size_t sz; int tmp; + uint64_t tsc_hz; sz = sizeof(tmp); tmp = 0; @@ -94,42 +77,13 @@ set_tsc_freq_from_sysctl(void) else if (tmp != 1) RTE_LOG(WARNING, EAL, "TSC is not invariant\n"); - sz = sizeof(eal_tsc_resolution_hz); - if (sysctlbyname("machdep.tsc_freq", &eal_tsc_resolution_hz, &sz, NULL, 0)) { + sz = sizeof(tsc_hz); + if (sysctlbyname("machdep.tsc_freq", &tsc_hz, &sz, NULL, 0)) { RTE_LOG(WARNING, EAL, "%s\n", strerror(errno)); - return -1; + return 0; } - return 0; -} - -static void -set_tsc_freq_fallback(void) -{ - RTE_LOG(WARNING, EAL, "WARNING: clock_gettime cannot use " - "CLOCK_MONOTONIC_RAW and HPET is not available" - " - clock timings may be less accurate.\n"); - /* assume that the sleep(1) will sleep for 1 second */ - uint64_t start = rte_rdtsc(); - sleep(1); - eal_tsc_resolution_hz = rte_rdtsc() - start; -} - -/* - * This function measures the TSC frequency. It uses a variety of approaches. - * - * 1. Read the TSC frequency value provided by the kernel - * 2. If above does not work, just sleep for 1 second and tune off that, - * printing a warning about inaccuracy of timing - */ -static void -set_tsc_freq(void) -{ - if (set_tsc_freq_from_sysctl() < 0) - set_tsc_freq_fallback(); - - RTE_LOG(INFO, EAL, "TSC frequency is ~%"PRIu64" KHz\n", - eal_tsc_resolution_hz/1000); + return tsc_hz; } int diff --git a/lib/librte_eal/bsdapp/eal/eal_timer.c b/lib/librte_eal/common/eal_common_timer.c similarity index 57% copy from lib/librte_eal/bsdapp/eal/eal_timer.c copy to lib/librte_eal/common/eal_common_timer.c index 7147abe..2956703 100644 --- a/lib/librte_eal/bsdapp/eal/eal_timer.c +++ b/lib/librte_eal/common/eal_common_timer.c @@ -30,6 +30,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #include #include #include @@ -41,22 +42,11 @@ #include #include #include -#include -#include -#include -#include #include "eal_private.h" -#include "eal_internal_cfg.h" - -#ifdef RTE_LIBEAL_USE_HPET -#warning HPET is not supported in FreeBSD -#endif - -enum timer_source eal_timer_source = EAL_TIMER_TSC; /* The frequency of the RDTSC timer resolution */ -static uint64_t eal_tsc_resolution_hz = 0; +static uint64_t eal_tsc_resolution_hz; void rte_delay_us(unsigned us) @@ -73,68 +63,21 @@ rte_get_tsc_hz(void) return eal_tsc_resolution_hz; } -static int -set_tsc_freq_from_sysctl(void) +static uint64_t +estimate_tsc_freq(void) { - size_t sz; - int tmp; - - sz = sizeof(tmp); - tmp = 0; - - if (sysctlbyname("kern.timecounter.smp_tsc", &tmp, &sz, NULL, 0)) - RTE_LOG(WARNING, EAL, "%s\n", strerror(errno)); - else if (tmp != 1) - RTE_LOG(WARNING, EAL, "TSC is not safe to use in SMP mode\n"); - - tmp = 0; - - if (sysctlbyname("kern.timecounter.invariant_tsc", &tmp, &sz, NULL, 0)) - RTE_LOG(WARNING, EAL, "%s\n", strerror(errno)); - else if (tmp != 1) - RTE_LOG(WARNING, EAL, "TSC is not invariant\n"); - - sz = sizeof(eal_tsc_resolution_hz); - if (sysctlbyname("machdep.tsc_freq", &eal_tsc_resolution_hz, &sz, NULL, 0)) { - RTE_LOG(WARNING, EAL, "%s\n", strerror(errno)); - return -1; - } - - return 0; -} - -static void -set_tsc_freq_fallback(void) -{ - RTE_LOG(WARNING, EAL, "WARNING: clock_gettime cannot use " - "CLOCK_MONOTONIC_RAW and HPET is not available" - " - clock timings may be less accurate.\n"); + RTE_LOG(WARNING, EAL, "WARNING: TSC frequency estimated roughly" + " - clock timings may be less accurate.\n"); /* assume that the sleep(1) will sleep for 1 second */ uint64_t start = rte_rdtsc(); sleep(1); - eal_tsc_resolution_hz = rte_rdtsc() - start; + return rte_rdtsc() - start; } -/* - * This function measures the TSC frequency. It uses a variety of approaches. - * - * 1. Read the TSC frequency value provided by the kernel - * 2. If above does not work, just sleep for 1 second and tune off that, - * printing a warning about inaccuracy of timing - */ -static void +void set_tsc_freq(void) { - if (set_tsc_freq_from_sysctl() < 0) - set_tsc_freq_fallback(); - - RTE_LOG(INFO, EAL, "TSC frequency is ~%"PRIu64" KHz\n", - eal_tsc_resolution_hz/1000); -} - -int -rte_eal_timer_init(void) -{ - set_tsc_freq(); - return 0; + uint64_t freq = get_tsc_freq() || estimate_tsc_freq(); + RTE_LOG(INFO, EAL, "TSC frequency is ~%" PRIu64 " KHz\n", freq / 1000); + eal_tsc_resolution_hz = freq; } diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h index 8505b05..f8e8869 100644 --- a/lib/librte_eal/common/eal_private.h +++ b/lib/librte_eal/common/eal_private.h @@ -314,4 +314,18 @@ unsigned eal_cpu_core_id(unsigned lcore_id); */ int eal_cpu_detected(unsigned lcore_id); +/** + * Set TSC frequency from precise value or estimation + * + * This function is private to the EAL. + */ +void set_tsc_freq(void); + +/** + * Get precise TSC frequency from system + * + * This function is private to the EAL. + */ +uint64_t get_tsc_freq(void); + #endif /* _EAL_PRIVATE_H_ */ diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile index f4f8cdf..376d275 100644 --- a/lib/librte_eal/linuxapp/eal/Makefile +++ b/lib/librte_eal/linuxapp/eal/Makefile @@ -71,6 +71,7 @@ endif # from common dir SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_lcore.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_timer.c SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_memzone.c SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_log.c SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_launch.c diff --git a/lib/librte_eal/linuxapp/eal/eal_timer.c b/lib/librte_eal/linuxapp/eal/eal_timer.c index 94909ed..76a8a65 100644 --- a/lib/librte_eal/linuxapp/eal/eal_timer.c +++ b/lib/librte_eal/linuxapp/eal/eal_timer.c @@ -57,9 +57,6 @@ enum timer_source eal_timer_source = EAL_TIMER_HPET; -/* The frequency of the RDTSC timer resolution */ -static uint64_t eal_tsc_resolution_hz = 0; - #ifdef RTE_LIBEAL_USE_HPET #define DEV_HPET "/dev/hpet" @@ -160,23 +157,6 @@ rte_get_hpet_cycles(void) #endif - -void -rte_delay_us(unsigned us) -{ - const uint64_t start = rte_get_timer_cycles(); - const uint64_t ticks = (uint64_t)us * rte_get_timer_hz() / 1E6; - while ((rte_get_timer_cycles() - start) < ticks) - rte_pause(); -} - -uint64_t -rte_get_tsc_hz(void) -{ - return eal_tsc_resolution_hz; -} - - #ifdef RTE_LIBEAL_USE_HPET /* * Open and mmap /dev/hpet (high precision event timer) that will @@ -275,8 +255,8 @@ check_tsc_flags(void) fclose(stream); } -static int -set_tsc_freq_from_clock(void) +uint64_t +get_tsc_freq(void) { #ifdef CLOCK_MONOTONIC_RAW #define NS_PER_SEC 1E9 @@ -284,6 +264,7 @@ set_tsc_freq_from_clock(void) struct timespec sleeptime = {.tv_nsec = 5E8 }; /* 1/2 second */ struct timespec t_start, t_end; + uint64_t tsc_hz; if (clock_gettime(CLOCK_MONOTONIC_RAW, &t_start) == 0) { uint64_t ns, end, start = rte_rdtsc(); @@ -294,40 +275,11 @@ set_tsc_freq_from_clock(void) ns += (t_end.tv_nsec - t_start.tv_nsec); double secs = (double)ns/NS_PER_SEC; - eal_tsc_resolution_hz = (uint64_t)((end - start)/secs); - return 0; + tsc_hz = (uint64_t)((end - start)/secs); + return tsc_hz; } #endif - return -1; -} - -static void -set_tsc_freq_fallback(void) -{ - RTE_LOG(WARNING, EAL, "WARNING: clock_gettime cannot use " - "CLOCK_MONOTONIC_RAW and HPET is not available" - " - clock timings may be less accurate.\n"); - /* assume that the sleep(1) will sleep for 1 second */ - uint64_t start = rte_rdtsc(); - sleep(1); - eal_tsc_resolution_hz = rte_rdtsc() - start; -} -/* - * This function measures the TSC frequency. It uses a variety of approaches. - * - * 1. If kernel provides CLOCK_MONOTONIC_RAW we use that to tune the TSC value - * 2. If kernel does not provide that, and we have HPET support, tune using HPET - * 3. Lastly, if neither of the above can be used, just sleep for 1 second and - * tune off that, printing a warning about inaccuracy of timing - */ -static void -set_tsc_freq(void) -{ - if (set_tsc_freq_from_clock() < 0) - set_tsc_freq_fallback(); - - RTE_LOG(INFO, EAL, "TSC frequency is ~%"PRIu64" KHz\n", - eal_tsc_resolution_hz/1000); + return 0; } int