From patchwork Sat Jan 22 23:28:27 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Marek Lindner X-Patchwork-Id: 741 Return-Path: Received: from nm8-vm0.bullet.mail.ukl.yahoo.com (nm8-vm0.bullet.mail.ukl.yahoo.com [217.146.183.238]) by open-mesh.org (Postfix) with SMTP id C1F4C154662 for ; Sun, 23 Jan 2011 00:31:58 +0100 (CET) Received: from [217.146.183.214] by nm8.bullet.mail.ukl.yahoo.com with NNFMP; 22 Jan 2011 23:31:58 -0000 Received: from [77.238.184.70] by tm7.bullet.mail.ukl.yahoo.com with NNFMP; 22 Jan 2011 23:31:58 -0000 Received: from [127.0.0.1] by smtp139.mail.ukl.yahoo.com with NNFMP; 22 Jan 2011 23:31:58 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.de; s=s1024; t=1295739118; bh=1D3Qnh5OCFAx3j7AaEzOqr4i2ezSwLwAS2Z4bRa06H0=; h=X-Yahoo-Newman-Id:Received:X-Yahoo-SMTP:X-YMail-OSG:X-Yahoo-Newman-Property:From:To:Cc:Subject:Date:Message-Id:X-Mailer:In-Reply-To:References:MIME-Version:Content-Type:Content-Transfer-Encoding; b=ovNmhAvI/Qloxc1zMxD+WGsNexy5zZ04TEFV7E/OUyWTKh3GTHJc82DxvTmCA8IuD5YT7vXGSzORNGwQcRyzV5r9ruWPtw7+vIjdhmYm/t+nda4NwizGbkTJI/CBcho9Xb0QhPP07EZq5Y0bc2JIhKtjfBr06jtEEel9OFfhALU= X-Yahoo-Newman-Id: 217137.39713.bm@smtp139.mail.ukl.yahoo.com Received: from localhost (lindner_marek@81.57.254.118 with plain) by smtp139.mail.ukl.yahoo.com with SMTP; 22 Jan 2011 23:31:54 +0000 GMT X-Yahoo-SMTP: tW.h3tiswBBMXO2coYcbPigGD5Lt6zY_.Zc- X-YMail-OSG: 25en4xIVM1nVetGfP8FksTNHCrWGF5UxqQQzO3tgKTbp1aA PcrbP8_6m_jwup8y8Bgi9r21ajIVTqxopFZGPg4SNZOaq1YiWZUs3L0RoUKW X3HG5O4Z8g.7jzYj.PKqRe7CgpscB7e8402_oPzEAP3pm4HIHvc52lTR6pBg Yx6iIRXr6rlK4PFHkH2ApekqYPhlPU.kGqhnaEWCfm72aSEDAAOEL48F5fGi NCAkBgpTQGKgWCKvULrZG3WMjiU.d63kCZDhymyjSsmlRh0mQpTzYV8AoeeK Re4kWHaZJT6ryBWs- X-Yahoo-Newman-Property: ymail-3 From: Marek Lindner To: b.a.t.m.a.n@lists.open-mesh.org Date: Sun, 23 Jan 2011 00:28:27 +0100 Message-Id: <1295738907-10092-1-git-send-email-lindner_marek@yahoo.de> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <1295733797-1552-1-git-send-email-lindner_marek@yahoo.de> References: <1295733797-1552-1-git-send-email-lindner_marek@yahoo.de> MIME-Version: 1.0 Cc: Marek Lindner Subject: [B.A.T.M.A.N.] [PATCHv2] batman-adv: protect bit operations to count OGMs with spinlock 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: Sat, 22 Jan 2011 23:31:59 -0000 Reported-by: Linus Lüssing Signed-off-by: Marek Lindner --- Found more code that touches the variables that need protection. batman-adv/routing.c | 61 ++++++++++++++++++++++++------------------------- batman-adv/types.h | 6 ++-- 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/batman-adv/routing.c b/batman-adv/routing.c index a90d105..06201dc 100644 --- a/batman-adv/routing.c +++ b/batman-adv/routing.c @@ -152,7 +152,8 @@ static int is_bidirectional_neigh(struct orig_node *orig_node, struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; struct hlist_node *node; unsigned char total_count; - int ret = 0; + uint8_t orig_eq_count, neigh_rq_count, tq_own; + int tq_asym_penalty, ret = 0; if (orig_node == orig_neigh_node) { rcu_read_lock(); @@ -205,23 +206,25 @@ static int is_bidirectional_neigh(struct orig_node *orig_node, orig_node->last_valid = jiffies; + spin_lock_bh(&orig_node->ogm_cnt_lock); + orig_eq_count = orig_neigh_node->bcast_own_sum[if_incoming->if_num]; + neigh_rq_count = neigh_node->real_packet_count; + spin_unlock_bh(&orig_node->ogm_cnt_lock); + /* pay attention to not get a value bigger than 100 % */ - total_count = (orig_neigh_node->bcast_own_sum[if_incoming->if_num] > - neigh_node->real_packet_count ? - neigh_node->real_packet_count : - orig_neigh_node->bcast_own_sum[if_incoming->if_num]); + total_count = (orig_eq_count > neigh_rq_count ? + neigh_rq_count : orig_eq_count); /* if we have too few packets (too less data) we set tq_own to zero */ /* if we receive too few packets it is not considered bidirectional */ if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) || - (neigh_node->real_packet_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM)) - orig_neigh_node->tq_own = 0; + (neigh_rq_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM)) + tq_own = 0; else /* neigh_node->real_packet_count is never zero as we * only purge old information when getting new * information */ - orig_neigh_node->tq_own = (TQ_MAX_VALUE * total_count) / - neigh_node->real_packet_count; + tq_own = (TQ_MAX_VALUE * total_count) / neigh_rq_count; /* * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does @@ -229,20 +232,16 @@ static int is_bidirectional_neigh(struct orig_node *orig_node, * punishes asymmetric links more. This will give a value * between 0 and TQ_MAX_VALUE */ - orig_neigh_node->tq_asym_penalty = - TQ_MAX_VALUE - - (TQ_MAX_VALUE * - (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) * - (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) * - (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count)) / - (TQ_LOCAL_WINDOW_SIZE * - TQ_LOCAL_WINDOW_SIZE * - TQ_LOCAL_WINDOW_SIZE); - - batman_packet->tq = ((batman_packet->tq * - orig_neigh_node->tq_own * - orig_neigh_node->tq_asym_penalty) / - (TQ_MAX_VALUE * TQ_MAX_VALUE)); + tq_asym_penalty = TQ_MAX_VALUE - (TQ_MAX_VALUE * + (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count) * + (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count) * + (TQ_LOCAL_WINDOW_SIZE - neigh_rq_count)) / + (TQ_LOCAL_WINDOW_SIZE * + TQ_LOCAL_WINDOW_SIZE * + TQ_LOCAL_WINDOW_SIZE); + + batman_packet->tq = ((batman_packet->tq * tq_own * tq_asym_penalty) / + (TQ_MAX_VALUE * TQ_MAX_VALUE)); bat_dbg(DBG_BATMAN, bat_priv, "bidirectional: " @@ -250,8 +249,7 @@ static int is_bidirectional_neigh(struct orig_node *orig_node, "real recv = %2i, local tq: %3i, asym_penalty: %3i, " "total tq: %3i\n", orig_node->orig, orig_neigh_node->orig, total_count, - neigh_node->real_packet_count, orig_neigh_node->tq_own, - orig_neigh_node->tq_asym_penalty, batman_packet->tq); + neigh_rq_count, tq_own, tq_asym_penalty, batman_packet->tq); /* if link has the minimum required transmission quality * consider it bidirectional */ @@ -539,18 +537,19 @@ static char count_real_packets(struct ethhdr *ethhdr, char is_duplicate = 0; int32_t seq_diff; int need_update = 0; - int set_mark; + int set_mark, ret = -1; orig_node = get_orig_node(bat_priv, batman_packet->orig); if (!orig_node) return 0; + spin_lock_bh(&orig_node->ogm_cnt_lock); seq_diff = batman_packet->seqno - orig_node->last_real_seqno; /* signalize caller that the packet is to be dropped. */ if (window_protected(bat_priv, seq_diff, &orig_node->batman_seqno_reset)) - goto err; + goto out; rcu_read_lock(); hlist_for_each_entry_rcu(tmp_neigh_node, node, @@ -583,12 +582,12 @@ static char count_real_packets(struct ethhdr *ethhdr, orig_node->last_real_seqno = batman_packet->seqno; } - kref_put(&orig_node->refcount, orig_node_free_ref); - return is_duplicate; + ret = is_duplicate; -err: +out: + spin_unlock_bh(&orig_node->ogm_cnt_lock); kref_put(&orig_node->refcount, orig_node_free_ref); - return -1; + return ret; } void receive_bat_packet(struct ethhdr *ethhdr, diff --git a/batman-adv/types.h b/batman-adv/types.h index 8e97861..56309bf 100644 --- a/batman-adv/types.h +++ b/batman-adv/types.h @@ -70,8 +70,6 @@ struct orig_node { struct neigh_node *router; unsigned long *bcast_own; uint8_t *bcast_own_sum; - uint8_t tq_own; - int tq_asym_penalty; unsigned long last_valid; unsigned long bcast_seqno_reset; unsigned long batman_seqno_reset; @@ -89,7 +87,9 @@ struct orig_node { struct kref refcount; struct bat_priv *bat_priv; unsigned long last_frag_packet; - spinlock_t ogm_cnt_lock; /* protects ogm counter */ + spinlock_t ogm_cnt_lock; /* protects: bcast_own, bcast_own_sum, + * neigh_node->real_bits, + * neigh_node->real_packet_count */ atomic_t bond_candidates; struct list_head bond_list; };