Skip to content

Commit c84cb37

Browse files
committed
x86/apic: Move TSC deadline timer debug printk
Leon reported that the printk_once() in __setup_APIC_LVTT() triggers a lockdep splat due to a lock order violation between hrtimer_base::lock and console_sem, when the 'once' condition is reset via /sys/kernel/debug/clear_warn_once after boot. The initial printk cannot trigger this because that happens during boot when the local APIC timer is set up on the boot CPU. Prevent it by moving the printk to a place which is guaranteed to be only called once during boot. Mark the deadline timer check related functions and data __init while at it. Reported-by: Leon Romanovsky <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent fdc63ff commit c84cb37

File tree

1 file changed

+14
-13
lines changed

1 file changed

+14
-13
lines changed

arch/x86/kernel/apic/apic.c

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,6 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
352352
* According to Intel, MFENCE can do the serialization here.
353353
*/
354354
asm volatile("mfence" : : : "memory");
355-
356-
printk_once(KERN_DEBUG "TSC deadline timer enabled\n");
357355
return;
358356
}
359357

@@ -546,7 +544,7 @@ static struct clock_event_device lapic_clockevent = {
546544
};
547545
static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
548546

549-
static u32 hsx_deadline_rev(void)
547+
static __init u32 hsx_deadline_rev(void)
550548
{
551549
switch (boot_cpu_data.x86_stepping) {
552550
case 0x02: return 0x3a; /* EP */
@@ -556,7 +554,7 @@ static u32 hsx_deadline_rev(void)
556554
return ~0U;
557555
}
558556

559-
static u32 bdx_deadline_rev(void)
557+
static __init u32 bdx_deadline_rev(void)
560558
{
561559
switch (boot_cpu_data.x86_stepping) {
562560
case 0x02: return 0x00000011;
@@ -568,7 +566,7 @@ static u32 bdx_deadline_rev(void)
568566
return ~0U;
569567
}
570568

571-
static u32 skx_deadline_rev(void)
569+
static __init u32 skx_deadline_rev(void)
572570
{
573571
switch (boot_cpu_data.x86_stepping) {
574572
case 0x03: return 0x01000136;
@@ -581,7 +579,7 @@ static u32 skx_deadline_rev(void)
581579
return ~0U;
582580
}
583581

584-
static const struct x86_cpu_id deadline_match[] = {
582+
static const struct x86_cpu_id deadline_match[] __initconst = {
585583
X86_MATCH_INTEL_FAM6_MODEL( HASWELL_X, &hsx_deadline_rev),
586584
X86_MATCH_INTEL_FAM6_MODEL( BROADWELL_X, 0x0b000020),
587585
X86_MATCH_INTEL_FAM6_MODEL( BROADWELL_D, &bdx_deadline_rev),
@@ -603,18 +601,19 @@ static const struct x86_cpu_id deadline_match[] = {
603601
{},
604602
};
605603

606-
static void apic_check_deadline_errata(void)
604+
static __init bool apic_validate_deadline_timer(void)
607605
{
608606
const struct x86_cpu_id *m;
609607
u32 rev;
610608

611-
if (!boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER) ||
612-
boot_cpu_has(X86_FEATURE_HYPERVISOR))
613-
return;
609+
if (!boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER))
610+
return false;
611+
if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
612+
return true;
614613

615614
m = x86_match_cpu(deadline_match);
616615
if (!m)
617-
return;
616+
return true;
618617

619618
/*
620619
* Function pointers will have the MSB set due to address layout,
@@ -626,11 +625,12 @@ static void apic_check_deadline_errata(void)
626625
rev = (u32)m->driver_data;
627626

628627
if (boot_cpu_data.microcode >= rev)
629-
return;
628+
return true;
630629

631630
setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE_TIMER);
632631
pr_err(FW_BUG "TSC_DEADLINE disabled due to Errata; "
633632
"please update microcode to version: 0x%x (or later)\n", rev);
633+
return false;
634634
}
635635

636636
/*
@@ -2092,7 +2092,8 @@ void __init init_apic_mappings(void)
20922092
{
20932093
unsigned int new_apicid;
20942094

2095-
apic_check_deadline_errata();
2095+
if (apic_validate_deadline_timer())
2096+
pr_debug("TSC deadline timer available\n");
20962097

20972098
if (x2apic_mode) {
20982099
boot_cpu_physical_apicid = read_apic_id();

0 commit comments

Comments
 (0)