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 6AB773CB35 for ; Thu, 14 Feb 2019 13:46:04 -0500 (EST) Received: by mail-qt1-x82b.google.com with SMTP id v10so8048493qtp.8 for ; Thu, 14 Feb 2019 10:46:04 -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=WJ1nTCasjhCYuGpxecHz/Aj6eD1EGtVTx/YovkpVKGo=; b=SzgDBr56gW9Uq1jF6cESO88vUY49JgGeRnGJhbGIbrwwTLuLgS3MxUoeJTwdlz9Cvk krhuCOtvwJ5VYuCjgL0eS2Z9a6HGSoVGWxsCr0UKTRkL0UZBeKhbLRnYntC0QZXqJDds +86UqyV+5h4BB/FAlmJK6okG+6JPQEfh+vQx7bwcHIF889zq3ZmjpJMExOV5tIuKUtHy /tbVUTa/nOnvMg2CbFCGTlo45C+AOcO7GrOERdcrHIz266jVlp7kaVbGtwkzpv1XXIF5 8uioabVecJDn3lmmVdF+M5Q+0Ta3dhkdWCukK0gV7+bDYth0i6lDybSSVyNpbdfBijbx oocA== 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=WJ1nTCasjhCYuGpxecHz/Aj6eD1EGtVTx/YovkpVKGo=; b=iMTDlT0MZsXcjExmgxjxPdedZIoGBaZdmnMcH9psEhdpLc7zk89Ao595kOI5dHZEg2 yogcwP9mbHI8VxQmQVEWPpps3SM2jZ09dscdj7jMC4710aycML8Plxjyp/IJS/6fKo9B 2R6lbmmqwETKd0oY+pQ92gmMEpSiMPlxcedLzDFLpErxtTkfdcfdgzSlOhUfUQ8nzdCr Xfiwxz3jD5xC4mF2uINKrc6TLWZ6BxJGxkojrKmSX5CuY8cKG/2Vc1G3aWNaifgUVPVe FA978tJSpvGBKFkyFLlQ5GiFeOE5Z1+YLOuGkBI4+q7NEczcc2GLJEUH2Ml0eehkdXxQ gyRA== X-Gm-Message-State: AHQUAuZrNGLMGxEtNuDCMU+bSLmLkXubmwCZmV4Paw6TFu8vUM5/0iHb aRNjrbL+fL64m5BJ/fA67xc= X-Google-Smtp-Source: AHgI3IaZPQqnC/2tuDPpjs3m+kf/bD+kS8E2JBPs/uiFcDLfK5QdrxJIzqTJHH1Q7yZbGebwXBhhbA== X-Received: by 2002:a0c:aa84:: with SMTP id f4mr4095139qvb.243.1550169963714; Thu, 14 Feb 2019 10:46:03 -0800 (PST) Received: from x3200.lan ([2601:152:4302:ae1f::16e]) by smtp.gmail.com with ESMTPSA id c68sm1528345qkf.65.2019.02.14.10.46.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 14 Feb 2019 10:46:02 -0800 (PST) From: George Amanakis To: toke@redhat.com Cc: cake@lists.bufferbloat.net, chromatix99@gmail.com, George Amanakis , Pete Heist Date: Thu, 14 Feb 2019 13:45:59 -0500 Message-Id: <20190214184559.2614-1-gamanakis@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <87zhqys0eb.fsf@toke.dk> References: <87zhqys0eb.fsf@toke.dk> 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 18:46:04 -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. Reported-by: Pete Heist Signed-off-by: George Amanakis --- sch_cake.c | 84 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 29 deletions(-) diff --git a/sch_cake.c b/sch_cake.c index d434ae0..ed3fbd9 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,6 @@ 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--; allocate_src = cake_dsrc(flow_mode); allocate_dst = cake_ddst(flow_mode); found: @@ -865,13 +863,12 @@ 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++; q->flows[reduced_hash].srchost = srchost_idx; } @@ -887,13 +884,12 @@ 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++; q->flows[reduced_hash].dsthost = dsthost_idx; } } @@ -1913,20 +1909,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 +2103,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 +2113,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 +2129,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 +2165,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 +2185,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