Date: Fri, 15 Apr 2016 15:53:41 +0300 From: Konstantin Belousov <kostikbel@gmail.com> To: Vladimir Zakharov <zakharov.vv@gmail.com> Cc: freebsd-current@freebsd.org Subject: Re: GENERIC-NODEBUG panics, GENERIC does not Message-ID: <20160415125341.GJ2422@kib.kiev.ua> In-Reply-To: <20160415113818.GA1613@vzakharov> References: <20160415102644.GA1380@vzakharov> <20160415105055.GI2422@kib.kiev.ua> <20160415113818.GA1613@vzakharov>
next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, Apr 15, 2016 at 02:38:18PM +0300, Vladimir Zakharov wrote: > On Fri, Apr 15, 2016, Konstantin Belousov wrote: > > On Fri, Apr 15, 2016 at 01:26:44PM +0300, Vladimir Zakharov wrote: > > > Hello > > > > > > Setting 'kern.eventtimer.periodic = 1' in /etc/sysctl.conf leads to > > > GENERIC-NODEBUG panic. GENERIC loads without problems. > > > So do GENERIC-NODEBUG as of r297245. > > > > > > https://imgur.com/0DtDU3m > > > > > > $ uname -a > > > > > > FreeBSD vzakharov 11.0-CURRENT FreeBSD 11.0-CURRENT #4 r298037: Fri Apr > > > 15 12:27:40 MSK 2016 root@vzakharov:/home/obj/usr/src/sys/GENERIC-NODEBUG amd64 > > > > > > > I cannot reproduce it locally. > > Please provide me verbose dmesg from the successfull boot on your machine. > > GENERIC with kern.eventtimer.periodic=1: http://pastebin.com/raw/TB0TKSje > GENERIC-NODEBUG: http://pastebin.com/raw/05CchraS I need _verbose_ dmesg. I need the reports about LAPICs initializations, with register dumps. > > > Also, for the panic, show me the output of the same data as on the > > screenshot and the output of 'show registers'. > > https://imgur.com/pO8Yc3w Ok, this seems to be yet another case of missed count mode divisor initialization. Please try the patch at the end of the messasge. > > > Also please load your kernel into kgdb and do > > list *lapic_et_start+0x281 By 'your kernel' I mean 'your panicing kernel'. diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c index 5830b77..854bda4 100644 --- a/sys/x86/x86/local_apic.c +++ b/sys/x86/x86/local_apic.c @@ -170,7 +170,7 @@ vm_paddr_t lapic_paddr; int x2apic_mode; int lapic_eoi_suppression; static int lapic_timer_tsc_deadline; -static u_long lapic_timer_divisor; +static u_long lapic_timer_divisor, count_freq; static struct eventtimer lapic_et; #ifdef SMP static uint64_t lapic_ipi_wait_mult; @@ -814,20 +814,46 @@ lapic_calibrate_initcount(struct eventtimer *et, struct lapic *la) printf("lapic: Divisor %lu, Frequency %lu Hz\n", lapic_timer_divisor, value); } - et->et_frequency = value; + count_freq = value; } static void lapic_calibrate_deadline(struct eventtimer *et, struct lapic *la __unused) { - et->et_frequency = tsc_freq; if (bootverbose) { printf("lapic: deadline tsc mode, Frequency %ju Hz\n", - (uintmax_t)et->et_frequency); + (uintmax_t)tsc_freq); } } +static void +lapic_change_mode(struct eventtimer *et, struct lapic *la, + enum lat_timer_mode newmode) +{ + + if (la->la_timer_mode == newmode) + return; + switch (newmode) { + case LAT_MODE_PERIODIC: + lapic_timer_set_divisor(lapic_timer_divisor); + et->et_frequency = count_freq; + break; + case LAT_MODE_DEADLINE: + et->et_frequency = tsc_freq; + break; + case LAT_MODE_ONESHOT: + lapic_timer_set_divisor(lapic_timer_divisor); + et->et_frequency = count_freq; + break; + default: + panic("lapic_change_mode %d", newmode); + } + la->la_timer_mode = newmode; + et->et_min_period = (0x00000002LLU << 32) / et->et_frequency; + et->et_max_period = (0xfffffffeLLU << 32) / et->et_frequency; +} + static int lapic_et_start(struct eventtimer *et, sbintime_t first, sbintime_t period) { @@ -835,28 +861,21 @@ lapic_et_start(struct eventtimer *et, sbintime_t first, sbintime_t period) la = &lapics[PCPU_GET(apic_id)]; if (et->et_frequency == 0) { + lapic_calibrate_initcount(et, la); if (lapic_timer_tsc_deadline) lapic_calibrate_deadline(et, la); - else - lapic_calibrate_initcount(et, la); - et->et_min_period = (0x00000002LLU << 32) / et->et_frequency; - et->et_max_period = (0xfffffffeLLU << 32) / et->et_frequency; } if (period != 0) { - if (la->la_timer_mode == LAT_MODE_UNDEF) - lapic_timer_set_divisor(lapic_timer_divisor); - la->la_timer_mode = LAT_MODE_PERIODIC; + lapic_change_mode(et, la, LAT_MODE_PERIODIC); la->la_timer_period = ((uint32_t)et->et_frequency * period) >> 32; lapic_timer_periodic(la); } else if (lapic_timer_tsc_deadline) { - la->la_timer_mode = LAT_MODE_DEADLINE; + lapic_change_mode(et, la, LAT_MODE_DEADLINE); la->la_timer_period = (et->et_frequency * first) >> 32; lapic_timer_deadline(la); } else { - if (la->la_timer_mode == LAT_MODE_UNDEF) - lapic_timer_set_divisor(lapic_timer_divisor); - la->la_timer_mode = LAT_MODE_ONESHOT; + lapic_change_mode(et, la, LAT_MODE_ONESHOT); la->la_timer_period = ((uint32_t)et->et_frequency * first) >> 32; lapic_timer_oneshot(la);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20160415125341.GJ2422>