Re: Is this a bug in the current serial8250_rx_chars()?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>> If it's done properly (barrier between filling the flag buffer and
>> clearing the TTYB_NORMAL flag), then receive_buf can remain lockless.

> I'm not seeing how that can be done without adding a complementary write
> barrier between reading the commit index and reading the flags on the
> consumer side, which would unnecessarily impact pty performance.

Yes, the first rule of memory barriers is that they must *always*
be used in pairs.  However, the write barrier is on the consumer side
(where it is much cheaper than the allocation it's saving), and smp_rmb()
is on the consumer side.

smp_rmb() is quite cheap.  On x86, it's zero instructions and almost free.
(It inhibits some compiler optimizations.)

If efficiency is a concern, it would be possible to arrange the code
to use the same smp_rmb() that's already in flush_to_ldisc().  It would
just require a more complex interface with receive_buf.

(Since it's a static function with only one call site, it's already
inlined and argument passing is free; the only issue is code cleanliness.)

But personally, I would be surprised if it was even 0.01% (effectively
unmeasurable) and so code cleanliness should decide.

On 8250-style serial ports, UART register reads are already on the
order of a microsecond per byte and an smp_rmb() is in the noise.
Higher-speed users of the tty_buffer interface use larger buffers and
so amortize the cost over many more bytes.

> If this space optimization is desirable, I'd rather see a simple state
> machine on the producer-side only that limited buffer type hysteresis;
> eg., starting out with tty_bufhead being TTYB_NORMAL capable until the
> first type switch is required because input flag was parity/break/overrun,
> and then requiring some fixed # of buffers input before resetting it.

This is certainly possible, but seems unnecessarily complex.  Converting
in place when necessary achieves "perfect" space utilization with no
need for any additional state.

Maybe I'm overly attracted to my own clever idea, but it certainly
seems simple enough: if they bytes that would be needed for a flags buffer
are not already in use, reassign them.


My *complex*, not-sure-if-it's-worth-it idea is to make each tty_buffer
fully circular, so in the simple case only one is needed.

Basically, rather than writing until p->used reached p->size,
it would fill circularly until it reached p->read + p->size.

(There would need to be an smp_wmb() before the update to head->read
in receive_buf().)
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux