From patchwork Tue Dec 15 23:31:36 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sven Eckelmann X-Patchwork-Id: 4793 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; dkim=pass reason="1024-bit key; unprotected key" header.d=narfation.org header.i=@narfation.org header.b=kKmHwm0L; 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 F1D2281944 for ; Wed, 16 Dec 2015 00:32:20 +0100 (CET) Received: from sven-desktop.home.narfation.org (unknown [IPv6:2a02:3100:260c:3afd:2066:82e6:79c1:88d8]) by v3-1039.vlinux.de (Postfix) with ESMTPSA id 87338110102; Wed, 16 Dec 2015 00:32:20 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=narfation.org; s=20121; t=1450222340; bh=UrgZRDNIvV/tISN/oGxlcdDaHsSeZWOxhj6eoGaOHqM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kKmHwm0LZwolLZAyjf+94pM6UIlWEXFVdN/Q9QpWQ3y9ohU9mM21W6w5jiuuOw+jf P4Q/bopdINaKnSAldfetVpe/6FKwl7ak3UOboUFKLfj34pdNZd/sbiAqm7fydf3fIz 0eTkbYTEtscOZwxbElhq8QPPUDBDtbMEmIhe3Jto= From: Sven Eckelmann To: b.a.t.m.a.n@lists.open-mesh.org Date: Wed, 16 Dec 2015 00:31:36 +0100 Message-Id: <1450222316-1764-3-git-send-email-sven@narfation.org> X-Mailer: git-send-email 2.6.4 In-Reply-To: <1450222316-1764-1-git-send-email-sven@narfation.org> References: <1450222316-1764-1-git-send-email-sven@narfation.org> Subject: [B.A.T.M.A.N.] [PATCH 03/23] batman-adv: Avoid recursive call_rcu for batadv_hardif_neigh_node 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: Tue, 15 Dec 2015 23:32:21 -0000 The batadv_hardif_neigh_put function uses call_rcu to delay the free of the batadv_hardif_neigh_node object until no (already started) rcu_read_lock is enabled anymore. This makes sure that no context still is trying to access the object which should be removed. But batadv_hardif_neigh_node also contains a reference to if_incoming which must be removed. This if_incoming was done in the call_rcu function batadv_hardif_neigh_free_rcu but should actually be done in the batadv_hardif_neigh_release_rcu 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 because this barrier was most likely 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. Signed-off-by: Sven Eckelmann --- net/batman-adv/originator.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 24c62a8..18305d3 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -215,7 +215,6 @@ void batadv_neigh_ifinfo_free_ref(struct batadv_neigh_ifinfo *neigh_ifinfo) static void batadv_hardif_neigh_free(struct batadv_hardif_neigh_node *hardif_neigh) { - batadv_hardif_free_ref_now(hardif_neigh->if_incoming); kfree(hardif_neigh); } @@ -235,6 +234,8 @@ static void batadv_hardif_neigh_release_now(struct kref *ref) hlist_del_init_rcu(&hardif_neigh->list); spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock); + batadv_hardif_free_ref_now(hardif_neigh->if_incoming); + batadv_hardif_neigh_free(hardif_neigh); } @@ -277,6 +278,8 @@ static void batadv_hardif_neigh_release_rcu(struct kref *ref) hlist_del_init_rcu(&hardif_neigh->list); spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock); + batadv_hardif_free_ref(hardif_neigh->if_incoming); + call_rcu(&hardif_neigh->rcu, batadv_hardif_neigh_free_rcu); }