Received: by 10.223.176.5 with SMTP id f5csp697163wra; Fri, 9 Feb 2018 05:52:36 -0800 (PST) X-Google-Smtp-Source: AH8x227GpuKLqebCP3HsqtGAvUeQike2F9/HYhjdp6/ipAVrEXjsqre7r0H2hfhg9+rSZH34WDal X-Received: by 10.99.116.92 with SMTP id e28mr2456743pgn.227.1518184356046; Fri, 09 Feb 2018 05:52:36 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518184356; cv=none; d=google.com; s=arc-20160816; b=JCkOI7CQZJ3OljovczqlBSvJ1E+TEacIwrdaogE07sEJATge+8284TQi2bl3NFuB8y LI7h1Pm352uNDgqQBA9JHX1t5fLWgsfEyRaYQmEHiGifHF/HbR3GhMU0vl3Vvl3F7RJu Eqk5rNlCV8DlPUTrdEAeCPYlHJuAvXyGYHmcvzwOtBjMc5wn1VqZzZ3huxiR7myyaoz3 W8S4GRiLVMm0LgBGROCdcfw8ObGDisj9kgrZt7XxYUOMUisQ3L/GA4Mraq7dPm1F8JVq CIPexQlQG0EdBs2d9zdPcoxlQICH13GjP1uYkklBc+1Wi/GYV3qOvWGV1355tjyxd7bb acag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=oPudeEDLzGc6jJctn6y4X+cjPS3ReDRekb892P5ZZWw=; b=qmlr4i0fQyRxEPP0U2OLZAX/T89t+qqaPgVwajnEfL+4FVafINqp3A9RxFEeOLITWw 0tIVN4R67ZuUGk9WC8VxX9PRwSPLQFT7dOXbwLrSKF19sSwThXKDJEkW4K6uhgujA0tv VI5kPQzmZ1/uPXfvbhH0Tvhk0NybASwOsF4NGGm1wgI+UIszCCKWWy3wNi458MXJ8SFs t8iDfJ9/noQXwyUm+c2/2w92Pr1Pu31ws62PlXPKYrgYQxmLLF9mwcLMJ6dPUhWBDUg9 nhAOBlQwp+900OVYoBS6E0OlSwh9hDVacjAcYKTslE2+KJyUqGJCkZ3CrNedTYI4TNun z81Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r7si1732304pfh.174.2018.02.09.05.52.22; Fri, 09 Feb 2018 05:52:36 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752413AbeBINu3 (ORCPT + 99 others); Fri, 9 Feb 2018 08:50:29 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:53122 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753453AbeBINqd (ORCPT ); Fri, 9 Feb 2018 08:46:33 -0500 Received: from localhost (LFbn-1-12258-90.w90-92.abo.wanadoo.fr [90.92.71.90]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 4A83FD34; Fri, 9 Feb 2018 13:46:32 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Paolo Abeni , Eric Dumazet , Jiri Pirko , Jamal Hadi Salim , Cong Wang , "David S. Miller" Subject: [PATCH 4.15 17/23] net_sched: get rid of rcu_barrier() in tcf_block_put_ext() Date: Fri, 9 Feb 2018 14:40:15 +0100 Message-Id: <20180209133939.183041389@linuxfoundation.org> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180209133938.366024920@linuxfoundation.org> References: <20180209133938.366024920@linuxfoundation.org> User-Agent: quilt/0.65 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.15-stable review patch. If anyone has any objections, please let me know. ------------------ From: Cong Wang [ Upstream commit efbf78973978b0d25af59bc26c8013a942af6e64 ] Both Eric and Paolo noticed the rcu_barrier() we use in tcf_block_put_ext() could be a performance bottleneck when we have a lot of tc classes. Paolo provided the following to demonstrate the issue: tc qdisc add dev lo root htb for I in `seq 1 1000`; do tc class add dev lo parent 1: classid 1:$I htb rate 100kbit tc qdisc add dev lo parent 1:$I handle $((I + 1)): htb for J in `seq 1 10`; do tc filter add dev lo parent $((I + 1)): u32 match ip src 1.1.1.$J done done time tc qdisc del dev root real 0m54.764s user 0m0.023s sys 0m0.000s The rcu_barrier() there is to ensure we free the block after all chains are gone, that is, to queue tcf_block_put_final() at the tail of workqueue. We can achieve this ordering requirement by refcnt'ing tcf block instead, that is, the tcf block is freed only when the last chain in this block is gone. This also simplifies the code. Paolo reported after this patch we get: real 0m0.017s user 0m0.000s sys 0m0.017s Tested-by: Paolo Abeni Cc: Eric Dumazet Cc: Jiri Pirko Cc: Jamal Hadi Salim Signed-off-by: Cong Wang Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- include/net/sch_generic.h | 1 - net/sched/cls_api.c | 30 +++++++++--------------------- 2 files changed, 9 insertions(+), 22 deletions(-) --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -280,7 +280,6 @@ struct tcf_block { struct net *net; struct Qdisc *q; struct list_head cb_list; - struct work_struct work; }; static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz) --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -217,8 +217,12 @@ static void tcf_chain_flush(struct tcf_c static void tcf_chain_destroy(struct tcf_chain *chain) { + struct tcf_block *block = chain->block; + list_del(&chain->list); kfree(chain); + if (list_empty(&block->chain_list)) + kfree(block); } static void tcf_chain_hold(struct tcf_chain *chain) @@ -329,27 +333,13 @@ int tcf_block_get(struct tcf_block **p_b } EXPORT_SYMBOL(tcf_block_get); -static void tcf_block_put_final(struct work_struct *work) -{ - struct tcf_block *block = container_of(work, struct tcf_block, work); - struct tcf_chain *chain, *tmp; - - rtnl_lock(); - - /* At this point, all the chains should have refcnt == 1. */ - list_for_each_entry_safe(chain, tmp, &block->chain_list, list) - tcf_chain_put(chain); - rtnl_unlock(); - kfree(block); -} - /* XXX: Standalone actions are not allowed to jump to any chain, and bound * actions should be all removed after flushing. */ void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q, struct tcf_block_ext_info *ei) { - struct tcf_chain *chain; + struct tcf_chain *chain, *tmp; if (!block) return; @@ -365,13 +355,11 @@ void tcf_block_put_ext(struct tcf_block tcf_block_offload_unbind(block, q, ei); - INIT_WORK(&block->work, tcf_block_put_final); - /* Wait for existing RCU callbacks to cool down, make sure their works - * have been queued before this. We can not flush pending works here - * because we are holding the RTNL lock. + /* At this point, all the chains should have refcnt >= 1. Block will be + * freed after all chains are gone. */ - rcu_barrier(); - tcf_queue_work(&block->work); + list_for_each_entry_safe(chain, tmp, &block->chain_list, list) + tcf_chain_put(chain); } EXPORT_SYMBOL(tcf_block_put_ext);