On Fri, 25 Mar 2016, Edward Tomasz [utf-8] Napiera?~Ba wrote:

On 0325T0809, Bruce Evans wrote:
On Thu, 24 Mar 2016, Edward Tomasz [utf-8] Napiera?~Ba wrote:

On 0324T1015, Warner Losh wrote:
On Thu, Mar 24, 2016 at 9:46 AM, Ian Lepore <i...@freebsd.org> wrote:

On Thu, 2016-03-24 at 16:01 +0100, Edward Tomasz Napiera??a wrote:
[...]
I've just noticed another curious thing, though: when you press
ScrLk,
the screen gets immediately refreshed; also, pressing arrows works
just
the way it should.  In other words, the refresh is broken except for
the ScrlLk mode, where it works as it should.

Since cngets() is used only by the mountroot prompt and the geli pw
entry, pausing/yielding within the input loop seems like a good idea.
 It would allow for things like plugging in a usb device and having it
actually appear without having to enter a '.' several times.

It would be nice if the pause were done with pause_sbt() and a shorter
timeout, maybe a millisecond or even 100uS.  Otherwise things like
pasting text at that prompt in a serial console is likely to drop
chars.

Serial consoles should work already due to their use of grab/ungrab, and
this use being easier to get right for serial consoles.

I still see problems with sio.  It doesn't use grab/ungrab yet, although
grab/ungrab were designed by me in ~1988 for my serial drivers older than
sio.

Note that cngetc() was broken by multiple console support in ~2000.
Before that, cngetc() waited with device interrupts disabled.  This
prevented the interrupt handler eating the interrupts.  Now it polls
and is still broken since its polling loop is not wrapped by
grab/ungrab.  cngets() was broken before multiple consoles, but was
fairly usable.  You just had to type reasonably slowly so that the
characters arrive in the low-level polling loop while device interrupts
are disabled.

Hmmm... speaking of the geli pw prompt... what's the locking situation
there?  Will there be any problems calling pause() from that context?

PVM isn't an ideal priority to wait at. PWAIT would be better. However,
if the only reason to call pause is run the scheduler after each character,
perhaps a better solution would be to call kern_yield() instead? We could
do that instead of cpu_waitspin() inside of cngetc, but that would break
the debugger's use of it....

Console drivers can't block or depend on timeouts.  Perhaps cngets() can,
because it is only called in simple contexts, but the simple contexts
make it especially easy for it to work using the same synchronous i/o that
is needed in more complicated contexts.

Note that this particular problem doesn't seem to be caused by the console
driver as such.  One of the things I've tried was to add a callout that
prints out something each second, and then enter an infinite loop.  The
assumption is, the loop in proc0 should get preempted by the callout.
For some reason this doesn't happen.

But it is a bug for (low level) console drivers to ever wait.  They should
assert that they don't.

I think we should first try to figure out why this doesn't work in the first
place.

Basically, even though the interrupts are running, scheduler seems to be ok,
and the thread that's calling this has a lower priority than the callouts
thread, it can't be preempted.  This doesn't seem to be caused by vt(4);
with syscons the callouts don't get called either (it just doesn't break
the echo in this case).  To demonstrate the problem you can add add
a callout that calls printf each second and then does an infinite loop.

cngets() is even correctly wrapped by cngrab()/cnungrab().  This is supposed
to put the console driver in a special synchronous mode for the duration of
the grabbing.  (Console drivers still need to be reentrant, so that they
can do i/o when the grabbed section is reentered for ddb or another
non-maskable trap.)  syscons and vt have similar too-simple grab handlers
which start with a screen switch in the !cold case.  This should refresh
the screen and/or switch it to special low-level console screen(s).

So basically, what you're suggesting is to make cngrab() set a flag that
switches vt, and its video drivers, into a mode that doesn't use any kind
of callouts, right?  That seems like a proper solution, but still doesn't
explain the root of the problem here.

Yes.  They already increment an xx_grabbed counter, but only use it to
do nothing for nested grabs.  (Doing nothing is too simple.)

Screen switching in ddb is noticeably more broken for vt than for syscons.
Indeed, it just doesn't work in vt (except for the initial switch to vty0).
This might be related.

Yeah; I remember some strange problems with keyboard state when
entering/leaving ddb.

Both syscons and vt hang fairly quickly in -current for the ddb command
's/p,1000'.  vt just hangs sooner.  I think I fixed this in an old version
of syscons, but I only tested the fix on systems with not as many CPUs as
the one that shows the most problems.  Printing after every instruction
in ddb is a good way to stress its i/o, except the i/o is very slow so it
takes too long to step through a few trillion instructions needed for a
good test.  A few trillion instructions might be enough to reach most
parts of the kernel.  The 'n' command is also good for stressing all paths,
but not so good for seeing the instruction that deadlocks, and the repeat
count doesn't work for it.

In -current with both syscons and vt, 's/p,1000' usually hangs on a
harmless-looking instruction nar the ithread loop.  But last time I
tried it hung on a known deadlock in scrn_update() (a lock cmpxchgl
for the bad locking there).  The trace showed interesting interleaving
of scrn_update() with handlevents(), presumably running on different
CPUs.  An old bug in single stepping in ddb is that it loses control on
every step.  SMP enlarges this bug.  The trace flag apparently got set
on different CPUs, though I thought I fixed that.  This shows that
every debugger entry that prints anything should print some pcpu info.

Bruce
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to