From nobody Wed Dec 29 15:47:00 2021 X-Original-To: dev-commits-src-all@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 738D01917CE7; Wed, 29 Dec 2021 15:47:01 +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 4JPG450PmSz4Ts8; Wed, 29 Dec 2021 15:47:01 +0000 (UTC) (envelope-from git@FreeBSD.org) 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 DCDF727792; Wed, 29 Dec 2021 15:47:00 +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 1BTFl0PV001442; Wed, 29 Dec 2021 15:47:00 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 1BTFl01m001441; Wed, 29 Dec 2021 15:47:00 GMT (envelope-from git) Date: Wed, 29 Dec 2021 15:47:00 GMT Message-Id: <202112291547.1BTFl01m001441@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mark Johnston Subject: git: c2f86ca65b67 - stable/13 - x86: Defer LAPIC calibration until after timecounters are available List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: c2f86ca65b67533899401eb9c74e40da58e287ed Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1640792821; 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=XZJ2hXSqpi+CqTXgqrRLO4OhgGsDK1Ef6wbyPuklijA=; b=v8HnnR2AjbIj44rZa/XMfBgrCc8Eii8VXu+KgAYV24++jNWJwVJon/9Qh2ZkDh0iUrUg3T 18zBZdRDnMsF2CJBxjuz0Wzz2EbV6nOwJADt/Kk+t+XGqCzn434ehKETuB3wsxPQiXMPNj UDidPPb09SvpSEJ6ZUdjC2lvlcRpxADtp4jLlgJsi/6qrpQW5PnpjYqU22z7WbJ/NkEPqu 2dAjDwWeXihb5deVBW1mMtg/SYE8DFwWgv4bnNx3XZmIg1Shb2lDTEBWw/8R5OiFLaUSfL A+thImhG9sUbQ0OQk8zhl8tf3O6ecJUuQfm4n9hG4zVaykt0V3QYhgBDXWf+4A== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1640792821; a=rsa-sha256; cv=none; b=JG43f9BMc0/EZ2KpNLvcnbaS1dt/3FvoQLyhXSlvbLlM0NJu1BAQsAK8czZqdoPz6f59kS aHdS8yGIdIadX2jj1odR5/BQ1mqIQRT40pFJxdRbmKufMHGFCgd+5iLSPrl+sv12zojfEg myNKqCUsfCU6hry7n5QwH/8goUVPMspihsMqUzPN3dWjDpoJr6DucmeQtDgapl69I+tAnw Dq+ZvUvJa/XBYw9jFWfCFhS7vXay4eB6PRbC8lyOjoHIM+9AeVuLmgsuSYhZX/j+FLW6JF hyNNjF1o3EwsAMrRWIt0dKrYBv6F5zYr/RjUA7E6tKDUoQbAgf2syGVIL5qM4Q== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=c2f86ca65b67533899401eb9c74e40da58e287ed commit c2f86ca65b67533899401eb9c74e40da58e287ed Author: Mark Johnston AuthorDate: 2021-12-06 15:42:10 +0000 Commit: Mark Johnston CommitDate: 2021-12-29 15:39:10 +0000 x86: Defer LAPIC calibration until after timecounters are available This ensures that we have a good reference timecounter for performing calibration. Change lapic_setup to avoid configuring the timer when booting, and move calibration and initial configuration to a new lapic routine, lapic_calibrate_timer. This calibration will be initiated from cpu_initclocks(), before an eventtimer is selected. Reviewed by: kib, jhb Sponsored by: The FreeBSD Foundation (cherry picked from commit 62d09b46ad7508ae74d462e49234f0a80f91ff69) --- sys/x86/include/apicvar.h | 10 +++++++++ sys/x86/include/clock.h | 1 + sys/x86/isa/clock.c | 4 ++++ sys/x86/x86/local_apic.c | 57 ++++++++++++++++++++++++----------------------- sys/x86/xen/xen_apic.c | 7 ++++++ 5 files changed, 51 insertions(+), 28 deletions(-) diff --git a/sys/x86/include/apicvar.h b/sys/x86/include/apicvar.h index f1794afa0bbd..373e7d576426 100644 --- a/sys/x86/include/apicvar.h +++ b/sys/x86/include/apicvar.h @@ -229,6 +229,9 @@ struct apic_ops { void (*disable_vector)(u_int, u_int); void (*free_vector)(u_int, u_int, u_int); + /* Timer */ + void (*calibrate_timer)(void); + /* PMC */ int (*enable_pmc)(void); void (*disable_pmc)(void); @@ -376,6 +379,13 @@ apic_free_vector(u_int apic_id, u_int vector, u_int irq) apic_ops.free_vector(apic_id, vector, irq); } +static inline void +lapic_calibrate_timer(void) +{ + + apic_ops.calibrate_timer(); +} + static inline int lapic_enable_pmc(void) { diff --git a/sys/x86/include/clock.h b/sys/x86/include/clock.h index 86a4541568ed..d492196bac85 100644 --- a/sys/x86/include/clock.h +++ b/sys/x86/include/clock.h @@ -27,6 +27,7 @@ extern int smp_tsc; void i8254_init(void); void i8254_delay(int); void clock_init(void); +void lapic_calibrate(void); /* * Driver to clock driver interface. diff --git a/sys/x86/isa/clock.c b/sys/x86/isa/clock.c index 568097d18fdf..2eb1c343f4db 100644 --- a/sys/x86/isa/clock.c +++ b/sys/x86/isa/clock.c @@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -411,6 +412,8 @@ cpu_initclocks(void) int i; td = curthread; + + lapic_calibrate_timer(); cpu_initclocks_bsp(); CPU_FOREACH(i) { if (i == 0) @@ -425,6 +428,7 @@ cpu_initclocks(void) sched_unbind(td); thread_unlock(td); #else + lapic_calibrate_timer(); cpu_initclocks_bsp(); #endif } diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c index b35c4ab459fa..85f4ef1a9c6d 100644 --- a/sys/x86/x86/local_apic.c +++ b/sys/x86/x86/local_apic.c @@ -214,7 +214,6 @@ SYSCTL_INT(_hw_apic, OID_AUTO, timer_tsc_deadline, CTLFLAG_RD, &lapic_timer_tsc_deadline, 0, ""); static void lapic_calibrate_initcount(struct lapic *la); -static void lapic_calibrate_deadline(struct lapic *la); /* * Use __nosanitizethread to exempt the LAPIC I/O accessors from KCSan @@ -366,6 +365,7 @@ static void native_apic_enable_vector(u_int apic_id, u_int vector); static void native_apic_free_vector(u_int apic_id, u_int vector, u_int irq); static void native_lapic_set_logical_id(u_int apic_id, u_int cluster, u_int cluster_id); +static void native_lapic_calibrate_timer(void); static int native_lapic_enable_pmc(void); static void native_lapic_disable_pmc(void); static void native_lapic_reenable_pmc(void); @@ -405,6 +405,7 @@ struct apic_ops apic_ops = { .enable_vector = native_apic_enable_vector, .disable_vector = native_apic_disable_vector, .free_vector = native_apic_free_vector, + .calibrate_timer = native_lapic_calibrate_timer, .enable_pmc = native_lapic_enable_pmc, .disable_pmc = native_lapic_disable_pmc, .reenable_pmc = native_lapic_reenable_pmc, @@ -797,21 +798,18 @@ native_lapic_setup(int boot) LAPIC_LVT_PCINT)); } - /* Program timer LVT. */ + /* + * Program the timer LVT. Calibration is deferred until it is certain + * that we have a reliable timecounter. + */ la->lvt_timer_base = lvt_mode(la, APIC_LVT_TIMER, lapic_read32(LAPIC_LVT_TIMER)); la->lvt_timer_last = la->lvt_timer_base; lapic_write32(LAPIC_LVT_TIMER, la->lvt_timer_base); - /* Calibrate the timer parameters using BSP. */ - if (boot && IS_BSP()) { - lapic_calibrate_initcount(la); - if (lapic_timer_tsc_deadline) - lapic_calibrate_deadline(la); - } - - /* Setup the timer if configured. */ - if (la->la_timer_mode != LAT_MODE_UNDEF) { + if (boot) + la->la_timer_mode = LAT_MODE_UNDEF; + else if (la->la_timer_mode != LAT_MODE_UNDEF) { KASSERT(la->la_timer_period != 0, ("lapic%u: zero divisor", lapic_id())); switch (la->la_timer_mode) { @@ -902,6 +900,25 @@ lapic_update_pmc(void *dummy) } #endif +static void +native_lapic_calibrate_timer(void) +{ + struct lapic *la; + register_t intr; + + intr = intr_disable(); + la = &lapics[lapic_id()]; + + lapic_calibrate_initcount(la); + + intr_restore(intr); + + if (lapic_timer_tsc_deadline && bootverbose) { + printf("lapic: deadline tsc mode, Frequency %ju Hz\n", + (uintmax_t)tsc_freq); + } +} + static int native_lapic_enable_pmc(void) { @@ -992,27 +1009,11 @@ lapic_calibrate_initcount(struct lapic *la) count_freq = value; } -static void -lapic_calibrate_deadline(struct lapic *la __unused) -{ - - if (bootverbose) { - printf("lapic: deadline tsc mode, Frequency %ju Hz\n", - (uintmax_t)tsc_freq); - } -} - static void lapic_change_mode(struct eventtimer *et, struct lapic *la, enum lat_timer_mode newmode) { - - /* - * The TSC frequency may change during late calibration against other - * timecounters (HPET or ACPI PMTimer). - */ - if (la->la_timer_mode == newmode && - (newmode != LAT_MODE_DEADLINE || et->et_frequency == tsc_freq)) + if (la->la_timer_mode == newmode) return; switch (newmode) { case LAT_MODE_PERIODIC: diff --git a/sys/x86/xen/xen_apic.c b/sys/x86/xen/xen_apic.c index 01dae36de2e8..b553e5248716 100644 --- a/sys/x86/xen/xen_apic.c +++ b/sys/x86/xen/xen_apic.c @@ -223,6 +223,12 @@ xen_pv_apic_free_vector(u_int apic_id, u_int vector, u_int irq) XEN_APIC_UNSUPPORTED; } +static void +xen_pv_lapic_calibrate_timer(void) +{ + +} + static void xen_pv_lapic_set_logical_id(u_int apic_id, u_int cluster, u_int cluster_id) { @@ -420,6 +426,7 @@ struct apic_ops xen_apic_ops = { .enable_vector = xen_pv_apic_enable_vector, .disable_vector = xen_pv_apic_disable_vector, .free_vector = xen_pv_apic_free_vector, + .calibrate_timer = xen_pv_lapic_calibrate_timer, .enable_pmc = xen_pv_lapic_enable_pmc, .disable_pmc = xen_pv_lapic_disable_pmc, .reenable_pmc = xen_pv_lapic_reenable_pmc,