From patchwork Wed Jul 6 20:57:37 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivo van Doorn X-Patchwork-Id: 951192 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p66L3Cjn000911 for ; Wed, 6 Jul 2011 21:03:13 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756248Ab1GFVAy (ORCPT ); Wed, 6 Jul 2011 17:00:54 -0400 Received: from mail-ey0-f174.google.com ([209.85.215.174]:43974 "EHLO mail-ey0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756057Ab1GFVAy (ORCPT ); Wed, 6 Jul 2011 17:00:54 -0400 Received: by eyx24 with SMTP id 24so105827eyx.19 for ; Wed, 06 Jul 2011 14:00:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:subject:date:user-agent:cc:references:in-reply-to :mime-version:content-type:content-transfer-encoding:message-id; bh=LAbWCBHEDMjE5diiV8/1ejLUuT68wECLqMEVB9mZO8w=; b=Qfro5kEusGR5iZ+uEA4DVWXSXwoPHWFXmnPN4ZJlQren6ZTPawzVqBU+azT+QKQtpl J0LpNwT74opWhdLp0v+B1bw4vQO72LEpuo+CLyVmcphHeaPdmvolnjbA6M62ukPBcQZF nYqrgu+uOgi4TsNSDwF2ABO+63/P2hJpVYw3M= Received: by 10.213.114.143 with SMTP id e15mr1332672ebq.80.1309986052718; Wed, 06 Jul 2011 14:00:52 -0700 (PDT) Received: from localhost.localdomain (g121037.upc-g.chello.nl [80.57.121.37]) by mx.google.com with ESMTPS id b9sm6469298een.8.2011.07.06.14.00.48 (version=SSLv3 cipher=OTHER); Wed, 06 Jul 2011 14:00:50 -0700 (PDT) From: Ivo van Doorn To: "John W. Linville" Subject: [PATCH 3/6] rt2x00: Reduce window of a queue's tx lock. Date: Wed, 6 Jul 2011 22:57:37 +0200 User-Agent: KMail/1.13.5 (Linux/2.6.32.26-175.fc12.x86_64; KDE/4.4.5; x86_64; ; ) Cc: users@rt2x00.serialmonkey.com, linux-wireless@vger.kernel.org References: <201107062256.25555.IvDoorn@gmail.com> <201107062257.01333.IvDoorn@gmail.com> In-Reply-To: <201107062257.01333.IvDoorn@gmail.com> MIME-Version: 1.0 Message-Id: <201107062257.38435.IvDoorn@gmail.com> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Wed, 06 Jul 2011 21:03:13 +0000 (UTC) From: Gertjan van Wingerde Currently a lot of actions that can be done without the queue's tx lock being held are done inside the locked area. Move them out to have a leaner and meaner code that operates while the tx lock is being held. Signed-off-by: Gertjan van Wingerde Acked-by: Helmut Schaa Signed-off-by: Ivo van Doorn --- drivers/net/wireless/rt2x00/rt2x00queue.c | 51 +++++++++++++++-------------- 1 files changed, 26 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index a70e700..29edb9f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -565,33 +565,11 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, u8 rate_idx, rate_flags; int ret = 0; - spin_lock(&queue->tx_lock); - - entry = rt2x00queue_get_entry(queue, Q_INDEX); - - if (unlikely(rt2x00queue_full(queue))) { - ERROR(queue->rt2x00dev, - "Dropping frame due to full tx queue %d.\n", queue->qid); - ret = -ENOBUFS; - goto out; - } - - if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, - &entry->flags))) { - ERROR(queue->rt2x00dev, - "Arrived at non-free entry in the non-full queue %d.\n" - "Please file bug report to %s.\n", - queue->qid, DRV_PROJECT); - ret = -EINVAL; - goto out; - } - /* * Copy all TX descriptor information into txdesc, * after that we are free to use the skb->cb array * for our information. */ - entry->skb = skb; rt2x00queue_create_tx_descriptor(queue->rt2x00dev, skb, &txdesc); /* @@ -604,7 +582,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, rate_flags = tx_info->control.rates[0].flags; skbdesc = get_skb_frame_desc(skb); memset(skbdesc, 0, sizeof(*skbdesc)); - skbdesc->entry = entry; skbdesc->tx_rate_idx = rate_idx; skbdesc->tx_rate_flags = rate_flags; @@ -633,9 +610,33 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, * for PCI devices. */ if (test_bit(REQUIRE_L2PAD, &queue->rt2x00dev->cap_flags)) - rt2x00queue_insert_l2pad(entry->skb, txdesc.header_length); + rt2x00queue_insert_l2pad(skb, txdesc.header_length); else if (test_bit(REQUIRE_DMA, &queue->rt2x00dev->cap_flags)) - rt2x00queue_align_frame(entry->skb); + rt2x00queue_align_frame(skb); + + spin_lock(&queue->tx_lock); + + if (unlikely(rt2x00queue_full(queue))) { + ERROR(queue->rt2x00dev, + "Dropping frame due to full tx queue %d.\n", queue->qid); + ret = -ENOBUFS; + goto out; + } + + entry = rt2x00queue_get_entry(queue, Q_INDEX); + + if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, + &entry->flags))) { + ERROR(queue->rt2x00dev, + "Arrived at non-free entry in the non-full queue %d.\n" + "Please file bug report to %s.\n", + queue->qid, DRV_PROJECT); + ret = -EINVAL; + goto out; + } + + skbdesc->entry = entry; + entry->skb = skb; /* * It could be possible that the queue was corrupted and this