Project

General

Profile

Actions

Bug #4663

closed

osmo-e1d: SOCK_SEQPACKET and RAW timeslots

Added by laforge almost 4 years ago. Updated almost 4 years ago.

Status:
Resolved
Priority:
Normal
Assignee:
Category:
-
Target version:
-
Start date:
07/11/2020
Due date:
% Done:

100%

Spec Reference:

Description

I actually think that the current code cannot work correctly for RAW timeslots.

As we use SOCK_SEQPACKET for the socketpair irrespective of the timeslot mode, this means that every read() of a ts-fd inside osmo-e1d will want to read one "packet" of whatever size the client has written.

However, in osmo-e1d we read only as many bytes as we have frames to send. With the current USB code this is 4..12 bytes per read().

In my understanding of SOCK_SEQPACKET semantics, this means that the first 4..12 bytes are read and the remainder of the packet is discarded.

We should probably eithe
  • use SOCK_STREAM sockets for RAW and keep SEQPACKET only for HDLC
  • use larger read() sizes as we probably really don't want one syscall for every 4..12 bytes of every voice channel

I have other priorities right now, but I think it would be worthwhile to develop a test for this. With vpair this test could run without any hardware (vpair uses a nominal 10 frames-to-send granularity).

Actions #1

Updated by laforge almost 4 years ago

  • Status changed from New to In Progress
  • Assignee set to laforge
  • % Done changed from 0 to 20

I used MSG_TRUNC in https://gerrit.osmocom.org/c/osmo-e1d/+/19218 to detect such situations, and a small test program reproduces it as expected.

Actions #2

Updated by tnt almost 4 years ago

One issue with SOCK_STREAM and larger reads is the buffering done by the kernel.

Having the read happen "as late as possible" is basically what provides back-pressure to the sender to make sure we don't end up with tons of latency added.
(that's one of the reason that osmo-e1d only reads when data is needed by the usb thread and not as soon as data is available).

From what I remember from early testing, the kernel buffered a max number of bytes and also a max number of "packets" which ever was reached first.

Actions #3

Updated by laforge almost 4 years ago

  • % Done changed from 20 to 80

https://gerrit.osmocom.org/c/osmo-e1d/+/19220 moves RAW timeslots to SOCK_STREAM.

It still means we end up with ridiculously small individual read() system calls, but let's not conflate fixing the bug with optimization.

Actions #4

Updated by laforge almost 4 years ago

tnt wrote:

One issue with SOCK_STREAM and larger reads is the buffering done by the kernel.

Having the read happen "as late as possible" is basically what provides back-pressure to the sender to make sure we don't end up with tons of latency added.

sure. The way how we deal with this in libosmo-abis (with DAHDI) is to never mark the timeslot-fd as BSC_FD_WRITE, but always only send as many bytes as we have read. But still those reads/writes happen with 160 bytes per read/write in DAHDI. The trau frame is 40 bytes anyway, and 4 trau frames together form one 160 byte chunk.

So I am not saying applications should write all they can into the kernel buffer, by all means.

Actions #5

Updated by laforge almost 4 years ago

  • Status changed from In Progress to Resolved
  • % Done changed from 80 to 100

patches merged

Actions

Also available in: Atom PDF

Add picture from clipboard (Maximum size: 48.8 MB)