Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp317283imm; Tue, 15 May 2018 02:04:28 -0700 (PDT) X-Google-Smtp-Source: AB8JxZoMOGVthvuFEXfAcFlVKH7PGhA2LTOHfBpBNztNIYSfa7eWpveYo9zi10le91CpDCMmmunE X-Received: by 2002:a65:64c7:: with SMTP id t7-v6mr11704596pgv.274.1526375067995; Tue, 15 May 2018 02:04:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526375067; cv=none; d=google.com; s=arc-20160816; b=hw+I8lMdvsudqq+VBMfmiBpAzBJl7M63uhu87I72+dpBr6Jqn6Ij6mN0I7Hlyhl5eB CPSWzO8Eiepl73BAoxzTg/lG+7ctLg5WvxpKHLW4MswS6qkG+t27knIUBsN20myAnfgf mGcoBtplTrz1EDet+gT88Tfvg5r3Cfq/S8vnhKtcKKryiIcYg5euy5JI05hHLdfw3gX6 I9ZsBchUtGN2Q/3Z9hHdJ8l5AmWe3lGZCDEBk6l1FOI7kNoT5fEND43qBbHFw7DtLwtA KFruP7EAciNcuEvv68k1y5aHszM5kzAyVXFtIqIihUvEj69jZ8q0Zw0ODLZ/etGXXDGQ dtag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:dkim-signature:arc-authentication-results; bh=yVr8FfQaGIWBxM59fcGhzlsIeVRECBkgDtTphLWdKJs=; b=ITMRW49NKkH7trdbc0fDw7gZ++KKO0CiiW8n7/BGOQJ3xdBoQuMBXGdpXbpXHPOnLe +N+Q7cDI1Cf+MYKL/QBAIzYoy7KCuUf5GEn5Vzh3mdQGRUG2EMI38BKykXqwvHr3vNV7 XGAMltrLyRpRA52C8nObXE4AjaAuxQxUXRHUQw4EY2884MXiFBRXav14cPiQ2cIyyEBC D7hLyx+4d2hRqwKalr9VPUmsThZ9TVluMXb5nUg5YhswUlZ2hUV+qqd/zz1k+lV169/d x1NYuonKaie83jktjBiTuTDB2fts03PAweOJdEbdOOEku6ro4yiMpQ2HHgRDVS4xhjdt Vz8Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@resnulli-us.20150623.gappssmtp.com header.s=20150623 header.b=Y7uq6qKc; 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 u6-v6si11479714pls.462.2018.05.15.02.04.13; Tue, 15 May 2018 02:04:27 -0700 (PDT) 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; dkim=pass header.i=@resnulli-us.20150623.gappssmtp.com header.s=20150623 header.b=Y7uq6qKc; 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 S1752417AbeEOJEB (ORCPT + 99 others); Tue, 15 May 2018 05:04:01 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:33657 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752325AbeEOJD7 (ORCPT ); Tue, 15 May 2018 05:03:59 -0400 Received: by mail-wm0-f65.google.com with SMTP id x12-v6so15010666wmc.0 for ; Tue, 15 May 2018 02:03:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=yVr8FfQaGIWBxM59fcGhzlsIeVRECBkgDtTphLWdKJs=; b=Y7uq6qKcz49hMZWbuuJFyOOfr3+sLVaKdLNfTg1anfmWE6dF7uXz+V05947LOj2OTD 1P+Lq0VuM5b+9toivB5ZBRtzvCA29HOOuQ5PKpHKr65KC3xUe2IAvJVsC2mfVSqn4lHo Pmhm+AOLvZx7PfQuQ2ACupOJLkwHA10U5E7IuJIdaMv6Cu/wznj2MpEFXTeZTrMhsor0 8ZUPesKq+jbc0b4n5+0rn6AUqiMlQ0FROe3BYmtRtRjtDeM3fTJeuCJI5c7R6sF5Jg90 5/IYKUZ2s0OoCstxR18xG5NA3ctTF359etaqi8kR2VtBbG4LzWdKl9nHolXHA3eqm7IY c/SQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=yVr8FfQaGIWBxM59fcGhzlsIeVRECBkgDtTphLWdKJs=; b=qj/QHqLgrtYwPamjyM7eK2CKgDL8A6Ok0iCfQYkB/I3m1xhhwgPVWXK6DJIHZM+4LU 0nV5vFhLEkppfzIVQ+NgkEvcQRjN0FHK/lQZxiy/Iht9w4KsdafKVWTFKKptvsIjG+mE 7YPXJC+lPbeCFZoflyY2skbjFj26q51AHIS84x6vRn4rCNgZPwKtvrA9Z4DAx9ZemII+ F45KYuaqyHlAw0AL/Pg/hDM0fPcZDGyMyjSBfqZDOZ5snozmnR9bd1Vj6BclnxZx4/q0 vZ5Eid6tIOdoEwbRrrV+veBig1XJ1NLF+VoFJz4uaVP/C6/ZNofHcBQHC4ZmXqFW7YJL Qnfg== X-Gm-Message-State: ALKqPweAIog5/832bkasXxtVZIgGV5oy2X0BGOP5UQDrKd9WgXd+5Xr2 64TwrhDaV2wgaG/9d5/pVhBReA== X-Received: by 2002:a1c:6b57:: with SMTP id g84-v6mr6819181wmc.127.1526375038504; Tue, 15 May 2018 02:03:58 -0700 (PDT) Received: from localhost (jirka.pirko.cz. [84.16.102.26]) by smtp.gmail.com with ESMTPSA id k30-v6sm18112563wrf.17.2018.05.15.02.03.57 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 15 May 2018 02:03:57 -0700 (PDT) Date: Tue, 15 May 2018 11:03:57 +0200 From: Jiri Pirko To: Vlad Buslov Cc: netdev@vger.kernel.org, davem@davemloft.net, jhs@mojatatu.com, xiyou.wangcong@gmail.com, pablo@netfilter.org, kadlec@blackhole.kfki.hu, fw@strlen.de, ast@kernel.org, daniel@iogearbox.net, edumazet@google.com, keescook@chromium.org, linux-kernel@vger.kernel.org, netfilter-devel@vger.kernel.org, coreteam@netfilter.org, kliteyn@mellanox.com Subject: Re: [PATCH 06/14] net: sched: implement reference counted action release Message-ID: <20180515090357.GK2134@nanopsycho.orion> References: <1526308035-12484-1-git-send-email-vladbu@mellanox.com> <1526308035-12484-7-git-send-email-vladbu@mellanox.com> <20180514164753.GF2134@nanopsycho.orion> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.9.2 (2017-12-15) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Mon, May 14, 2018 at 09:07:06PM CEST, vladbu@mellanox.com wrote: > >On Mon 14 May 2018 at 16:47, Jiri Pirko wrote: >> Mon, May 14, 2018 at 04:27:07PM CEST, vladbu@mellanox.com wrote: >> >> [...] >> >> >>>+static int tcf_action_del_1(struct net *net, char *kind, u32 index, >>>+ struct netlink_ext_ack *extack) >>>+{ >>>+ const struct tc_action_ops *ops; >>>+ int err = -EINVAL; >>>+ >>>+ ops = tc_lookup_action_n(kind); >>>+ if (!ops) { >> >> How this can happen? Apparently you hold reference to the module since >> you put it couple lines below. In that case, I don't really understand >> why you need to lookup and just don't use "ops" pointer you have in >> tcf_action_delete(). > >The problem is that I cant really delete action while holding reference Wait a sec. I was talking about a "module reference" (module_put()) >to it. I can try to decrement reference twice, however that might result >race condition if another task tries to delete that action at the same >time. > >Imagine situation: >1. Action is in actions idr, refcount==1 >2. Task tries to delete action, takes reference while working with it, >refcount==2 >3. Another task tries to delete same action, takes reference, >refcount==3 >4. First task decrements refcount twice, refcount==1 >5. At the same time second task decrements refcount twice, refcount==-1 > >My solution is to save action index, but release the reference. Then try >to lookup action again and delete it if it is still in idr. (was not >concurrently deleted) > >Now same potential race condition with this patch: >1. Action is in actions idr, refcount==1 >2. Task tries to delete action, takes reference while working with it, >refcount==2 >3. Another task tries to delete same action, takes reference, >refcount==3 >4. First task releases reference and deletes actions from idr, which >results another refcount decrement, refcount==1 >5. At the same time second task releases reference to action, >refcount==0, action is deleted >6. When task tries to lookup-delete action from idr by index, action is >not found. This case is handled correctly by code and no negative >overflow of refcount happens. > >> >> >>>+ NL_SET_ERR_MSG(extack, "Specified TC action not found"); >>>+ goto err_out; >>>+ } >>>+ >>>+ if (ops->delete) >>>+ err = ops->delete(net, index); >>>+ >>>+ module_put(ops->owner); >>>+err_out: >>>+ return err; >>>+} >>>+ >>> static int tca_action_flush(struct net *net, struct nlattr *nla, >>> struct nlmsghdr *n, u32 portid, >>> struct netlink_ext_ack *extack) >>>@@ -1052,6 +1088,36 @@ static int tca_action_flush(struct net *net, struct nlattr *nla, >>> return err; >>> } >>> >>>+static int tcf_action_delete(struct net *net, struct list_head *actions, >>>+ struct netlink_ext_ack *extack) >>>+{ >>>+ int ret; >>>+ struct tc_action *a, *tmp; >>>+ char kind[IFNAMSIZ]; >>>+ u32 act_index; >>>+ >>>+ list_for_each_entry_safe(a, tmp, actions, list) { >>>+ const struct tc_action_ops *ops = a->ops; >>>+ >>>+ /* Actions can be deleted concurrently >>>+ * so we must save their type and id to search again >>>+ * after reference is released. >>>+ */ >>>+ strncpy(kind, a->ops->kind, sizeof(kind) - 1); >>>+ act_index = a->tcfa_index; >>>+ >>>+ list_del(&a->list); >>>+ if (tcf_action_put(a)) >>>+ module_put(ops->owner); >>>+ >>>+ /* now do the delete */ >>>+ ret = tcf_action_del_1(net, kind, act_index, extack); >>>+ if (ret < 0) >>>+ return ret; >>>+ } >>>+ return 0; >>>+} >>>+ >> >> [...] >