[Devel] [PATCH RHEL7 COMMIT] rh/tcp: provide TCP_FRAG_IN_WRITE/RTX_QUEUE for tcp_fragment use
Konstantin Khorenko
khorenko at virtuozzo.com
Thu Aug 15 18:44:44 MSK 2019
The commit is pushed to "branch-rh7-3.10.0-957.27.2.vz7.107.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-957.27.2.vz7.107.3
------>
commit 94eaeef64746e759e6b0e291a3b14afdd3d240f5
Author: Florian Westphal <fwestpha at redhat.com>
Date: Tue Jul 2 12:14:27 2019 +0200
rh/tcp: provide TCP_FRAG_IN_WRITE/RTX_QUEUE for tcp_fragment use
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1723032
Upstream Status: RHEL-only/partial backport
This extracts minimal bits from commit
75c119afe14f74b4dd9 ("tcp: implement rb-tree based retransmit queue"),
namely the tcp_queue enum and passing it to tcp_fragment().
Its needed by next patch to tell if the caller is providing an skb
from write or retransmit queue.
Signed-off-by: Florian Westphal <fwestpha at redhat.com>
Signed-off-by: Jiri Benc <jbenc at redhat.com>
Signed-off-by: Denys Vlasenko <dvlasenk at redhat.com>
=================================
This patch is included into 3.10.0-957.27.4.el7 RHEL7.6 EUS kernel,
so apply them.
https://jira.sw.ru/browse/PSBM-95578
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
include/net/tcp.h | 8 +++++++-
net/ipv4/tcp_input.c | 4 ++--
net/ipv4/tcp_output.c | 15 ++++++++++-----
3 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/include/net/tcp.h b/include/net/tcp.h
index abc3adea73aa..6a4d5bc9382a 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -556,7 +556,13 @@ void tcp_retransmit_timer(struct sock *sk);
void tcp_xmit_retransmit_queue(struct sock *);
void tcp_simple_retransmit(struct sock *);
int tcp_trim_head(struct sock *, struct sk_buff *, u32);
-int tcp_fragment(struct sock *, struct sk_buff *, u32, unsigned int);
+enum tcp_queue {
+ TCP_FRAG_IN_WRITE_QUEUE,
+ TCP_FRAG_IN_RTX_QUEUE,
+};
+int tcp_fragment(struct sock *sk, enum tcp_queue tcp_queue,
+ struct sk_buff *skb, u32 len,
+ unsigned int mss_now);
void tcp_send_probe0(struct sock *);
void tcp_send_partial(struct sock *);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index b6f476dd7778..e802eb0192bb 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1201,7 +1201,7 @@ static int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb,
if (pkt_len >= skb->len && !in_sack)
return 0;
- err = tcp_fragment(sk, skb, pkt_len, mss);
+ err = tcp_fragment(sk, TCP_FRAG_IN_RTX_QUEUE, skb, pkt_len, mss);
if (err < 0)
return err;
}
@@ -2295,7 +2295,7 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head)
/* If needed, chop off the prefix to mark as lost. */
lost = (packets - oldcnt) * mss;
if (lost < skb->len &&
- tcp_fragment(sk, skb, lost, mss) < 0)
+ tcp_fragment(sk, TCP_FRAG_IN_RTX_QUEUE, skb, lost, mss) < 0)
break;
cnt = packets;
}
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 69b9ebc20302..48fa7fa40370 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1112,7 +1112,8 @@ static void tcp_adjust_pcount(struct sock *sk, const struct sk_buff *skb, int de
* packet to the list. This won't be called frequently, I hope.
* Remember, these are still headerless SKBs at this point.
*/
-int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len,
+int tcp_fragment(struct sock *sk, enum tcp_queue tcp_queue,
+ struct sk_buff *skb, u32 len,
unsigned int mss_now)
{
struct tcp_sock *tp = tcp_sk(sk);
@@ -1695,7 +1696,8 @@ static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len,
/* All of a TSO frame must be composed of paged data. */
if (skb->len != skb->data_len)
- return tcp_fragment(sk, skb, len, mss_now);
+ return tcp_fragment(sk, TCP_FRAG_IN_WRITE_QUEUE,
+ skb, len, mss_now);
buff = sk_stream_alloc_skb(sk, 0, gfp);
if (unlikely(buff == NULL))
@@ -2193,7 +2195,8 @@ void tcp_send_loss_probe(struct sock *sk)
goto rearm_timer;
if ((pcount > 1) && (skb->len > (pcount - 1) * mss)) {
- if (unlikely(tcp_fragment(sk, skb, (pcount - 1) * mss, mss)))
+ if (unlikely(tcp_fragment(sk, TCP_FRAG_IN_RTX_QUEUE, skb,
+ (pcount - 1) * mss, mss)))
goto rearm_timer;
skb = tcp_write_queue_tail(sk);
}
@@ -2535,7 +2538,8 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
return -EAGAIN;
if (skb->len > cur_mss) {
- if (tcp_fragment(sk, skb, cur_mss, cur_mss))
+ if (tcp_fragment(sk, TCP_FRAG_IN_RTX_QUEUE, skb,
+ cur_mss, cur_mss))
return -ENOMEM; /* We'll try again later. */
} else {
int oldpcount = tcp_skb_pcount(skb);
@@ -3368,7 +3372,8 @@ int tcp_write_wakeup(struct sock *sk)
skb->len > mss) {
seg_size = min(seg_size, mss);
TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_PSH;
- if (tcp_fragment(sk, skb, seg_size, mss))
+ if (tcp_fragment(sk, TCP_FRAG_IN_WRITE_QUEUE,
+ skb, seg_size, mss))
return -1;
} else if (!tcp_skb_pcount(skb))
tcp_set_skb_tso_segs(sk, skb, mss);
More information about the Devel
mailing list