Re: Serial driver hangs

From: Paul Fulghum
Date: Thu Sep 30 2004 - 19:52:26 EST


On Thu, 2004-09-30 at 16:25, Paul Fulghum wrote:
> > flush_to_ldisc was ok, then someone added the low latency
> > flag. In the current 2.6.9rc3 patch flush_to_ldisc honours
> > TTY_DONT_FLIP also
>
> In the cases I described the low latency flag
> does not come into play because flush_to_ldisc()
> is called directly instead of
> through tty_flip_buffer_push().
>
> TTY_DONT_FLIP is only set in read_chan().
> If read_chan() is not running, TTY_DONT_FLIP is not
> set and does not prevent buffers from flipping
> if the ISR calls flush_to_ldisc() directly
> while ldisc->receive_buf() is running.
>
> The answer seems to be: don't call
> flush_to_ldisc directly like the current
> serial driver does.

I've looked at this more on 2.6

If a driver only calls tty_flip_buffer_push(),
with low_latency cleared, it is still possible for
flush_to_ldisc() to run concurrently on SMP machines.

* IRQ on proc 0, flush_to_ldisc work queued for events/0
* events/0 processes work item:
1) work->pending cleared (work can now be queued again)
2) work function runs on proc 0

While work function is running on proc 0:

* IRQ on proc 1, flush_to_ldisc work queued for events/1
* events/1 processes work item:
1) work->pending cleared (work can now be queued again)
2) work function runs on proc 1

flush_to_ldisc/ldisc->receive_buf do not set TTY_DONT_FLIP
and I see no other mechanism to serialize flush_to_ldisc

That means the buffers can flip while running in
ldisc->receive_buf() which reads from the buffers.

This is contrived, and timing may prevent
this from actually occurring in practice, but it
seems to indicate a hole that needs to be plugged.

I wrong in my reading of the code?

--
Paul Fulghum
paulkf@xxxxxxxxxxxxx


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/