diff options
author | Gertjan van Wingerde <gwingerde@gmail.com> | 2011-07-06 16:57:37 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-07-07 13:20:58 -0400 |
commit | 128f8f773d77d41a7dbcaf5d36325a0f4e7955cd (patch) | |
tree | f514ad12fb4fc930797e27b4874c846c55989b23 /drivers/net/wireless/rt2x00 | |
parent | 77b5621bac4a56b83b9081f48d4e7d1accdde400 (diff) |
rt2x00: Reduce window of a queue's tx lock.
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>
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r-- | 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 a70e7000b528..29edb9fbe6f1 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, | |||
565 | u8 rate_idx, rate_flags; | 565 | u8 rate_idx, rate_flags; |
566 | int ret = 0; | 566 | int ret = 0; |
567 | 567 | ||
568 | spin_lock(&queue->tx_lock); | ||
569 | |||
570 | entry = rt2x00queue_get_entry(queue, Q_INDEX); | ||
571 | |||
572 | if (unlikely(rt2x00queue_full(queue))) { | ||
573 | ERROR(queue->rt2x00dev, | ||
574 | "Dropping frame due to full tx queue %d.\n", queue->qid); | ||
575 | ret = -ENOBUFS; | ||
576 | goto out; | ||
577 | } | ||
578 | |||
579 | if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, | ||
580 | &entry->flags))) { | ||
581 | ERROR(queue->rt2x00dev, | ||
582 | "Arrived at non-free entry in the non-full queue %d.\n" | ||
583 | "Please file bug report to %s.\n", | ||
584 | queue->qid, DRV_PROJECT); | ||
585 | ret = -EINVAL; | ||
586 | goto out; | ||
587 | } | ||
588 | |||
589 | /* | 568 | /* |
590 | * Copy all TX descriptor information into txdesc, | 569 | * Copy all TX descriptor information into txdesc, |
591 | * after that we are free to use the skb->cb array | 570 | * after that we are free to use the skb->cb array |
592 | * for our information. | 571 | * for our information. |
593 | */ | 572 | */ |
594 | entry->skb = skb; | ||
595 | rt2x00queue_create_tx_descriptor(queue->rt2x00dev, skb, &txdesc); | 573 | rt2x00queue_create_tx_descriptor(queue->rt2x00dev, skb, &txdesc); |
596 | 574 | ||
597 | /* | 575 | /* |
@@ -604,7 +582,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | |||
604 | rate_flags = tx_info->control.rates[0].flags; | 582 | rate_flags = tx_info->control.rates[0].flags; |
605 | skbdesc = get_skb_frame_desc(skb); | 583 | skbdesc = get_skb_frame_desc(skb); |
606 | memset(skbdesc, 0, sizeof(*skbdesc)); | 584 | memset(skbdesc, 0, sizeof(*skbdesc)); |
607 | skbdesc->entry = entry; | ||
608 | skbdesc->tx_rate_idx = rate_idx; | 585 | skbdesc->tx_rate_idx = rate_idx; |
609 | skbdesc->tx_rate_flags = rate_flags; | 586 | skbdesc->tx_rate_flags = rate_flags; |
610 | 587 | ||
@@ -633,9 +610,33 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | |||
633 | * for PCI devices. | 610 | * for PCI devices. |
634 | */ | 611 | */ |
635 | if (test_bit(REQUIRE_L2PAD, &queue->rt2x00dev->cap_flags)) | 612 | if (test_bit(REQUIRE_L2PAD, &queue->rt2x00dev->cap_flags)) |
636 | rt2x00queue_insert_l2pad(entry->skb, txdesc.header_length); | 613 | rt2x00queue_insert_l2pad(skb, txdesc.header_length); |
637 | else if (test_bit(REQUIRE_DMA, &queue->rt2x00dev->cap_flags)) | 614 | else if (test_bit(REQUIRE_DMA, &queue->rt2x00dev->cap_flags)) |
638 | rt2x00queue_align_frame(entry->skb); | 615 | rt2x00queue_align_frame(skb); |
616 | |||
617 | spin_lock(&queue->tx_lock); | ||
618 | |||
619 | if (unlikely(rt2x00queue_full(queue))) { | ||
620 | ERROR(queue->rt2x00dev, | ||
621 | "Dropping frame due to full tx queue %d.\n", queue->qid); | ||
622 | ret = -ENOBUFS; | ||
623 | goto out; | ||
624 | } | ||
625 | |||
626 | entry = rt2x00queue_get_entry(queue, Q_INDEX); | ||
627 | |||
628 | if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, | ||
629 | &entry->flags))) { | ||
630 | ERROR(queue->rt2x00dev, | ||
631 | "Arrived at non-free entry in the non-full queue %d.\n" | ||
632 | "Please file bug report to %s.\n", | ||
633 | queue->qid, DRV_PROJECT); | ||
634 | ret = -EINVAL; | ||
635 | goto out; | ||
636 | } | ||
637 | |||
638 | skbdesc->entry = entry; | ||
639 | entry->skb = skb; | ||
639 | 640 | ||
640 | /* | 641 | /* |
641 | * It could be possible that the queue was corrupted and this | 642 | * It could be possible that the queue was corrupted and this |