/proc/net/tcp6 inconsistent line length

6 messages, 4 authors, 2012-01-17 · open the first message on its own page

/proc/net/tcp6 inconsistent line length

From: <hidden>
Date: 2012-01-17 13:29:12

My application relies heavily on the constant number of chars in a line of /proc/net/tcp* files

/proc/net/tcp does pad have such constancy
0: 000000:006F .......
1: 000000:DD36 .......
2: 000000:B23A .......
We know that 1 is exactly 150 chars after 0 and 2 is exactly 150 chars after 1 and so forth.

There is no such consistency with /proc/net/tcp6, i.e.

  sl  local_address                         remote_address                        st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
   0: 00000000000000000000000000000000:DD36 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000  1000        0 162811 1 ea464b00 300 0 0 2 -1
   1: 0000000000000000FFFF00000100007F:225B 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000  1000        0 109176 1 ea464000 300 0 0 2 -1
   2: 0000000000000000FFFF00007201A8C0:A4F4 0000000000000000FFFF000009A6D38C:0050 08 00000000:00000001 00:00000000 00000000  1000        0 3128779 1 c210f700 66 4 0 3 2
   3: 0000000000000000FFFF00007201A8C0:AD90 0000000000000000FFFF00001AC64F42:0050 08 00000000:00000001 00:00000000 00000000  1000        0 3128796 1 ea465600 4800 4 0 3 2
   4: 0000000000000000FFFF00007201A8C0:DD24 0000000000000000FFFF00002CD8D2CF:0050 01 00000000:00000000 00:00000000 00000000  1000        0 3128263 1 c210ec00 295 0 0 3 2
   5: 0000000000000000FFFF00007201A8C0:BBC6 0000000000000000FFFF000063E8B244:0050 01 00000000:00000000 00:00000000 00000000  1000        0 3128375 1 c210c580 4800 0 0 4 2

(word wrap need to turned off when viewing this to better understand my point.
Here the amount of chars fluctuate:
between 0 and 1 = 170 chars
between 1 and 2 = 170 chars
between 2 and 3 = 169 chars
between 3 and 4 = 171 chars
between 4 and 5 = 170 chars

Is it possible to implement a constant amount of chars in one line just like in /proc/net/tcp.
This is very helpful for parsing when you extract i.e. the source port, then seek 150 chars and extract the next line's source port and so on.

My application parses /proc/net/tcp6 at least 4 times per second, so the overhead of figuring out the length of each line and subtracting the offset is quite expensive.

P.S. Please CC me when replying to this thread

RE: /proc/net/tcp6 inconsistent line length

From: David Laight <hidden>
Date: 2012-01-17 13:33:05

 
My application parses /proc/net/tcp6 at least 4 times per 
second, so the overhead of figuring out the length of each 
line and subtracting the offset is quite expensive.
I'd be surprised if you can detect the cost of calling
strchr(buf, '\n') on each line at the frequency.

It is probably far less than the other processing you
do on the line.

	David

Re: /proc/net/tcp6 inconsistent line length

From: <hidden>
Date: 2012-01-17 14:14:38

On Tue, 17 Jan 2012 13:33:01 -0000
"David Laight" [off-list ref] wrote:
 
quoted
My application parses /proc/net/tcp6 at least 4 times per 
second, so the overhead of figuring out the length of each 
line and subtracting the offset is quite expensive.
I'd be surprised if you can detect the cost of calling
strchr(buf, '\n') on each line at the frequency.

It is probably far less than the other processing you
do on the line.

	David
Thank you, David. I first fread() the whole file to membuf and then process it thusly trying to find a line that matches my source port (porthex) :

while(1){
    memcpy(buffer,&tcp6_membuf[184+170*i],4);
    if ( !memcmp ( porthex, buffer, 4 ) ){ //match!
        goto endloop;
    }
     i++;
     continue;

N.B. 184 is the offset of source port on line 2 from the beginning of file (line 1 is used for column headings)

my /proc/net/tcp6 file contains 300 - 500 lines and I parse it at least from 4 to 10 times per sec. So the maximum is 5000 iterations per sec. It would be very costly CPU wise to do strchr(buf, '\n')
 
I'm not skillful enough to understand the code in kernel sources.
My concern boils down to this:

Was /proc/net/tcp* meant to have an equal length of each line?
If yes, then I discovered a bug.
If no, then would it be possible to patch the kernel to enable an equal length on each line? 

Re: /proc/net/tcp6 inconsistent line length

From: David Miller <davem@davemloft.net>
Date: 2012-01-17 14:29:22

From: <redacted>
Date: Tue, 17 Jan 2012 15:29:19 +0000
My application relies heavily on the constant number of chars in a line of /proc/net/tcp* files
Too bad, parse the fields properly.

Re: /proc/net/tcp6 inconsistent line length

From: Eric Dumazet <hidden>
Date: 2012-01-17 15:13:21

Le mardi 17 janvier 2012 à 16:14 +0000, abirvalg@lavabit.com a écrit :
Thank you, David. I first fread() the whole file to membuf and then process it thusly trying to find a line that matches my source port (porthex) :

while(1){
    memcpy(buffer,&tcp6_membuf[184+170*i],4);
    if ( !memcmp ( porthex, buffer, 4 ) ){ //match!
        goto endloop;
    }
     i++;
     continue;

Wow... no comment on this code.
N.B. 184 is the offset of source port on line 2 from the beginning of file (line 1 is used for column headings)

my /proc/net/tcp6 file contains 300 - 500 lines and I parse it at least from 4 to 10 times per sec. So the maximum is 5000 iterations per sec. It would be very costly CPU wise to do strchr(buf, '\n')
 
I'm not skillful enough to understand the code in kernel sources.
My concern boils down to this:

Was /proc/net/tcp* meant to have an equal length of each line?
If yes, then I discovered a bug.
If no, then would it be possible to patch the kernel to enable an equal length on each line? 
netlink can give you the needed information much faster.

Take a look at what is done by :

"ss -emoi src :22"
State      Recv-Q Send-Q                   Local Address:Port
Peer Address:Port 
ESTAB      0      0                       192.168.20.108:22
10.37.168.20:39444  timer:(keepalive,115min,0) ino:6852
sk:ffff88011ca81900
	 mem:(r0,w0,f8192,t0) ts sack cubic wscale:4,4 rto:208 rtt:8/11 ato:51
cwnd:10 ssthresh:24 send 14.5Mbps rcv_rtt:15 rcv_space:14480


sendmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000},
msg_iov(3)=[{"`\0\0\0\22\0\1\3@\342\1\0\0\0\0\0\2\0\0\17\0\0\0\0\0\0\0\0
\0\0\0\0"..., 76}, {"\24\0\1\0", 4}, {"\7\20\24\0\0\0\0\0\26\0\0\0\0\0\0
\0", 16}], msg_controllen=0, msg_flags=0}, 0) = 96
recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000},
msg_iov(1)=[{"\344\0\0\0\22\0\2\0@\342\1\0l\f\0\0\2\1\1\0\0\26\232\24
\300\250\24l320 "..., 8192}], msg_controllen=0, msg_flags=0}, 0) = 228




One sendmsg() for the request, one recvmsg() for the answer (with _all_
details included), even if your /proc/net/tcp*** has 1.000.000 lines.

Really say no to /proc files.

Re: /proc/net/tcp6 inconsistent line length

From: David Miller <davem@davemloft.net>
Date: 2012-01-17 15:15:22

From: Eric Dumazet <redacted>
Date: Tue, 17 Jan 2012 16:13:17 +0100
One sendmsg() for the request, one recvmsg() for the answer (with _all_
details included), even if your /proc/net/tcp*** has 1.000.000 lines.

Really say no to /proc files.
Indeed.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help