New tty flip interface doubt.
Alan,
Could you please slightly clarify the intent and suggest the right way to use the new interface routine tty_buffer_request_room() along with tty_insert_flip_string() (see below)?
I'm looking into some drivers that use it and into your initial description of the changes to the tty flip buffers, and I have a doubt. Consider the code:
tty_buffer_request_room(tty, urb->actual_length); tty_insert_flip_string(tty, data, urb->actual_length); tty_flip_buffer_push(tty);
For me it seems that in this case the call to tty_buffer_request_room() is useless as the first thing tty_insert_flip_string() does is to call tty_buffer_request_room() with exactly the same parameters anyway.
On the other hand, your explanations of the new interfaces talk about tty_buffer_request_room() as something that lets kernel handle memory better. I'm not sure I understand what it means in practice.
On yet another hand (or foot, should one has only two hands), some drivers do call tty_buffer_request_room(), and others don't.
Yet another way of doing things I see in the kernel code is:
int count = tty_buffer_request_room(tty, length); tty_insert_flip_string(tty, data, count);
this one is also doubtful as just calling
tty_insert_flip_string(tty, data, length);
instead has slightly more chances to transfer 'length' chars as tty_insert_flip_string(), unlike tty_buffer_request_room(), loops to find the memory.
Overall, what's the canonical way to transfer 'length' chars from a buffer 'buf' to the tty layer?
Signature · 1 line
Sergei.
Quoted 8 lines · Sergei Organov
tty_insert_flip_string(tty, data, length);instead has slightly more chances to transfer 'length' chars as
tty_insert_flip_string(), unliketty_buffer_request_room(), loops to find the memory.Overall, what's the canonical way to transfer 'length' chars from a buffer 'buf' to the tty layer?
tty_insert_flip_string called by itself will try to do the right thing. The tty_insert_flip_char interface can benefit a lot from you knowing the ideal buffer size to use so its very useful in the case of
int bytes = inw(port->fifo);
int count = tty_buffer_request_room(tty, bytes);
while(...) {
tty_insert_flip_char ..It is also useful if you want a linear buffer for ease of copying.
In the USB case it may be helpful as it will try and allocate blocks of memory reflecting the size of the blocks to be pushed to the user rather than guessing. As you suggest for most cases it probably makes no real difference
Quoted 20 lines · Alan Cox
Quoted 8 lines · Sergei Organov
tty_insert_flip_string(tty, data, length);instead has slightly more chances to transfer 'length' chars as
tty_insert_flip_string(), unliketty_buffer_request_room(), loops to find the memory.Overall, what's the canonical way to transfer 'length' chars from a buffer 'buf' to the tty layer?
tty_insert_flip_stringcalled by itself will try to do the right thing. Thetty_insert_flip_charinterface can benefit a lot from you knowing the ideal buffer size to use so its very useful in the case ofint bytes = inw(port->fifo); int count = tty_buffer_request_room(tty, bytes); while(...) { tty_insert_flip_char ..
Quoted 6 lines
It is also useful if you want a linear buffer for ease of copying.
In the USB case it may be helpful as it will try and allocate blocks of memory reflecting the size of the blocks to be pushed to the user rather than guessing. As you suggest for most cases it probably makes no real difference
Thanks, -- that's the answer I've more or less expected.
One more question, if I get memory for N bytes with tty_prepare_flip_string() then store M (M <= N) bytes into the buffer, how do I tell tty layer that only M bytes are in fact stored?
[I'm thinking about eliminating buffers allocation for urbs as well as data copy when transferring data from USB subsystem to flip buffers of the tty subsystem. Currently the flow is:
- allocate data buffer for urb.
- submit the urb to USB subsystem.
- copy received data from the buffer to tty (possibly allocating more buffers in tty)
- deallocate the data buffer
- flip (possibly deallocating some buffers in tty)
and it seems that using tty buffers directly is a better idea:
- allocate N-bytes data buffer from tty and use it for urb
- submit the urb to USB subsystem
- flip M-bytes of data (M <= N) in USB receive callback. ]
Signature · 1 line
Sergei.
Quoted 3 lines · Sergei Organov
One more question, if I get memory for N bytes with
tty_prepare_flip_string()then store M (M <= N) bytes into the buffer, how do I tell tty layer that only M bytes are in fact stored?
You don't.
Quoted 3 lines
[I'm thinking about eliminating buffers allocation for urbs as well as data copy when transferring data from USB subsystem to flip buffers of the tty subsystem. Currently the flow is:
The tty buffers may not be DMAable
Quoted 5 lines
and it seems that using tty buffers directly is a better idea:
- allocate N-bytes data buffer from tty and use it for urb
- submit the urb to USB subsystem
- flip M-bytes of data (M <= N) in USB receive callback.
Its doable in theory but is it worth it ?
Quoted 5 lines · Alan Cox
Quoted 3 lines · Sergei Organov
One more question, if I get memory for N bytes with
tty_prepare_flip_string()then store M (M <= N) bytes into the buffer, how do I tell tty layer that only M bytes are in fact stored?
Quoted 7 lines
You don't.
Quoted 3 lines
[I'm thinking about eliminating buffers allocation for urbs as well as data copy when transferring data from USB subsystem to flip buffers of the tty subsystem. Currently the flow is:
The tty buffers may not be DMAable
I saw this warning, but didn't think that USB urbs must be given DMAable memory. Does "transfer_buffer: This buffer has to be allocated as a non-pageable contiguous physical memory block" imply the memory must be DMAable? If it doesn't, then do tty buffers meet the above cited requirement?
Quoted 8 lines
Quoted 6 lines
and it seems that using tty buffers directly is a better idea:
- allocate N-bytes data buffer from tty and use it for urb
- submit the urb to USB subsystem
- flip M-bytes of data (M <= N) in USB receive callback.Its doable in theory but is it worth it ?
Well, I don't actually know, -- does your experience suggest it is not?
I thought that saving roughly 30% memory (ttys require x2 memory due to flags, right?) plus eliminating memcpy(), could be a valuable improvement, especially for embedded/low end systems and/or USB2 speeds.
If you don't see some hard to avoid obstacles making it difficult to implement, I'll probably try to modify tty layer to be able to support such a feature to see what it gives.
[My daily job is programming real-time applications for embedded systems, and time to time I do consider Linux a platform for our future embedded development. Recent progress of the kernel towards preemptibility and real-time performance is very promising, so I'm somewhat interested party indeed.]
Signature · 1 line
Sergei.
Quoted 5 lines · Sergei Organov
I saw this warning, but didn't think that USB urbs must be given DMAable memory. Does "
transfer_buffer: This buffer has to be allocated as a non-pageable contiguous physical memory block" imply the memory must be DMAable? If it doesn't, then do tty buffers meet the above cited requirement?
At the moment the tty buffers are a chain of buffers meeting that requirement.
Quoted 7 lines
Quoted 5 lines
Quoted 3 lines
- allocate N-bytes data buffer from tty and use it for urb
- submit the urb to USB subsystem
- flip M-bytes of data (M <= N) in USB receive callback.Its doable in theory but is it worth it ?
Well, I don't actually know, -- does your experience suggest it is not?
On a PC almost certainly not because the cost of the accesses is almost nil with the cache sizes on the CPU die and the performance of the CPU. Embedded I don't know , you tell me 8)
Quoted 3 lines
If you don't see some hard to avoid obstacles making it difficult to implement, I'll probably try to modify tty layer to be able to support such a feature to see what it gives.
I've no problem with that. At the moment the allocations all use kmalloc which should be fine for remapping. At worst you could add an optional
tty->alloc_buftty->free_buf
function pointer pair
Alan