Skip to contentSkip to conversation

include listenq max backlog in /proc/net/tcp and include in tcp_info

PATCH In review Rick Jones 3 participants 9 messages Sep 10, 2007 – Sep 11, 2007

Subsystems (4)
lore
Share & tools
lore

Rick Jones

author
#0 lore raw

PATCH 1/1 include listenq max backlog in /proc/net/tcp and include in tcp_info

Return some useful information such as the maximum listen backlog and the current listen backlog in the tcp_info structure and have that match what one can see in /proc/net/tcp and /proc/net/tcp6.

---

Documentation/networking/proc_net_tcp.txt +2 -2
diff -r bdcdd0e1ee9d Documentation/networking/proc_net_tcp.txt
@@ -20,8 +20,8 @@ up into 3 parts because of the length of
       |        |     |     |       |--> number of unrecovered RTO timeouts
       |        |     |     |----------> number of jiffies until timer expires
       |        |     |----------------> timer_active (see below)
-      |        |----------------------> receive-queue
-      |-------------------------------> transmit-queue
+      |        |----------------------> receive-queue or connection backlog
+      |-------------------------------> transmit-queue or connection limit
 
    1000        0 54165785 4 cd1e6040 25 4 27 3 -1
     |          |    |     |    |     |  | |  | |--> slow start size threshold, 
net/ipv4/tcp.c +8 -2
diff -r bdcdd0e1ee9d net/ipv4/tcp.c
@@ -2030,8 +2030,14 @@ void tcp_get_info(struct sock *sk, struc
 	info->tcpi_snd_mss = tp->mss_cache;
 	info->tcpi_rcv_mss = icsk->icsk_ack.rcv_mss;
 
-	info->tcpi_unacked = tp->packets_out;
-	info->tcpi_sacked = tp->sacked_out;
+	if (sk->sk_state == TCP_LISTEN) {
+		info->tcpi_unacked = sk->sk_ack_backlog;
+		info->tcpi_sacked = sk->sk_max_ack_backlog;
+	}
+	else {
+		info->tcpi_unacked = tp->packets_out;
+		info->tcpi_sacked = tp->sacked_out;
+	}
 	info->tcpi_lost = tp->lost_out;
 	info->tcpi_retrans = tp->retrans_out;
 	info->tcpi_fackets = tp->fackets_out;
net/ipv4/tcp_ipv4.c +2 -1
diff -r bdcdd0e1ee9d net/ipv4/tcp_ipv4.c
@@ -2320,7 +2320,8 @@ static void get_tcp4_sock(struct sock *s
 	sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX "
 			"%08X %5d %8d %lu %d %p %u %u %u %u %d",
 		i, src, srcp, dest, destp, sk->sk_state,
-		tp->write_seq - tp->snd_una,
+		sk->sk_state == TCP_LISTEN ? sk->sk_max_ack_backlog :
+					     (tp->write_seq - tp->snd_una),
 		sk->sk_state == TCP_LISTEN ? sk->sk_ack_backlog :
 					     (tp->rcv_nxt - tp->copied_seq),
 		timer_active,
net/ipv6/tcp_ipv6.c +4 -2
diff -r bdcdd0e1ee9d net/ipv6/tcp_ipv6.c
@@ -2005,8 +2005,10 @@ static void get_tcp6_sock(struct seq_fil
 		   dest->s6_addr32[0], dest->s6_addr32[1],
 		   dest->s6_addr32[2], dest->s6_addr32[3], destp,
 		   sp->sk_state,
-		   tp->write_seq-tp->snd_una,
-		   (sp->sk_state == TCP_LISTEN) ? sp->sk_ack_backlog : (tp->rcv_nxt - tp->copied_seq),
+		   (sp->sk_state == TCP_LISTEN) ? sp->sk_max_ack_backlog:
+						  tp->write_seq-tp->snd_una,
+		   (sp->sk_state == TCP_LISTEN) ? sp->sk_ack_backlog : 
+					(tp->rcv_nxt - tp->copied_seq),
 		   timer_active,
 		   jiffies_to_clock_t(timer_expires - jiffies),
 		   icsk->icsk_retransmits,
#1 lore raw
Quoted 3 lines · Rick Jones

Return some useful information such as the maximum listen backlog and the current listen backlog in the tcp_info structure and have that match what one can see in /proc/net/tcp and /proc/net/tcp6.

If we are also exporting max listen backlog, another place to consider adding this is to tcp_diag_get_info() called via INET_DIAG_INFO. Current listen backlog is returned in inet_diag_msg->idiag_rqueue. max listen backlog can be returned in inet_diag_msg->idiag_wqueue.

Thanks
Sridhar

Quoted 71 lines

---

diff -r bdcdd0e1ee9d Documentation/networking/proc_net_tcp.txt

Documentation/networking/proc_net_tcp.txt +2 -2
@@ -20,8 +20,8 @@ up into 3 parts because of the length of
       |        |     |     |       |--> number of unrecovered RTO timeouts
       |        |     |     |----------> number of jiffies until timer expires
       |        |     |----------------> timer_active (see below)
-      |        |----------------------> receive-queue
-      |-------------------------------> transmit-queue
+      |        |----------------------> receive-queue or connection backlog
+      |-------------------------------> transmit-queue or connection limit
 
    1000        0 54165785 4 cd1e6040 25 4 27 3 -1
     |          |    |     |    |     |  | |  | |--> slow start size threshold, 

diff -r bdcdd0e1ee9d net/ipv4/tcp.c

net/ipv4/tcp.c +8 -2
@@ -2030,8 +2030,14 @@ void tcp_get_info(struct sock *sk, struc
 	info->tcpi_snd_mss = tp->mss_cache;
 	info->tcpi_rcv_mss = icsk->icsk_ack.rcv_mss;
 
-	info->tcpi_unacked = tp->packets_out;
-	info->tcpi_sacked = tp->sacked_out;
+	if (sk->sk_state == TCP_LISTEN) {
+		info->tcpi_unacked = sk->sk_ack_backlog;
+		info->tcpi_sacked = sk->sk_max_ack_backlog;
+	}
+	else {
+		info->tcpi_unacked = tp->packets_out;
+		info->tcpi_sacked = tp->sacked_out;
+	}
 	info->tcpi_lost = tp->lost_out;
 	info->tcpi_retrans = tp->retrans_out;
 	info->tcpi_fackets = tp->fackets_out;

diff -r bdcdd0e1ee9d net/ipv4/tcp_ipv4.c

net/ipv4/tcp_ipv4.c +2 -1
@@ -2320,7 +2320,8 @@ static void get_tcp4_sock(struct sock *s
 	sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX "
 			"%08X %5d %8d %lu %d %p %u %u %u %u %d",
 		i, src, srcp, dest, destp, sk->sk_state,
-		tp->write_seq - tp->snd_una,
+		sk->sk_state == TCP_LISTEN ? sk->sk_max_ack_backlog :
+					     (tp->write_seq - tp->snd_una),
 		sk->sk_state == TCP_LISTEN ? sk->sk_ack_backlog :
 					     (tp->rcv_nxt - tp->copied_seq),
 		timer_active,

diff -r bdcdd0e1ee9d net/ipv6/tcp_ipv6.c

net/ipv6/tcp_ipv6.c +4 -3
@@ -2005,8 +2005,10 @@ static void get_tcp6_sock(struct seq_fil
 		   dest->s6_addr32[0], dest->s6_addr32[1],
 		   dest->s6_addr32[2], dest->s6_addr32[3], destp,
 		   sp->sk_state,
-		   tp->write_seq-tp->snd_una,
-		   (sp->sk_state == TCP_LISTEN) ? sp->sk_ack_backlog : (tp->rcv_nxt - tp->copied_seq),
+		   (sp->sk_state == TCP_LISTEN) ? sp->sk_max_ack_backlog:
+						  tp->write_seq-tp->snd_una,
+		   (sp->sk_state == TCP_LISTEN) ? sp->sk_ack_backlog : 
+					(tp->rcv_nxt - tp->copied_seq),
 		   timer_active,
 		   jiffies_to_clock_t(timer_expires - jiffies),
 		   icsk->icsk_retransmits,
-

To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#2 lore raw
Quoted 9 lines · Sridhar Samudrala
Quoted 2 lines · Rick Jones

Return some useful information such as the maximum listen backlog and
the current listen backlog in the tcp_info structure and have that match what one can see in /proc/net/tcp and /proc/net/tcp6.

If we are also exporting max listen backlog, another place to consider adding this is to tcp_diag_get_info() called via INET_DIAG_INFO. Current listen backlog is returned in inet_diag_msg->idiag_rqueue. max listen backlog can be returned in inet_diag_msg->idiag_wqueue.

I agree, /proc/net/tcp is deprecated nowadays...

Rick, could you add this part in your patch, and add my Sign-off-by ?

Thank you
Eric

net/ipv4/tcp_diag.c +5 -3
index 57c5f0b..f5b6275 100644
@@ -25,11 +25,13 @@ static void tcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
 	const struct tcp_sock *tp = tcp_sk(sk);
 	struct tcp_info *info = _info;
 
-	if (sk->sk_state == TCP_LISTEN)
+	if (sk->sk_state == TCP_LISTEN) {
 		r->idiag_rqueue = sk->sk_ack_backlog;
-	else
+		r->idiag_wqueue = sk->sk_max_ack_backlog;
+	else {
 		r->idiag_rqueue = tp->rcv_nxt - tp->copied_seq;
-	r->idiag_wqueue = tp->write_seq - tp->snd_una;
+		r->idiag_wqueue = tp->write_seq - tp->snd_una;
+	}
 	if (info != NULL)
 		tcp_get_info(sk, info);
 }
#3 lore raw
Quoted 11 lines · Eric Dumazet
Quoted 9 lines · Sridhar Samudrala
Quoted 2 lines · Rick Jones

Return some useful information such as the maximum listen backlog and
the current listen backlog in the tcp_info structure and have that match what one can see in /proc/net/tcp and /proc/net/tcp6.

If we are also exporting max listen backlog, another place to consider adding this is to tcp_diag_get_info() called via INET_DIAG_INFO. Current listen backlog is returned in inet_diag_msg->idiag_rqueue. max listen backlog can be returned in inet_diag_msg->idiag_wqueue.

Quoted 6 lines

I agree, /proc/net/tcp is deprecated nowadays...

Rick, could you add this part in your patch, and add my Sign-off-by ?

Thank you
Eric

One } was missing, sorry

net/ipv4/tcp_diag.c +5 -3
index 57c5f0b..f5b6275 100644
@@ -25,11 +25,13 @@ static void tcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
 	const struct tcp_sock *tp = tcp_sk(sk);
 	struct tcp_info *info = _info;
 
-	if (sk->sk_state == TCP_LISTEN)
+	if (sk->sk_state == TCP_LISTEN) {
 		r->idiag_rqueue = sk->sk_ack_backlog;
-	else
+		r->idiag_wqueue = sk->sk_max_ack_backlog;
+	} else {
 		r->idiag_rqueue = tp->rcv_nxt - tp->copied_seq;
-	r->idiag_wqueue = tp->write_seq - tp->snd_una;
+		r->idiag_wqueue = tp->write_seq - tp->snd_una;
+	}
 	if (info != NULL)
 		tcp_get_info(sk, info);
 }
author
#4 lore raw
In reply to Eric Dumazet
Quoted 8 lines · Eric Dumazet
Quoted 6 lines · Sridhar Samudrala
Quoted 2 lines · Rick Jones

Return some useful information such as the maximum listen backlog and
the current listen backlog in the tcp_info structure and have that match what one can see in /proc/net/tcp and /proc/net/tcp6.

Quoted 7 lines
Quoted 5 lines

If we are also exporting max listen backlog, another place to consider adding this is to tcp_diag_get_info() called via INET_DIAG_INFO. Current listen backlog is returned in inet_diag_msg->idiag_rqueue. max listen backlog can be returned in inet_diag_msg->idiag_wqueue.

I agree, /proc/net/tcp is deprecated nowadays...

What takes its place?

Quoted 1 line

Rick, could you add this part in your patch, and add my Sign-off-by ?

My pleasure.

I have a small test program for the tcp_info bit - where do I go to find how the inet diag stuff works?

BTW, what do people think about doing the same thing with the rxqueue and txqueue's of netstat output?

rick jones

Quoted 30 lines

Thank you
Eric

------------------------------------------------------------------------

net/ipv4/tcp_diag.c +5 -3
index 57c5f0b..f5b6275 100644
@@ -25,11 +25,13 @@ static void tcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
 	const struct tcp_sock *tp = tcp_sk(sk);
 	struct tcp_info *info = _info;
 
-	if (sk->sk_state == TCP_LISTEN)
+	if (sk->sk_state == TCP_LISTEN) {
 		r->idiag_rqueue = sk->sk_ack_backlog;
-	else
+		r->idiag_wqueue = sk->sk_max_ack_backlog;
+	else {
 		r->idiag_rqueue = tp->rcv_nxt - tp->copied_seq;
-	r->idiag_wqueue = tp->write_seq - tp->snd_una;
+		r->idiag_wqueue = tp->write_seq - tp->snd_una;
+	}
 	if (info != NULL)
 		tcp_get_info(sk, info);
 }
#5 lore raw
Quoted 16 lines · On Tue, 11 Sep 2007 10:00:21 -0700 Rick Jones <[email protected]> wrote:
Quoted 15 lines · Eric Dumazet
Quoted 12 lines · Sridhar Samudrala
Quoted 3 lines · Rick Jones

Return some useful information such as the maximum listen backlog and the current listen backlog in the tcp_info structure and have that match what one can see in /proc/net/tcp and /proc/net/tcp6.

If we are also exporting max listen backlog, another place to consider adding this is to tcp_diag_get_info() called via INET_DIAG_INFO. Current listen backlog is returned in inet_diag_msg->idiag_rqueue. max listen backlog can be returned in inet_diag_msg->idiag_wqueue.

Quoted 3 lines
Quoted 1 line

I agree, /proc/net/tcp is deprecated nowadays...

What takes its place?

ss command from iproute2 package ( http://linux-net.osdl.org/index.php/Iproute2 )

Problem with /proc/net/tcp is its quadratic time O(N^2) to output N lines...

On a loaded server :

# time ss|wc -l
 145695
real    0m9.383s
user    0m4.656s
sys     0m0.632s
# time netstat -an|wc -l
^C after some minutes .... no way...
real    3m23.825s
user    0m0.744s
sys     3m18.721s
Quoted 7 lines
Quoted 2 lines

Rick, could you add this part in your patch, and add my Sign-off-by ?

My pleasure.

I have a small test program for the tcp_info bit - where do I go to find how the inet diag stuff works?

ss state listen

Quoted 4 lines

BTW, what do people think about doing the same thing with the rxqueue and txqueue's of netstat output?

I dont understand this question, I thought your patch already handled this (for the txqueue, since rxqueue is already there), as netstat uses /proc/net/tcp (unfortunatly)

author
#6 lore raw
Quoted 3 lines

ss command from iproute2 package ( http://linux-net.osdl.org/index.php/Iproute2 )

Problem with /proc/net/tcp is its quadratic time O(N^2) to output N lines...

I could see where that might be a problem.

Quoted 8 lines
Quoted 5 lines
Quoted 1 line

Rick, could you add this part in your patch, and add my Sign-off-by ?

My pleasure.

I have a small test program for the tcp_info bit - where do I go to find how the inet diag stuff works?

ss state listen

hpcpc103:~# ss --version
ss utility, iproute2-ss070313
hpcpc103:~# ss state listen
ss: no socket states to show with such filter.
hpcpc103:~# ss --all
State      Recv-Q Send-Q      Local Address:Port          Peer Address:Port
LISTEN     0      128                     *:sunrpc                   *:* 

LISTEN 0 128 *:auth *:*

LISTEN 0 128 :::ssh :::*

LISTEN 0 20 127.0.0.1:smtp *:*

LISTEN 0 128 *:42137 *:*

Quoted 7 lines
Quoted 4 lines

BTW, what do people think about doing the same thing with the rxqueue and txqueue's of netstat output?

I dont understand this question, I thought your patch already handled this (for the txqueue, since rxqueue is already there), as netstat uses /proc/net/tcp (unfortunatly)

Well, it doesn't seem to be the case. This is from the same system as the ss output above:

hpcpc103:~# netstat -an | grep LISTEN
tcp        0      0 0.0.0.0:111          0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:113          0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:25         0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:42137        0.0.0.0:*               LISTEN
tcp6       0      0 :::22                :::*                    LISTEN
unix  2    [ ACC ]     STREAM   LISTENING   5666  /var/run/acpid.socket

I thought I saw some other code in there when I was stumbling around.

rick

#7 lore raw
Quoted 14 lines · Rick Jones
Quoted 3 lines

ss command from iproute2 package ( http://linux-net.osdl.org/index.php/Iproute2 )

Problem with /proc/net/tcp is its quadratic time O(N^2) to output N lines...

I could see where that might be a problem.

Quoted 8 lines
Quoted 6 lines
Quoted 1 line

Rick, could you add this part in your patch, and add my Sign-off-by ?

My pleasure.

I have a small test program for the tcp_info bit - where do I go to find how the inet diag stuff works?

Quoted 6 lines
Quoted 1 line

ss state listen

hpcpc103:~# ss --version
ss utility, iproute2-ss070313
hpcpc103:~# ss state listen
ss: no socket states to show with such filter.

looks like 'ss state listening' or 'ss -l' is the right syntax.

Quoted 36 lines
hpcpc103:~# ss --all
State      Recv-Q Send-Q      Local Address:Port          Peer 
Address:Port
LISTEN     0      128                     *:sunrpc                   *:* 

LISTEN 0 128 *:auth *:*

LISTEN 0 128 :::ssh :::*

LISTEN 0 20 127.0.0.1:smtp *:*

LISTEN 0 128 *:42137 *:*

Quoted 10 lines
Quoted 5 lines

BTW, what do people think about doing the same thing with the rxqueue and txqueue's of netstat output?

I dont understand this question, I thought your patch already handled this (for the txqueue, since rxqueue is already there), as netstat uses /proc/net/tcp (unfortunatly)

Well, it doesn't seem to be the case. This is from the same system as the ss output above:

hpcpc103:~# netstat -an | grep LISTEN
tcp        0      0 0.0.0.0:111          0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:113          0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:25         0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:42137        0.0.0.0:*               LISTEN
tcp6       0      0 :::22                :::*                    LISTEN
unix  2    [ ACC ]     STREAM   LISTENING   5666  /var/run/acpid.socket
Quoted 1 line

I thought I saw some other code in there when I was stumbling around.

Yes. netstat code seems to have a explicit check for TCP_LISTEN state and zeroing txq and rxq.

Quoted 1 line

From tcp_do_one() in netstat.c

    if (state == TCP_LISTEN) {
        time_len = 0;
        retr = 0L;
        rxq = 0L;
        txq = 0L;
    }

We should fix this. Also i think it is a good idea to update netstat to use INET_DIAG_INFO instead of /proc/net/tcp.

Thanks
Sridhar

author
#8 lore raw
Quoted 21 lines
Quoted 16 lines
Quoted 5 lines
Quoted 2 lines

BTW, what do people think about doing the same thing with the rxqueue and txqueue's of netstat output?

I dont understand this question, I thought your patch already handled this (for the txqueue, since rxqueue is already there), as netstat uses /proc/net/tcp (unfortunatly)

Well, it doesn't seem to be the case. This is from the same system as the ss output above:

hpcpc103:~# netstat -an | grep LISTEN
tcp        0      0 0.0.0.0:111          0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:113          0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:25         0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:42137        0.0.0.0:*               LISTEN
tcp6       0      0 :::22                :::*                    LISTEN
unix  2    [ ACC ]     STREAM   LISTENING   5666  /var/run/acpid.socket
Quoted 1 line

I thought I saw some other code in there when I was stumbling around.

Yes. netstat code seems to have a explicit check for TCP_LISTEN state and zeroing txq and rxq.

Quoted 7 lines
Quoted 1 line

From tcp_do_one() in netstat.c

    if (state == TCP_LISTEN) {
        time_len = 0;
        retr = 0L;
        rxq = 0L;
        txq = 0L;
    }

How terribly cheeky of them. I wonder why they were doing that?

Quoted 1 line

We should fix this. Also i think it is a good idea to update netstat to use INET_DIAG_INFO instead of /proc/net/tcp.

Since that is user space I went ahead and sent the updated kernel patch in a fresh thread.

rick