Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp2212473imm; Thu, 19 Jul 2018 15:32:39 -0700 (PDT) X-Google-Smtp-Source: AAOMgpekzr/mmUsn4lIGqfjsaL+gjeIlUUDAYBN3N8QZI41Eh+k5mTSYBBhJ2xTjmY3aO9DbgoQ6 X-Received: by 2002:a63:9802:: with SMTP id q2-v6mr11665232pgd.70.1532039559072; Thu, 19 Jul 2018 15:32:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1532039559; cv=none; d=google.com; s=arc-20160816; b=TqL1bJNDAiNs/97uJpnDZWdVZIQmNWVDg7sCwpmrXWQ77d7/E8o7ADH7YNgAG5+UNI a7KW8f8ponOk5Asx5aZiPIp/0GUoFda8c7det4M8toesZj+nAJhB+u4MFkbSFGYIcL7x 3BvyNn1rxQ/dQtoFjrXp7p8CWjIeQsn9ZIz+gJ9PS1nVIXc0pbr2x7RKsRUCOIhW4hCo CNB6AY+2VbAn0aR6VV2ziq2aIR/j3qANiHokYevUFhWuhSWQkJ5a/dGg9xDTDdn+wl4D Pz9mH+h/7dvUf5bWW0+H/GR6Y6EimIufHKU3T1LM2CFWgi8vZcof0/UaU9fAFAlkmYOi AWfQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-disposition :content-transfer-encoding:mime-version:robot-unsubscribe:robot-id :git-commit-id:subject:to:references:in-reply-to:reply-to:cc :message-id:from:date:arc-authentication-results; bh=Ey7ETEVfQOrnq518UulTwxLJwx/XaHGxVNRccN3hDC4=; b=CX/9zbNSVeUdtBevjnkEKUN14Jq9JCZKTTDmo+++HDAaWVJLq/lKr5Ccx7JPT1uBY2 GR13hdSEkWUsnI30nOIicwxyaHX9gETI4dYU8YHVyJlBcoFCCPb9vG7+zEVBXczSMYPT 5Gr5jxKXhAZHJaHcsNaHGA/NJHbk0XY/ObgIWpWlYMT1v5fGmXcgeJL+IJDHOj6Ej2T0 Uq0NqsUpxJDsT2YiLb06++d08Ae4QbJS7EtPB/KrZJzCj/x4Zmet80wEAFzETv6snfGu Fbz1hXRnvAliRTuDBwF16SB5SrltZhv95tm0X6Cxz7O3Li4AD3twFWZoJj2Lk0ppDAln 58RA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v17-v6si298286pgk.135.2018.07.19.15.32.24; Thu, 19 Jul 2018 15:32:39 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731269AbeGSXRD (ORCPT + 99 others); Thu, 19 Jul 2018 19:17:03 -0400 Received: from terminus.zytor.com ([198.137.202.136]:44623 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730369AbeGSXRD (ORCPT ); Thu, 19 Jul 2018 19:17:03 -0400 Received: from terminus.zytor.com (localhost [127.0.0.1]) by terminus.zytor.com (8.15.2/8.15.2) with ESMTPS id w6JMVlTV2439590 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 19 Jul 2018 15:31:47 -0700 Received: (from tipbot@localhost) by terminus.zytor.com (8.15.2/8.15.2/Submit) id w6JMVlhd2439587; Thu, 19 Jul 2018 15:31:47 -0700 Date: Thu, 19 Jul 2018 15:31:47 -0700 X-Authentication-Warning: terminus.zytor.com: tipbot set sender to tipbot@zytor.com using -f From: tip-bot for Pavel Tatashin Message-ID: Cc: mingo@kernel.org, tglx@linutronix.de, pasha.tatashin@oracle.com, hpa@zytor.com, linux-kernel@vger.kernel.org Reply-To: linux-kernel@vger.kernel.org, hpa@zytor.com, pasha.tatashin@oracle.com, mingo@kernel.org, tglx@linutronix.de In-Reply-To: <20180719205545.16512-21-pasha.tatashin@oracle.com> References: <20180719205545.16512-21-pasha.tatashin@oracle.com> To: linux-tip-commits@vger.kernel.org Subject: [tip:x86/timers] x86/tsc: Initialize cyc2ns when tsc frequency is determined Git-Commit-ID: e2a9ca29b5edc89da2fddeae30e1070b272395c5 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00, DATE_IN_FUTURE_96_Q autolearn=ham autolearn_force=no version=3.4.1 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on terminus.zytor.com Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: e2a9ca29b5edc89da2fddeae30e1070b272395c5 Gitweb: https://git.kernel.org/tip/e2a9ca29b5edc89da2fddeae30e1070b272395c5 Author: Pavel Tatashin AuthorDate: Thu, 19 Jul 2018 16:55:39 -0400 Committer: Thomas Gleixner CommitDate: Fri, 20 Jul 2018 00:02:42 +0200 x86/tsc: Initialize cyc2ns when tsc frequency is determined cyc2ns converts tsc to nanoseconds, and it is handled in a per-cpu data structure. Currently, the setup code for c2ns data for every possible CPU goes through the same sequence of calculations as for the boot CPU, but is based on the same tsc frequency as the boot CPU, and thus this is not necessary. Initialize the boot cpu when tsc frequency is determined. Copy the calculated data from the boot CPU to the other CPUs in tsc_init(). In addition do the following: - Remove unnecessary zeroing of c2ns data by removing cyc2ns_data_init() - Split set_cyc2ns_scale() into two functions, so set_cyc2ns_scale() can be called when system is up, and wraps around __set_cyc2ns_scale() that can be called directly when system is booting but avoids saving restoring IRQs and going and waking up from idle. Suggested-by: Thomas Gleixner Signed-off-by: Pavel Tatashin Signed-off-by: Thomas Gleixner Cc: steven.sistare@oracle.com Cc: daniel.m.jordan@oracle.com Cc: linux@armlinux.org.uk Cc: schwidefsky@de.ibm.com Cc: heiko.carstens@de.ibm.com Cc: john.stultz@linaro.org Cc: sboyd@codeaurora.org Cc: hpa@zytor.com Cc: douly.fnst@cn.fujitsu.com Cc: peterz@infradead.org Cc: prarit@redhat.com Cc: feng.tang@intel.com Cc: pmladek@suse.com Cc: gnomes@lxorguk.ukuu.org.uk Cc: linux-s390@vger.kernel.org Cc: boris.ostrovsky@oracle.com Cc: jgross@suse.com Cc: pbonzini@redhat.com Link: https://lkml.kernel.org/r/20180719205545.16512-21-pasha.tatashin@oracle.com --- arch/x86/kernel/tsc.c | 94 +++++++++++++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 41 deletions(-) diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 4cab2236169e..7ea0718a4c75 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -103,23 +103,6 @@ void cyc2ns_read_end(void) * -johnstul@us.ibm.com "math is hard, lets go shopping!" */ -static void cyc2ns_data_init(struct cyc2ns_data *data) -{ - data->cyc2ns_mul = 0; - data->cyc2ns_shift = 0; - data->cyc2ns_offset = 0; -} - -static void __init cyc2ns_init(int cpu) -{ - struct cyc2ns *c2n = &per_cpu(cyc2ns, cpu); - - cyc2ns_data_init(&c2n->data[0]); - cyc2ns_data_init(&c2n->data[1]); - - seqcount_init(&c2n->seq); -} - static inline unsigned long long cycles_2_ns(unsigned long long cyc) { struct cyc2ns_data data; @@ -135,18 +118,11 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc) return ns; } -static void set_cyc2ns_scale(unsigned long khz, int cpu, unsigned long long tsc_now) +static void __set_cyc2ns_scale(unsigned long khz, int cpu, unsigned long long tsc_now) { unsigned long long ns_now; struct cyc2ns_data data; struct cyc2ns *c2n; - unsigned long flags; - - local_irq_save(flags); - sched_clock_idle_sleep_event(); - - if (!khz) - goto done; ns_now = cycles_2_ns(tsc_now); @@ -178,12 +154,55 @@ static void set_cyc2ns_scale(unsigned long khz, int cpu, unsigned long long tsc_ c2n->data[0] = data; raw_write_seqcount_latch(&c2n->seq); c2n->data[1] = data; +} + +static void set_cyc2ns_scale(unsigned long khz, int cpu, unsigned long long tsc_now) +{ + unsigned long flags; + + local_irq_save(flags); + sched_clock_idle_sleep_event(); + + if (khz) + __set_cyc2ns_scale(khz, cpu, tsc_now); -done: sched_clock_idle_wakeup_event(); local_irq_restore(flags); } +/* + * Initialize cyc2ns for boot cpu + */ +static void __init cyc2ns_init_boot_cpu(void) +{ + struct cyc2ns *c2n = this_cpu_ptr(&cyc2ns); + + seqcount_init(&c2n->seq); + __set_cyc2ns_scale(tsc_khz, smp_processor_id(), rdtsc()); +} + +/* + * Secondary CPUs do not run through cyc2ns_init(), so set up + * all the scale factors for all CPUs, assuming the same + * speed as the bootup CPU. (cpufreq notifiers will fix this + * up if their speed diverges) + */ +static void __init cyc2ns_init_secondary_cpus(void) +{ + unsigned int cpu, this_cpu = smp_processor_id(); + struct cyc2ns *c2n = this_cpu_ptr(&cyc2ns); + struct cyc2ns_data *data = c2n->data; + + for_each_possible_cpu(cpu) { + if (cpu != this_cpu) { + seqcount_init(&c2n->seq); + c2n = per_cpu_ptr(&cyc2ns, cpu); + c2n->data[0] = data[0]; + c2n->data[1] = data[1]; + } + } +} + /* * Scheduler clock - returns current time in nanosec units. */ @@ -1385,6 +1404,10 @@ void __init tsc_early_init(void) if (!determine_cpu_tsc_frequencies()) return; loops_per_jiffy = get_loops_per_jiffy(); + + /* Sanitize TSC ADJUST before cyc2ns gets initialized */ + tsc_store_and_check_tsc_adjust(true); + cyc2ns_init_boot_cpu(); } void __init tsc_init(void) @@ -1401,23 +1424,12 @@ void __init tsc_init(void) setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE_TIMER); return; } + /* Sanitize TSC ADJUST before cyc2ns gets initialized */ + tsc_store_and_check_tsc_adjust(true); + cyc2ns_init_boot_cpu(); } - /* Sanitize TSC ADJUST before cyc2ns gets initialized */ - tsc_store_and_check_tsc_adjust(true); - - /* - * Secondary CPUs do not run through tsc_init(), so set up - * all the scale factors for all CPUs, assuming the same - * speed as the bootup CPU. (cpufreq notifiers will fix this - * up if their speed diverges) - */ - cyc = rdtsc(); - for_each_possible_cpu(cpu) { - cyc2ns_init(cpu); - set_cyc2ns_scale(tsc_khz, cpu, cyc); - } - + cyc2ns_init_secondary_cpus(); static_branch_enable(&__use_tsc); if (!no_sched_irq_time)