From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72BFEC43381 for ; Thu, 14 Feb 2019 20:34:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 46C7121916 for ; Thu, 14 Feb 2019 20:34:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2439974AbfBNUed (ORCPT ); Thu, 14 Feb 2019 15:34:33 -0500 Received: from mx1.redhat.com ([209.132.183.28]:55188 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2439968AbfBNUec (ORCPT ); Thu, 14 Feb 2019 15:34:32 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7EBF38E5AA; Thu, 14 Feb 2019 20:34:31 +0000 (UTC) Received: from localhost (ovpn-200-19.brq.redhat.com [10.40.200.19]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3B1B05D6B3; Thu, 14 Feb 2019 20:34:28 +0000 (UTC) Date: Thu, 14 Feb 2019 21:34:23 +0100 From: Stefano Brivio To: Vlad Buslov Cc: netdev@vger.kernel.org, jhs@mojatatu.com, xiyou.wangcong@gmail.com, jiri@resnulli.us, davem@davemloft.net Subject: Re: [PATCH net-next 03/12] net: sched: flower: introduce reference counting for filters Message-ID: <20190214213423.2260f5b9@redhat.com> In-Reply-To: <20190214074712.17846-4-vladbu@mellanox.com> References: <20190214074712.17846-1-vladbu@mellanox.com> <20190214074712.17846-4-vladbu@mellanox.com> Organization: Red Hat MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 14 Feb 2019 20:34:31 +0000 (UTC) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org On Thu, 14 Feb 2019 09:47:03 +0200 Vlad Buslov wrote: > +static struct cls_fl_filter *fl_get_next_filter(struct tcf_proto *tp, > + unsigned long *handle) > +{ > + struct cls_fl_head *head = fl_head_dereference(tp); > + struct cls_fl_filter *f; > + > + rcu_read_lock(); > + /* don't return filters that are being deleted */ > + while ((f = idr_get_next_ul(&head->handle_idr, > + handle)) != NULL && > + !refcount_inc_not_zero(&f->refcnt)) > + ++(*handle); This... hurts :) What about: while ((f = idr_get_next_ul(&head->handle_idr, &handle))) { if (refcount_inc_not_zero(&f->refcnt)) break; ++(*handle); } ? > + rcu_read_unlock(); > + > + return f; > +} > + > static bool __fl_delete(struct tcf_proto *tp, struct cls_fl_filter *f, > struct netlink_ext_ack *extack) > { > @@ -456,10 +503,7 @@ static bool __fl_delete(struct tcf_proto *tp, struct cls_fl_filter *f, > if (!tc_skip_hw(f->flags)) > fl_hw_destroy_filter(tp, f, extack); > tcf_unbind_filter(tp, &f->res); > - if (async) > - tcf_queue_work(&f->rwork, fl_destroy_filter_work); > - else > - __fl_destroy_filter(f); > + __fl_put(f); > > return last; > } > @@ -494,11 +538,18 @@ static void fl_destroy(struct tcf_proto *tp, bool rtnl_held, > tcf_queue_work(&head->rwork, fl_destroy_sleepable); > } > > +static void fl_put(struct tcf_proto *tp, void *arg) > +{ > + struct cls_fl_filter *f = arg; > + > + __fl_put(f); > +} > + > static void *fl_get(struct tcf_proto *tp, u32 handle) > { > struct cls_fl_head *head = fl_head_dereference(tp); > > - return idr_find(&head->handle_idr, handle); > + return __fl_get(head, handle); > } > > static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = { > @@ -1321,12 +1372,16 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, > struct nlattr **tb; > int err; > > - if (!tca[TCA_OPTIONS]) > - return -EINVAL; > + if (!tca[TCA_OPTIONS]) { > + err = -EINVAL; > + goto errout_fold; > + } > > mask = kzalloc(sizeof(struct fl_flow_mask), GFP_KERNEL); > - if (!mask) > - return -ENOBUFS; > + if (!mask) { > + err = -ENOBUFS; > + goto errout_fold; > + } > > tb = kcalloc(TCA_FLOWER_MAX + 1, sizeof(struct nlattr *), GFP_KERNEL); > if (!tb) { > @@ -1349,6 +1404,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, > err = -ENOBUFS; > goto errout_tb; > } > + refcount_set(&fnew->refcnt, 1); > > err = tcf_exts_init(&fnew->exts, TCA_FLOWER_ACT, 0); > if (err < 0) > @@ -1381,6 +1437,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, > if (!tc_in_hw(fnew->flags)) > fnew->flags |= TCA_CLS_FLAGS_NOT_IN_HW; > > + refcount_inc(&fnew->refcnt); I guess I'm not getting the semantics but... why is it 2 now? -- Stefano