From patchwork Thu Jan 14 14:28:19 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sven Eckelmann X-Patchwork-Id: 4862 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=79.140.41.39; helo=v3-1039.vlinux.de; envelope-from=sven@narfation.org; receiver=b.a.t.m.a.n@lists.open-mesh.org Authentication-Results: open-mesh.org; dmarc=pass header.from=narfation.org Authentication-Results: open-mesh.org; dkim=pass reason="1024-bit key; unprotected key" header.d=narfation.org header.i=@narfation.org header.b=xujQ+nfu; dkim-adsp=pass; dkim-atps=neutral Received: from v3-1039.vlinux.de (narfation.org [79.140.41.39]) by open-mesh.org (Postfix) with ESMTPS id A39FC81B0C for ; Thu, 14 Jan 2016 15:28:23 +0100 (CET) Received: from sven-desktop.home.narfation.org (x5d849b03.dyn.telefonica.de [93.132.155.3]) by v3-1039.vlinux.de (Postfix) with ESMTPSA id 233561100F1; Thu, 14 Jan 2016 15:28:23 +0100 (CET) Authentication-Results: v3-1039.vlinux.de; dmarc=none header.from=narfation.org DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=narfation.org; s=20121; t=1452781703; bh=n+FhKwvu+VTWurZflpQY05cb5a2MprLacV5MH9GIu+Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=xujQ+nfuWSR45qnyu8egPL/VTyl2orr98XMo9kObqqvYilIdHWNpZMG2NySh4yHFM 1cpQl/vZuNGWQdvFd7FSUG8e05I4rGlDeeBjzaHhK3P+ndaz2ftyN7DJtYNuF1QH59 pA015Y/pqHVt1fToqvTFnkV737LkyBq7bbrKE0eQ= From: Sven Eckelmann To: b.a.t.m.a.n@lists.open-mesh.org Date: Thu, 14 Jan 2016 15:28:19 +0100 Message-Id: <1452781699-14539-1-git-send-email-sven@narfation.org> X-Mailer: git-send-email 2.7.0.rc3 In-Reply-To: <1451992006-13191-3-git-send-email-sven@narfation.org> References: <1451992006-13191-3-git-send-email-sven@narfation.org> Subject: [B.A.T.M.A.N.] [PATCH v5 03/31] batman-adv: Avoid recursive call_rcu for batadv_bla_claim X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: The list for a Better Approach To Mobile Ad-hoc Networking List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Jan 2016 14:28:24 -0000 The batadv_claim_free_ref function uses call_rcu to delay the free of the batadv_bla_claim object until no (already started) rcu_read_lock is enabled anymore. This makes sure that no context is still trying to access the object which should be removed. But batadv_bla_claim also contains a reference to backbone_gw which must be removed. The reference drop of backbone_gw was done in the call_rcu function batadv_claim_free_rcu but should actually be done in the batadv_claim_release function to avoid nested call_rcus. This is important because rcu_barrier (e.g. batadv_softif_free or batadv_exit) will not detect the inner call_rcu as relevant for its execution. Otherwise this barrier will most likely be inserted in the queue before the callback of the first call_rcu was executed. The caller of rcu_barrier will therefore continue to run before the inner call_rcu callback finished. Fixes: a9ce0dc43e2c ("batman-adv: add basic bridge loop avoidance code") Signed-off-by: Sven Eckelmann --- v5: - fix commit message ("batadv_hardif_neigh_free_ref()" -> "batadv_claim_free_ref()" v4: - fix function names in commit messages - fix double whitespace in batadv_tt_orig_list_entry_release kerneldoc - add extra patch for batadv_claim_free_ref kerneldoc fix - change the phrase "free it" in all *_free_ref/*_put functions to "release it" v3: - update copyright year v2: - split patchset into fixes and kref migration to make it easier when the decision is made where each patch will be applied net/batman-adv/bridge_loop_avoidance.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 034db05..7e92fd1 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -154,17 +154,14 @@ batadv_backbone_gw_free_ref(struct batadv_bla_backbone_gw *backbone_gw) } /** - * batadv_claim_free_rcu - finally deinitialize the claim - * @rcu: rcu pointer within the claim structure + * batadv_claim_release - release claim from lists and queue for free after rcu + * grace period + * @claim: claim to be free'd */ -static void batadv_claim_free_rcu(struct rcu_head *rcu) +static void batadv_claim_release(struct batadv_bla_claim *claim) { - struct batadv_bla_claim *claim; - - claim = container_of(rcu, struct batadv_bla_claim, rcu); - batadv_backbone_gw_free_ref(claim->backbone_gw); - kfree(claim); + kfree_rcu(claim, rcu); } /** @@ -175,7 +172,7 @@ static void batadv_claim_free_rcu(struct rcu_head *rcu) static void batadv_claim_free_ref(struct batadv_bla_claim *claim) { if (atomic_dec_and_test(&claim->refcount)) - call_rcu(&claim->rcu, batadv_claim_free_rcu); + batadv_claim_release(claim); } /**