Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 1 Apr 2019 20:02:46 +1100 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Konstantin Belousov <kostikbel@gmail.com>
Cc:        Bruce Evans <brde@optusnet.com.au>, src-committers@freebsd.org,  svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   Re: svn commit: r345696 - head/lib/libvgl
Message-ID:  <20190401185606.Q2155@besplex.bde.org>
In-Reply-To: <20190331145122.GL1923@kib.kiev.ua>
References:  <201903291557.x2TFv9AW097226@repo.freebsd.org> <20190329182100.GZ1923@kib.kiev.ua> <20190330142319.I1011@besplex.bde.org> <20190330094558.GA1923@kib.kiev.ua> <20190331214235.K961@besplex.bde.org> <20190331121015.GK1923@kib.kiev.ua> <20190331231926.M1259@besplex.bde.org> <20190331145122.GL1923@kib.kiev.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 31 Mar 2019, Konstantin Belousov wrote:

> On Mon, Apr 01, 2019 at 12:04:45AM +1100, Bruce Evans wrote:
>> Serial consoles are not always available.
>>
>> Better debuggers switch the screen mode as necessary.
>>
>> I recently noticed another mode switching problem.  On i386, cycling
>> through about 50 modes to test them all takes a small fraction of a
>> second for each mode switch (done directly in syscons or by a vm86
>> BIOS call) even when the monitor takes too long to resync (the monitor
>> resyncs are coalesced, so 50 resyncs take about 5 seconds instead of
>> 250).  But on amd64, mode switches to VESA mode and back take about
>> 20 seconds.  They are not coalesced, and most of the system is stopped
>> waiting for them (at least remote network access is stopped).  amd64
>> can't use vm86, so it emulates BIOS calls.  Why does the emulation stop
>> the rest of the system and take so long?
>
> How many CPUs do you have ?

8 on the machine that shows the problem -- an underdesktop with Haswell
graphics.

A laptop with Sandybridge graphics only waits for 0.25 seconds (sys time)
I don't know if it stops the system for that long (it would be 2 blockages
for half that long).  The laptop's integrated screen also syncs instantly.
The undermydesktop has an LED screen connected by DVI-D.

> x86bios.c x86bios_call() does spinlock_enter() around emulator calls.
> This disables interrupts.
>
> If you have only one CPU, the consequences are obvious. If you have
> more than one, then perhaps next IPI targeted to this CPU blocks the
> originator, if IPI requires ack, which typically true for most common
> TLB shutdown IPIs. Then both this CPU and originator block any other CPU
> trying to send an IPI.

Serial console interrupts on another CPU work to enter ddb instantly and
show the emulator stopped.

Binding drivers to CPU unimproves scheduling in general, and here it might
result in iflib waiting for the CPU with interrupts disabled, but usually
the CPU with interrupts disabled is not the one(s) bound to by iflib, and
binding the graphics program to one not used by iflib doesn't help.

Removing the spinlock_enter/exit() using ddb makes no difference.

> For this reason I have to come through several hoops to not disable
> interrupts for duration of EFI runtime calls, otherwise spinlocks die
> due to 'spin lock held too long' on other CPUs.

I turn off the 'spin lock held too long' panics in my fixes for console
and message buffer i/o.  Printing "spin lock held too long\n" takes 120
seconds at 2 bps.  Draining 16K of buffered messages takes 81920 seconds
at 2 bps.  The main fix is to cancel the timeouts here while any console
driver is making progress (hopefully printing messages about the actual
error).  2 bps is too slow to be useful, but it gives a good stress test
and a check that the timeouts are scaled properly by the console speed.

Disabling interrupts might be FUD.  vm86 on i386 only uses critical_enter()
in addition to its sleep lock.  But this is bad for scheduling too.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20190401185606.Q2155>