mirror of
https://github.com/Evolution-X-Devices/kernel_google_b1c1
synced 2026-01-27 17:26:47 +00:00
BACKPORT: net_sched: sch_fq: handle non connected flows
FQ packet scheduler assumed that packets could be classified based on their owning socket. This means that if a UDP server uses one UDP socket to send packets to different destinations, packets all land in one FQ flow. This is unfair, since each TCP flow has a unique bucket, meaning that in case of pressure (fully utilised uplink), TCP flows have more share of the bandwidth. If we instead detect unconnected sockets, we can use a stochastic hash based on the 4-tuple hash. This also means a QUIC server using one UDP socket will properly spread the outgoing packets to different buckets, and in-kernel pacing based on EDT model will no longer risk having big rb-tree on one flow. Note that UDP application might provide the skb->hash in an ancillary message at sendmsg() time to avoid the cost of a dissection in fq packet scheduler. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Albert I <kras@raphielgang.org> Signed-off-by: Rapherion Rollerscaperers <rapherion@raphielgang.org>
This commit is contained in:
committed by
DhineshCool
parent
ad2e747ae4
commit
ce9f46cf74
@@ -256,6 +256,17 @@ static struct fq_flow *fq_classify(struct sk_buff *skb, struct fq_sched_data *q)
|
||||
*/
|
||||
sk = (struct sock *)((hash << 1) | 1UL);
|
||||
skb_orphan(skb);
|
||||
} else if (sk->sk_state == TCP_CLOSE) {
|
||||
unsigned long hash = skb_get_hash(skb) & q->orphan_mask;
|
||||
/*
|
||||
* Sockets in TCP_CLOSE are non connected.
|
||||
* Typical use case is UDP sockets, they can send packets
|
||||
* with sendto() to many different destinations.
|
||||
* We probably could use a generic bit advertising
|
||||
* non connected sockets, instead of sk_state == TCP_CLOSE,
|
||||
* if we care enough.
|
||||
*/
|
||||
sk = (struct sock *)((hash << 1) | 1UL);
|
||||
}
|
||||
|
||||
root = &q->fq_root[hash_32((u32)(long)sk, q->fq_trees_log)];
|
||||
@@ -276,7 +287,7 @@ static struct fq_flow *fq_classify(struct sk_buff *skb, struct fq_sched_data *q)
|
||||
* It not, we need to refill credit with
|
||||
* initial quantum
|
||||
*/
|
||||
if (unlikely(skb->sk &&
|
||||
if (unlikely(skb->sk == sk &&
|
||||
f->socket_hash != sk->sk_hash)) {
|
||||
f->credit = q->initial_quantum;
|
||||
f->socket_hash = sk->sk_hash;
|
||||
@@ -299,7 +310,7 @@ static struct fq_flow *fq_classify(struct sk_buff *skb, struct fq_sched_data *q)
|
||||
}
|
||||
fq_flow_set_detached(f);
|
||||
f->sk = sk;
|
||||
if (skb->sk)
|
||||
if (skb->sk == sk)
|
||||
f->socket_hash = sk->sk_hash;
|
||||
f->credit = q->initial_quantum;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user