From patchwork Wed Jul 11 07:22:48 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: alex.bluesman.smirnov@gmail.com X-Patchwork-Id: 170382 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 884392C0080 for ; Wed, 11 Jul 2012 17:27:16 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932287Ab2GKH1L (ORCPT ); Wed, 11 Jul 2012 03:27:11 -0400 Received: from mail-wg0-f44.google.com ([74.125.82.44]:32780 "EHLO mail-wg0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932078Ab2GKH1J (ORCPT ); Wed, 11 Jul 2012 03:27:09 -0400 Received: by mail-wg0-f44.google.com with SMTP id dr13so745049wgb.1 for ; Wed, 11 Jul 2012 00:27:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=X2C3oM3wCuLON65MBw5tNRsMLnaaE21wFp6RMtFGV7g=; b=qy6GEUiP/En8sBNdT/8SMRjKFK6NpYeKvRYhCMiKL7Nsi7m8wqS5x8uSHrq9eV/LRU 7TLaN4/hpn1vROCsBTF2U9VRKSi4RRdDlaEClXWi1sO2hYnOe/WM8vUQdaWtGmlV8HNR puumlEbIT8kajvtv7VvUeH1jQ7huA89Gu3iKE9PGyhelwLu53BYD3hUXW7vvv4ZHgBBx 43XVm/q0BFTaVyg0Q2vZl0Hr8aqwo5CyXRZuuQq5ba2/l8Jrup4gMhsSHiU/4WDkzwBq fvjwvGS+EgxklPll9bhHDLvuMggquUNIZUvjQlZb4au6EjBAYD89XkxToZn/ijkg+CM+ JPSQ== Received: by 10.180.78.99 with SMTP id a3mr44608226wix.15.1341991628577; Wed, 11 Jul 2012 00:27:08 -0700 (PDT) Received: from localhost.localdomain ([91.213.169.4]) by mx.google.com with ESMTPS id t7sm3040238wix.6.2012.07.11.00.27.06 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 11 Jul 2012 00:27:08 -0700 (PDT) From: Alexander Smirnov To: davem@davemloft.net, eric.dumazet@gmail.com Cc: netdev@vger.kernel.org, Alexander Smirnov Subject: [PATCH net-next v2 7/7] 6lowpan: rework fragment-deleting routine Date: Wed, 11 Jul 2012 11:22:48 +0400 Message-Id: <1341991368-11800-8-git-send-email-alex.bluesman.smirnov@gmail.com> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <1341991368-11800-1-git-send-email-alex.bluesman.smirnov@gmail.com> References: <1341991368-11800-1-git-send-email-alex.bluesman.smirnov@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 6lowpan module starts collecting incomming frames and fragments right after lowpan_module_init() therefor it will be better to clean unfinished fragments in lowpan_cleanup_module() function instead of doing it when link goes down. Changed spinlocks type to prevent deadlock with expired timer event and removed unused one. Signed-off-by: Alexander Smirnov --- net/ieee802154/6lowpan.c | 39 ++++++++++++++++++++------------------- 1 files changed, 20 insertions(+), 19 deletions(-) diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c index 2e790fb..6871ec1 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c @@ -113,7 +113,6 @@ struct lowpan_dev_record { struct lowpan_fragment { struct sk_buff *skb; /* skb to be assembled */ - spinlock_t lock; /* concurency lock */ u16 length; /* length to be assemled */ u32 bytes_rcv; /* bytes received */ u16 tag; /* current fragment tag */ @@ -637,10 +636,7 @@ static void lowpan_fragment_timer_expired(unsigned long entry_addr) pr_debug("timer expired for frame with tag %d\n", entry->tag); - spin_lock(&flist_lock); list_del(&entry->list); - spin_unlock(&flist_lock); - dev_kfree_skb(entry->skb); kfree(entry); } @@ -727,7 +723,7 @@ lowpan_process_data(struct sk_buff *skb) * check if frame assembling with the same tag is * already in progress */ - spin_lock(&flist_lock); + spin_lock_bh(&flist_lock); list_for_each_entry(frame, &lowpan_fragments, list) if (frame->tag == tag) { @@ -761,9 +757,9 @@ lowpan_process_data(struct sk_buff *skb) if ((frame->bytes_rcv == frame->length) && frame->timer.expires > jiffies) { /* if timer haven't expired - first of all delete it */ - del_timer(&frame->timer); + del_timer_sync(&frame->timer); list_del(&frame->list); - spin_unlock(&flist_lock); + spin_unlock_bh(&flist_lock); dev_kfree_skb(skb); skb = frame->skb; @@ -774,7 +770,7 @@ lowpan_process_data(struct sk_buff *skb) break; } - spin_unlock(&flist_lock); + spin_unlock_bh(&flist_lock); return kfree_skb(skb), 0; } @@ -929,7 +925,7 @@ lowpan_process_data(struct sk_buff *skb) return lowpan_skb_deliver(skb, &hdr); unlock_and_drop: - spin_unlock(&flist_lock); + spin_unlock_bh(&flist_lock); drop: kfree_skb(skb); return -EINVAL; @@ -1196,19 +1192,9 @@ static void lowpan_dellink(struct net_device *dev, struct list_head *head) struct lowpan_dev_info *lowpan_dev = lowpan_dev_info(dev); struct net_device *real_dev = lowpan_dev->real_dev; struct lowpan_dev_record *entry, *tmp; - struct lowpan_fragment *frame, *tframe; ASSERT_RTNL(); - spin_lock(&flist_lock); - list_for_each_entry_safe(frame, tframe, &lowpan_fragments, list) { - del_timer(&frame->timer); - list_del(&frame->list); - dev_kfree_skb(frame->skb); - kfree(frame); - } - spin_unlock(&flist_lock); - mutex_lock(&lowpan_dev_info(dev)->dev_list_mtx); list_for_each_entry_safe(entry, tmp, &lowpan_devices, list) { if (entry->ldev == dev) { @@ -1264,9 +1250,24 @@ out: static void __exit lowpan_cleanup_module(void) { + struct lowpan_fragment *frame, *tframe; + lowpan_netlink_fini(); dev_remove_pack(&lowpan_packet_type); + + /* Now 6lowpan packet_type is removed, so no new fragments are + * expected on RX, therefore that's the time to clean incomplete + * fragments. + */ + spin_lock_bh(&flist_lock); + list_for_each_entry_safe(frame, tframe, &lowpan_fragments, list) { + del_timer_sync(&frame->timer); + list_del(&frame->list); + dev_kfree_skb(frame->skb); + kfree(frame); + } + spin_unlock_bh(&flist_lock); } module_init(lowpan_init_module);