Re: [RFC PATCH 0/3] UART slave device bus

From: One Thousand Gnomes
Date: Mon Aug 22 2016 - 05:11:08 EST


> When and how fast is the work queue scheduled?
> And by which event?

That depends upon the platform and how busy the machine is. The dumb
uarts generally schedule it as soon as they've emptied the hardware. Some
controllers it may be done off a timer, others off DMA completion events

> > The workqueue involves the receive handler.
>
> This should be faster than if a driver directly processes incoming bytes?

It is in cases like n_tty yes and more importantly the serial port can
take another interrupt while the workqueue is running, so you won't drop
bytes if you have flow control.

> Or you have to assemble chunks into a frame, i.e. copy data around.

You have to do a pass over the data anyway to remove any quoting in the
framing for things like SLIP and PPP.

> Both seems a waste of scarce cpu cycles in high-speed situations to me.

The only case that I am aware of where there is a clear inefficiency is
where the hardware is handling characters in big chunks with good
buffering (eg DMA) and we are driving a protocol like PPP which simply
wants to do one pass over the data and stuff it into the network stack.

That one would be nice to fix with the port->rx suggestion I made.

> Which might become the pitfall of the design because as I have described it is an
> essential part of processing UART based protocols. You seem to focus on efficiently
> buffering only but not about efficiently processing the queued data.

There's a good reason for that - latency and throughput are not the same
thing. We need good latency on the buffering but good throughput on the
processing. Also if we fail to queue all the data reliably it doesn't
matter how efficient the processing side is.

> > We do, today for bluetooth and other protocols just fine
> I think it works (even with user-space HCI daemon) because bluetooth HCI is slow (<300kByte/s).

We do it for PPP over 3G modem as well. Modern 3G modems pretend to be
network devices, older ones didn't - and you are correct that in that
scenario we struggled (it's a lot better since Peter sorted the locking
out to be efficient).

> Yes, but you should also take framing into account for a solution that helps to implement
> UART slave devices. That is my concern.

I understand that I think anyway - you want to know the protocol state in
order to do optimal power management. Use a GPIO edge and assume it's a
'$', pick up via UART from the next byte, power the UART off the moment
you see \n. Leave the power on if you seem to be out of sync so you can
find a '$' and resync.

If you have driver specific code for this your driver gets told when the
line discipline changes so you can actually bury such logic in your low
level driver and even hide what is going on from above.

I've never had a problemw with what you are doing - just that it needs to
b generic to be upstream, otherwise every serial driver would immediately
develop thousands of lines of code for fifty differently wired and
working phone and IoT devices.

If the tty being open and normal tty operations are acceptable for the
write/configuration side then the point I've been trying to make is you
can't generically handle this at the uart layer.


At the ldisc layer it would have a slightly higher latency but look
something like (in an NMEA ldisc)


/* We got newline, tell the port to go into low power mode
directly or via whatever helpers it uses and to send us a '$'
when it wakes back up if it can't send us the true char */
if (port->slave) {
if (ch == '\n')
port->slave->ops.lowpower(port, '$');
/* If we get a $ then wakey wakey */
if (ch == '$')
port->slave->ops.lowpower(port, 0);
}
/* And if ops.lowpower is a no-op it all still works */

That also means that the port->slave-> method would be called in a
workqueue so can do sensible stuff even on things like USB


And the driver would presumably do something like

name = find_slave_name(blah); /* From DeviceTree etc */
if (name)
port->slave = request_tty_slave(name);

(if you for some reason needed different behaviour knowledge at the slave
level a tty ldisc change does notify the tty_port so we can do that too)


Alan