Patch "tcp: seq_file: Avoid skipping sk during tcp_seek_last_pos" has been added to the 5.14-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    tcp: seq_file: Avoid skipping sk during tcp_seek_last_pos

to the 5.14-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     tcp-seq_file-avoid-skipping-sk-during-tcp_seek_last_.patch
and it can be found in the queue-5.14 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit a9995428bc92578595e694825d93ae02fa05fb68
Author: Martin KaFai Lau <kafai@xxxxxx>
Date:   Thu Jul 1 13:05:41 2021 -0700

    tcp: seq_file: Avoid skipping sk during tcp_seek_last_pos
    
    [ Upstream commit 525e2f9fd0229eb10cb460a9e6d978257f24804e ]
    
    st->bucket stores the current bucket number.
    st->offset stores the offset within this bucket that is the sk to be
    seq_show().  Thus, st->offset only makes sense within the same
    st->bucket.
    
    These two variables are an optimization for the common no-lseek case.
    When resuming the seq_file iteration (i.e. seq_start()),
    tcp_seek_last_pos() tries to continue from the st->offset
    at bucket st->bucket.
    
    However, it is possible that the bucket pointed by st->bucket
    has changed and st->offset may end up skipping the whole st->bucket
    without finding a sk.  In this case, tcp_seek_last_pos() currently
    continues to satisfy the offset condition in the next (and incorrect)
    bucket.  Instead, regardless of the offset value, the first sk of the
    next bucket should be returned.  Thus, "bucket == st->bucket" check is
    added to tcp_seek_last_pos().
    
    The chance of hitting this is small and the issue is a decade old,
    so targeting for the next tree.
    
    Fixes: a8b690f98baf ("tcp: Fix slowness in read /proc/net/tcp")
    Signed-off-by: Martin KaFai Lau <kafai@xxxxxx>
    Signed-off-by: Andrii Nakryiko <andrii@xxxxxxxxxx>
    Reviewed-by: Eric Dumazet <edumazet@xxxxxxxxxx>
    Acked-by: Kuniyuki Iwashima <kuniyu@xxxxxxxxxxxx>
    Acked-by: Yonghong Song <yhs@xxxxxx>
    Link: https://lore.kernel.org/bpf/20210701200541.1033917-1-kafai@xxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index a692626c19e4..db07c05736b2 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2451,6 +2451,7 @@ static void *tcp_get_idx(struct seq_file *seq, loff_t pos)
 static void *tcp_seek_last_pos(struct seq_file *seq)
 {
 	struct tcp_iter_state *st = seq->private;
+	int bucket = st->bucket;
 	int offset = st->offset;
 	int orig_num = st->num;
 	void *rc = NULL;
@@ -2461,7 +2462,7 @@ static void *tcp_seek_last_pos(struct seq_file *seq)
 			break;
 		st->state = TCP_SEQ_STATE_LISTENING;
 		rc = listening_get_next(seq, NULL);
-		while (offset-- && rc)
+		while (offset-- && rc && bucket == st->bucket)
 			rc = listening_get_next(seq, rc);
 		if (rc)
 			break;
@@ -2472,7 +2473,7 @@ static void *tcp_seek_last_pos(struct seq_file *seq)
 		if (st->bucket > tcp_hashinfo.ehash_mask)
 			break;
 		rc = established_get_first(seq);
-		while (offset-- && rc)
+		while (offset-- && rc && bucket == st->bucket)
 			rc = established_get_next(seq, rc);
 	}
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux