Skip to contentSkip to conversation

New tty flip interface doubt.

Q Sergei Organov 2 participants 6 messages Jun 21, 2006 – Jun 23, 2006 TTY layer and serial drivers

lore
Share & tools
lore
#0 lore raw

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.
#1 lore raw
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(), 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?

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

#2 lore raw
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(), 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?

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 ..
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.
#3 lore raw
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 ?

#4 lore raw
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.
#5 lore raw
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_buf
tty->free_buf

function pointer pair

Alan