From patchwork Tue Jan 26 07:16:38 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Marek Lindner X-Patchwork-Id: 21 Return-Path: Received: from mo-p05-ob.rzone.de (mo-p05-ob.rzone.de [81.169.146.181]) by open-mesh.net (Postfix) with ESMTPS id 97F491541ED for ; Tue, 26 Jan 2010 08:41:56 +0100 (CET) X-RZG-AUTH: :OGkHfVO9a++ASa1NN1xF8Z+yxAO4YqHmxoKm7X00LncCjhL5i1Yt3al3Gv4UR4pxi2RPNNa4 X-RZG-CLASS-ID: mo05 Received: from turgot.localnet (61-59-128-157.static.seed.net.tw [61.59.128.157]) by post.strato.de (klopstock mo48) (RZmta 22.6) with ESMTP id R02504m0Q7HRe0 for ; Tue, 26 Jan 2010 08:20:33 +0100 (MET) From: Marek Lindner To: "The list for a Better Approach To Mobile Ad-hoc Networking" Date: Tue, 26 Jan 2010 15:16:38 +0800 User-Agent: KMail/1.12.4 (Linux/2.6.32-trunk-686; KDE/4.3.4; i686; ; ) References: <20100123174616.GA4795@Sellars> <20100126061311.GA12697@Sellars> In-Reply-To: <20100126061311.GA12697@Sellars> MIME-Version: 1.0 Message-Id: <201001261516.39057.lindner_marek@yahoo.de> Subject: Re: [B.A.T.M.A.N.] slowpath warning 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: Tue, 26 Jan 2010 07:41:57 -0000 On Tuesday 26 January 2010 14:13:11 Linus Lüssing wrote: > I'm now able to reproduce the second problem as well: > Activating the vis-server on one node causes the vis-clients to > throw this call trace with its slow path warning imediately. > Nevertheless, vis output works anyway, clients are sending > vis-packets and the server is drawing nice graphs. > See the attachment for an example call trace. Please try the attached patch and see if it helps. Regards, Marek diff --git a/batman-adv-kernelland/vis.c b/batman-adv-kernelland/vis.c index b118d1e..a6c235f 100644 --- a/batman-adv-kernelland/vis.c +++ b/batman-adv-kernelland/vis.c @@ -405,6 +405,9 @@ static void purge_vis_packets(void) { HASHIT(hashit); struct vis_info *info; + unsigned long flags; + + spin_lock_irqsave(&vis_hash_lock, flags); while (hash_iterate(vis_hash, &hashit)) { info = hashit.bucket->data; @@ -416,13 +419,17 @@ static void purge_vis_packets(void) free_info(info); } } + + spin_unlock_irqrestore(&vis_hash_lock, flags); } static void broadcast_vis_packet(struct vis_info *info, int packet_length) { HASHIT(hashit); struct orig_node *orig_node; + struct batman_if *batman_if; unsigned long flags; + uint8_t dstaddr[ETH_ALEN]; spin_lock_irqsave(&orig_hash_lock, flags); @@ -431,45 +438,60 @@ static void broadcast_vis_packet(struct vis_info *info, int packet_length) orig_node = hashit.bucket->data; /* if it's a vis server and reachable, send it. */ - if (orig_node && - (orig_node->flags & VIS_SERVER) && - orig_node->batman_if && - orig_node->router) { + if ((!orig_node) || (!orig_node->batman_if) || + (!orig_node->router)) + continue; - /* don't send it if we already received the packet from - * this node. */ - if (recv_list_is_in(&info->recv_list, orig_node->orig)) - continue; + if (!(orig_node->flags & VIS_SERVER)) + continue; - memcpy(info->packet.target_orig, - orig_node->orig, ETH_ALEN); + /* don't send it if we already received the packet from + * this node. */ + if (recv_list_is_in(&info->recv_list, orig_node->orig)) + continue; - send_raw_packet((unsigned char *) &info->packet, - packet_length, - orig_node->batman_if, - orig_node->router->addr); - } + spin_unlock_irqrestore(&orig_hash_lock, flags); + + memcpy(info->packet.target_orig, orig_node->orig, ETH_ALEN); + batman_if = orig_node->batman_if; + memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); + + send_raw_packet((unsigned char *)&info->packet, + packet_length, batman_if, dstaddr); + + spin_lock_irqsave(&orig_hash_lock, flags); } - memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); + spin_unlock_irqrestore(&orig_hash_lock, flags); + memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); } static void unicast_vis_packet(struct vis_info *info, int packet_length) { struct orig_node *orig_node; + struct batman_if *batman_if; unsigned long flags; + uint8_t dstaddr[ETH_ALEN]; spin_lock_irqsave(&orig_hash_lock, flags); orig_node = ((struct orig_node *) hash_find(orig_hash, info->packet.target_orig)); - if ((orig_node != NULL) && - (orig_node->batman_if != NULL) && - (orig_node->router != NULL)) { - send_raw_packet((unsigned char *) &info->packet, packet_length, - orig_node->batman_if, - orig_node->router->addr); - } + if ((!orig_node) || (!orig_node->batman_if) || (!orig_node->router)) + goto out; + + /* don't lock while sending the packets ... we therefore + * copy the required data before sending */ + batman_if = orig_node->batman_if; + memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); + spin_unlock_irqrestore(&orig_hash_lock, flags); + + send_raw_packet((unsigned char *)&info->packet, + packet_length, batman_if, dstaddr); + + return; + +out: spin_unlock_irqrestore(&orig_hash_lock, flags); } @@ -502,17 +524,18 @@ static void send_vis_packets(struct work_struct *work) struct vis_info *info, *temp; unsigned long flags; - spin_lock_irqsave(&vis_hash_lock, flags); purge_vis_packets(); if (generate_vis_packet() == 0) /* schedule if generation was successful */ list_add_tail(&my_vis_info->send_list, &send_list); + spin_lock_irqsave(&vis_hash_lock, flags); list_for_each_entry_safe(info, temp, &send_list, send_list) { list_del_init(&info->send_list); send_vis_packet(info); } + spin_unlock_irqrestore(&vis_hash_lock, flags); start_vis_timer(); }