From nobody Mon Dec 06 16:21:49 2021 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 42B1B18B08CE; Mon, 6 Dec 2021 16:21:50 +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 4J77ws39fWz4t9q; Mon, 6 Dec 2021 16:21:49 +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 39BE56EA6; Mon, 6 Dec 2021 16:21:49 +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 1B6GLnF8070867; Mon, 6 Dec 2021 16:21:49 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 1B6GLnbZ070866; Mon, 6 Dec 2021 16:21:49 GMT (envelope-from git) Date: Mon, 6 Dec 2021 16:21:49 GMT Message-Id: <202112061621.1B6GLnbZ070866@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mark Johnston Subject: git: 62d09b46ad75 - main - x86: Defer LAPIC calibration until after timecounters are available 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: markj X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 62d09b46ad7508ae74d462e49234f0a80f91ff69 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1638807709; 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=HKEhvYZUHX43JsHDZpWRygbHDwmuk9fNcgOpIIbnGKE=; b=AEdqceBg2l2mnNkOIM5JQdW9Z+F1/HsFbNXLtfNoKEclF1/36YhJeU/pkZQLex/gAIWXTI reB9unD93XacQ4Rvj+Ra1lI7P4XuRI4q3vC/igER49u1gy8ju2al0diYR5zTmy7DgW2OlC ZfRkVPMxd9oi20paPR5lUY5PCmIMWJo4WPan8WsvzB5Q5elQaPrDC1pUfVLS6Mlt3VFwWM 3YyAaI07n9lWEns9lqtubDlIY78RBwcpdmXFje96BGloGZs9E1ODOJvzQ36CxhmG3LeO/W L1dBfJFsrz1bBdK0qT3/LnMHSJqhOIl5iU+8BRApei/tQ/7U/SH8ff9IWGZMyw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1638807709; a=rsa-sha256; cv=none; b=Hkkd8Jw0OjfwrgDIisT4ZI27QCEVl744xcBkmKXLZRhovcewXH6aXcR2jEoAXY0bmEqAuT M2TvNYwJPRPaT33PN1CHhm5Myg6eKAAIvRG5cPun4Sx4QvBdaBO/WQCcss+lihGhUJfeQQ pKM5uY0zVFacEF8B/hnaNMC/PqaGIaRM64TdrTBcQlqRVClB0oC7N5gsSyIm2QcefJsRtU uOSW3YvhoncF9V2UkY1iszCrU3gz3pimbRM4KYRDLe/jMrA7xd0WWh7a1IClwngTXK4JFm KoTTdpAoRG1JxE+f9Oix1ngF1PK5JaJ/NrUKne1vhIi9MCpWbpCP+4deAniHdA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=62d09b46ad7508ae74d462e49234f0a80f91ff69 commit 62d09b46ad7508ae74d462e49234f0a80f91ff69 Author: Mark Johnston AuthorDate: 2021-12-06 15:42:10 +0000 Commit: Mark Johnston CommitDate: 2021-12-06 15:42: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 MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D33206 --- 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 778760be1921..7e8db869a884 100644 --- a/sys/x86/x86/local_apic.c +++ b/sys/x86/x86/local_apic.c @@ -221,7 +221,6 @@ SYSCTL_INT(_hw_apic, OID_AUTO, ds_idle_timeout, CTLFLAG_RWTUN, #endif 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 @@ -373,6 +372,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); @@ -412,6 +412,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, @@ -804,21 +805,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) { @@ -909,6 +907,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) { @@ -999,27 +1016,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,