rt2x00: Reduce window of a queue's tx lock.
authorGertjan van Wingerde <gwingerde@gmail.com>
Wed, 6 Jul 2011 20:57:37 +0000 (22:57 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 7 Jul 2011 17:20:58 +0000 (13:20 -0400)
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 <gwingerde@gmail.com>
Acked-by: Helmut Schaa <helmut.schaa@googlemail.com>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/rt2x00/rt2x00queue.c

index a70e700..29edb9f 100644 (file)
@@ -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