From patchwork Sun Jan 30 01:52:57 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sven Eckelmann X-Patchwork-Id: 799 Return-Path: Received: from v3-1039.vlinux.de (narfation.org [79.140.41.39]) by open-mesh.org (Postfix) with ESMTPS id 268B2154638 for ; Sun, 30 Jan 2011 02:53:09 +0100 (CET) Received: from sven-desktop.home.narfation.org (unknown [88.130.181.181]) by v3-1039.vlinux.de (Postfix) with ESMTPSA id AC01C94061; Sun, 30 Jan 2011 02:53:41 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=narfation.org; s=mail; t=1296352422; bh=qoaa96d0LxsqrfqEubAcyVgcwpXyCi+QstiOiGC2xMc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=h8QYwirRfvzk3hi7UINxJKz81zRT/bkLx14W36W9vjZHsjbPauRgnbJd+CA3zqJ3t rM7DiIgdIrP3XAlyPWpYLxxTMuoMfpvbo6VuiyI10ELa67SMAArj39LXpvBZk62vPb LvbmgWfwXfCPmTB7uJnd8NWzR2JIRxL22DzMsCA4= From: Sven Eckelmann To: b.a.t.m.a.n@lists.open-mesh.org Date: Sun, 30 Jan 2011 02:52:57 +0100 Message-Id: <1296352379-1546-3-git-send-email-sven@narfation.org> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <1296352379-1546-1-git-send-email-sven@narfation.org> References: <1296352379-1546-1-git-send-email-sven@narfation.org> Subject: [B.A.T.M.A.N.] [PATCH 2/4] batman-adv: Correct rcu refcounting for softif_neigh X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.11 Precedence: list Reply-To: The list for a Better Approach To Mobile Ad-hoc Networking 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: Sun, 30 Jan 2011 01:53:09 -0000 Signed-off-by: Sven Eckelmann --- batman-adv/soft-interface.c | 34 ++++++++++++++++------------------ batman-adv/types.h | 2 +- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/batman-adv/soft-interface.c b/batman-adv/soft-interface.c index 145e0f7..9fb8a6a 100644 --- a/batman-adv/soft-interface.c +++ b/batman-adv/soft-interface.c @@ -79,20 +79,18 @@ int my_skb_head_push(struct sk_buff *skb, unsigned int len) return 0; } -static void softif_neigh_free_ref(struct kref *refcount) -{ - struct softif_neigh *softif_neigh; - - softif_neigh = container_of(refcount, struct softif_neigh, refcount); - kfree(softif_neigh); -} - static void softif_neigh_free_rcu(struct rcu_head *rcu) { struct softif_neigh *softif_neigh; softif_neigh = container_of(rcu, struct softif_neigh, rcu); - kref_put(&softif_neigh->refcount, softif_neigh_free_ref); + kfree(softif_neigh); +} + +static void softif_neigh_free_ref(struct softif_neigh *softif_neigh) +{ + if (atomic_dec_and_test(&softif_neigh->refcount)) + call_rcu(&softif_neigh->rcu, softif_neigh_free_rcu); } void softif_neigh_purge(struct bat_priv *bat_priv) @@ -119,11 +117,10 @@ void softif_neigh_purge(struct bat_priv *bat_priv) softif_neigh->addr, softif_neigh->vid); softif_neigh_tmp = bat_priv->softif_neigh; bat_priv->softif_neigh = NULL; - kref_put(&softif_neigh_tmp->refcount, - softif_neigh_free_ref); + softif_neigh_free_ref(softif_neigh_tmp); } - call_rcu(&softif_neigh->rcu, softif_neigh_free_rcu); + softif_neigh_free_ref(softif_neigh); } spin_unlock_bh(&bat_priv->softif_neigh_lock); @@ -144,8 +141,11 @@ static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv, if (softif_neigh->vid != vid) continue; + if (!atomic_inc_not_zero(&softif_neigh->refcount)) + continue; + softif_neigh->last_seen = jiffies; - goto found; + goto out; } softif_neigh = kzalloc(sizeof(struct softif_neigh), GFP_ATOMIC); @@ -155,15 +155,13 @@ static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv, memcpy(softif_neigh->addr, addr, ETH_ALEN); softif_neigh->vid = vid; softif_neigh->last_seen = jiffies; - kref_init(&softif_neigh->refcount); + atomic_set(&softif_neigh->refcount, 1); INIT_HLIST_NODE(&softif_neigh->list); spin_lock_bh(&bat_priv->softif_neigh_lock); hlist_add_head_rcu(&softif_neigh->list, &bat_priv->softif_neigh_list); spin_unlock_bh(&bat_priv->softif_neigh_lock); -found: - kref_get(&softif_neigh->refcount); out: rcu_read_unlock(); return softif_neigh; @@ -267,7 +265,7 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev, softif_neigh->addr, softif_neigh->vid); softif_neigh_tmp = bat_priv->softif_neigh; bat_priv->softif_neigh = softif_neigh; - kref_put(&softif_neigh_tmp->refcount, softif_neigh_free_ref); + softif_neigh_free_ref(softif_neigh_tmp); /* we need to hold the additional reference */ goto err; } @@ -285,7 +283,7 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev, } out: - kref_put(&softif_neigh->refcount, softif_neigh_free_ref); + softif_neigh_free_ref(softif_neigh); err: kfree_skb(skb); return; diff --git a/batman-adv/types.h b/batman-adv/types.h index ca5f20a..8df6d9d 100644 --- a/batman-adv/types.h +++ b/batman-adv/types.h @@ -270,7 +270,7 @@ struct softif_neigh { uint8_t addr[ETH_ALEN]; unsigned long last_seen; short vid; - struct kref refcount; + atomic_t refcount; struct rcu_head rcu; };