From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-qt1-x82b.google.com (mail-qt1-x82b.google.com [IPv6:2607:f8b0:4864:20::82b]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.bufferbloat.net (Postfix) with ESMTPS id 736D43CB35 for ; Thu, 14 Feb 2019 16:22:36 -0500 (EST) Received: by mail-qt1-x82b.google.com with SMTP id z39so8672159qtz.0 for ; Thu, 14 Feb 2019 13:22:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cQ9RpE2KsjIcJ34XqTDPwDtNE9WxJ6FlGUWE3I8/AmI=; b=q7mLbNUlkDJQJyFkzXDQM+Kz/mRDo3Z5vNQ4hl3Q/3JOdJXV4y4ZWdSLBM96aa9iso 4sU9CR13w0lwA8Nh3AiIIsjUOTI9KsmMiFVDrtGkDKxGmUPgMfMEGPh+4QoMD32QfqzE ccfSSiiaBIRiOaNCs5fNlza+TrlyEd2OXKJHKJclQjvYNeGWysThXaF+vjY/2e4o/UJG YGYzzKTJnwYZXhx3Ou+nYstTKOG5a5oqsZTAiBofa9IS3xogN8d6/ztIe6gMpK06966r YiCH6auBR4DxFNN4ABqKxCxXvSO6QY/620HlUuoX5Ija5Mc9mTzVVun5xRBV1gb1BAa3 78zA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cQ9RpE2KsjIcJ34XqTDPwDtNE9WxJ6FlGUWE3I8/AmI=; b=T/frqNeVcSnnOT+w863xESpnDn7Ddu7kORLRFXeUVy5qf6C1reQxCv+B9AtEiqMtCg yWV4x24xvjhcRGExQEhOBhWYP3cFixH5z7lFbEf1IFLeg7SqR67GrxONhszYUbP6N4Pb HpbHXQKuN6IU+9oEEoJ8kvgeiAcCLSUQ4TiaiRCg2YBQCPUhqRSXu8b/FGfQ8KdBpMWm mD1nHttYPmUupbkDBj3PWfF55mf0rO9RVEhcZtHuF4h5W5palxdMDMFwo6bNLA29olUJ Zewlbwb19U1KsZHMBaendhyX+gJyzTU0LEv9ElikV18EBdZiiFRpVxdkrc5fZoK3lz7D q1xg== X-Gm-Message-State: AHQUAuY0y8852rr5bt2/7UcwTHFQarC5ABKKwzLuJgCaw608TdX6yB4z 3M8FmnWu8QUOOYMst+T7M3A= X-Google-Smtp-Source: AHgI3Ib7/JmnSFDUeF+bh1hp4H/HrA3PCmA+Re8sdAIMbreVgbjOJBNnQQSyyiHLjSyY/3iMRME68A== X-Received: by 2002:aed:3964:: with SMTP id l91mr4909129qte.33.1550179355800; Thu, 14 Feb 2019 13:22:35 -0800 (PST) Received: from x3200.lan ([2601:152:4302:ae1f::16e]) by smtp.gmail.com with ESMTPSA id 12sm3472867qka.83.2019.02.14.13.22.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 14 Feb 2019 13:22:34 -0800 (PST) From: George Amanakis To: chromatix99@gmail.com Cc: cake@lists.bufferbloat.net, toke@redhat.com, George Amanakis , Pete Heist Date: Thu, 14 Feb 2019 16:22:31 -0500 Message-Id: <20190214212231.12308-1-gamanakis@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <003401d4c4a3$b8502340$28f069c0$@gmail.com> References: <003401d4c4a3$b8502340$28f069c0$@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [Cake] Make the dual modes fairer X-BeenThere: cake@lists.bufferbloat.net X-Mailman-Version: 2.1.20 Precedence: list List-Id: Cake - FQ_codel the next generation List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Feb 2019 21:22:36 -0000 Host fairness does not work well with TCP flows in dual-srchost and dual-dsthost setup. The reason is that ACKs generated by TCP flows are classified as sparse flows, and affect flow isolation from other hosts. Fix this by calculating host_load based only on the bulk flows a host generates. In a hash collision the host_bulk_flow_count values must be decremented on the old hosts and incremented on the new ones *if* the queue is in the bulk set. Reported-by: Pete Heist Signed-off-by: George Amanakis --- sch_cake.c | 92 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 29 deletions(-) diff --git a/sch_cake.c b/sch_cake.c index d434ae0..7ddbe37 100644 --- a/sch_cake.c +++ b/sch_cake.c @@ -146,8 +146,8 @@ struct cake_flow { struct cake_host { u32 srchost_tag; u32 dsthost_tag; - u16 srchost_refcnt; - u16 dsthost_refcnt; + u16 srchost_bulk_flow_count; + u16 dsthost_bulk_flow_count; }; struct cake_heap_entry { @@ -844,8 +844,10 @@ skip_hash: * queue, accept the collision, update the host tags. */ q->way_collisions++; - q->hosts[q->flows[reduced_hash].srchost].srchost_refcnt--; - q->hosts[q->flows[reduced_hash].dsthost].dsthost_refcnt--; + if (q->flows[outer_hash + k].set == CAKE_SET_BULK) { + q->hosts[q->flows[reduced_hash].srchost].srchost_bulk_flow_count--; + q->hosts[q->flows[reduced_hash].dsthost].dsthost_bulk_flow_count--; + } allocate_src = cake_dsrc(flow_mode); allocate_dst = cake_ddst(flow_mode); found: @@ -865,13 +867,14 @@ found: } for (i = 0; i < CAKE_SET_WAYS; i++, k = (k + 1) % CAKE_SET_WAYS) { - if (!q->hosts[outer_hash + k].srchost_refcnt) + if (!q->hosts[outer_hash + k].srchost_bulk_flow_count) break; } q->hosts[outer_hash + k].srchost_tag = srchost_hash; found_src: srchost_idx = outer_hash + k; - q->hosts[srchost_idx].srchost_refcnt++; + if (q->flows[reduced_hash].set == CAKE_SET_BULK) + q->hosts[srchost_idx].srchost_bulk_flow_count++; q->flows[reduced_hash].srchost = srchost_idx; } @@ -887,13 +890,14 @@ found_src: } for (i = 0; i < CAKE_SET_WAYS; i++, k = (k + 1) % CAKE_SET_WAYS) { - if (!q->hosts[outer_hash + k].dsthost_refcnt) + if (!q->hosts[outer_hash + k].dsthost_bulk_flow_count) break; } q->hosts[outer_hash + k].dsthost_tag = dsthost_hash; found_dst: dsthost_idx = outer_hash + k; - q->hosts[dsthost_idx].dsthost_refcnt++; + if (q->flows[reduced_hash].set == CAKE_SET_BULK) + q->hosts[dsthost_idx].dsthost_bulk_flow_count++; q->flows[reduced_hash].dsthost = dsthost_idx; } } @@ -1913,20 +1917,30 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, b->sparse_flow_count++; if (cake_dsrc(q->flow_mode)) - host_load = max(host_load, srchost->srchost_refcnt); + host_load = max(host_load, srchost->srchost_bulk_flow_count); if (cake_ddst(q->flow_mode)) - host_load = max(host_load, dsthost->dsthost_refcnt); + host_load = max(host_load, dsthost->dsthost_bulk_flow_count); flow->deficit = (b->flow_quantum * quantum_div[host_load]) >> 16; } else if (flow->set == CAKE_SET_SPARSE_WAIT) { + struct cake_host *srchost = &b->hosts[flow->srchost]; + struct cake_host *dsthost = &b->hosts[flow->dsthost]; + /* this flow was empty, accounted as a sparse flow, but actually * in the bulk rotation. */ flow->set = CAKE_SET_BULK; b->sparse_flow_count--; b->bulk_flow_count++; + + if (cake_dsrc(q->flow_mode)) + srchost->srchost_bulk_flow_count++; + + if (cake_ddst(q->flow_mode)) + dsthost->dsthost_bulk_flow_count++; + } if (q->buffer_used > q->buffer_max_used) @@ -2097,23 +2111,8 @@ retry: dsthost = &b->hosts[flow->dsthost]; host_load = 1; - if (cake_dsrc(q->flow_mode)) - host_load = max(host_load, srchost->srchost_refcnt); - - if (cake_ddst(q->flow_mode)) - host_load = max(host_load, dsthost->dsthost_refcnt); - - WARN_ON(host_load > CAKE_QUEUES); - /* flow isolation (DRR++) */ if (flow->deficit <= 0) { - /* The shifted prandom_u32() is a way to apply dithering to - * avoid accumulating roundoff errors - */ - flow->deficit += (b->flow_quantum * quantum_div[host_load] + - (prandom_u32() >> 16)) >> 16; - list_move_tail(&flow->flowchain, &b->old_flows); - /* Keep all flows with deficits out of the sparse and decaying * rotations. No non-empty flow can go into the decaying * rotation, so they can't get deficits @@ -2122,6 +2121,13 @@ retry: if (flow->head) { b->sparse_flow_count--; b->bulk_flow_count++; + + if (cake_dsrc(q->flow_mode)) + srchost->srchost_bulk_flow_count++; + + if (cake_ddst(q->flow_mode)) + dsthost->dsthost_bulk_flow_count++; + flow->set = CAKE_SET_BULK; } else { /* we've moved it to the bulk rotation for @@ -2131,6 +2137,22 @@ retry: flow->set = CAKE_SET_SPARSE_WAIT; } } + + if (cake_dsrc(q->flow_mode)) + host_load = max(host_load, srchost->srchost_bulk_flow_count); + + if (cake_ddst(q->flow_mode)) + host_load = max(host_load, dsthost->dsthost_bulk_flow_count); + + WARN_ON(host_load > CAKE_QUEUES); + + /* The shifted prandom_u32() is a way to apply dithering to + * avoid accumulating roundoff errors + */ + flow->deficit += (b->flow_quantum * quantum_div[host_load] + + (prandom_u32() >> 16)) >> 16; + list_move_tail(&flow->flowchain, &b->old_flows); + goto retry; } @@ -2151,6 +2173,13 @@ retry: &b->decaying_flows); if (flow->set == CAKE_SET_BULK) { b->bulk_flow_count--; + + if (cake_dsrc(q->flow_mode)) + srchost->srchost_bulk_flow_count--; + + if (cake_ddst(q->flow_mode)) + dsthost->dsthost_bulk_flow_count--; + b->decaying_flow_count++; } else if (flow->set == CAKE_SET_SPARSE || flow->set == CAKE_SET_SPARSE_WAIT) { @@ -2164,14 +2193,19 @@ retry: if (flow->set == CAKE_SET_SPARSE || flow->set == CAKE_SET_SPARSE_WAIT) b->sparse_flow_count--; - else if (flow->set == CAKE_SET_BULK) + else if (flow->set == CAKE_SET_BULK) { b->bulk_flow_count--; - else + + if (cake_dsrc(q->flow_mode)) + srchost->srchost_bulk_flow_count--; + + if (cake_ddst(q->flow_mode)) + dsthost->dsthost_bulk_flow_count--; + + } else b->decaying_flow_count--; flow->set = CAKE_SET_NONE; - srchost->srchost_refcnt--; - dsthost->dsthost_refcnt--; } goto begin; } -- 2.20.1