All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2] b43: avoid packet losses in the dma worker code.
@ 2011-12-15 16:33 ` francesco.gringoli at ing.unibs.it
  0 siblings, 0 replies; 4+ messages in thread
From: francesco.gringoli @ 2011-12-15 16:33 UTC (permalink / raw)
  To: m, linville, linux-wireless
  Cc: b43-dev, michele.orru, riccardo.paolillo, francesco.gringoli

This patch addresses a bug in the dma worker code that keeps draining
packets even when the hardware queues are full. In such cases packets
can not be passed down to the device and are erroneusly dropped by the
code.

This problem was already discussed here

http://www.mail-archive.com/b43-dev@lists.infradead.org/msg01413.html

and acknowledged by Michael.

The patch also introduces separate workers for each hardware queue
and dedicated buffers where storing packets from mac80211 before sending
them down to the hardware. Using different workers let bandwidth be
perfectly shared among the queues according to contention window parameters
defined at the air interface (EDCA settings).

Number of hardware queues is now defined in b43.h (B43_QOS_QUEUE_NUM).

Acknowledgements to Riccardo Paolillo <riccardo.paolillo@gmail.com> and
Michele Orru <michele.orru@hotmail.it>

Signed-off-by: Francesco Gringoli <francesco.gringoli@ing.unibs.it>
---

Index: wireless-testing-new/drivers/net/wireless/b43/b43.h
===================================================================
--- wireless-testing-new.orig/drivers/net/wireless/b43/b43.h	2011-12-12 16:15:45.134475457 +0100
+++ wireless-testing-new/drivers/net/wireless/b43/b43.h	2011-12-15 16:26:43.444536723 +0100
@@ -667,6 +667,7 @@
 };
 
 /* SHM offsets to the QOS data structures for the 4 different queues. */
+#define B43_QOS_QUEUE_NUM	4
 #define B43_QOS_PARAMS(queue)	(B43_SHM_SH_EDCFQ + \
 				 (B43_NR_QOSPARAMS * sizeof(u16) * (queue)))
 #define B43_QOS_BACKGROUND	B43_QOS_PARAMS(0)
@@ -845,6 +846,14 @@
 #endif
 };
 
+/* Multi-Queue work struct */
+struct b43_mt_work {
+	/* Work associated to the queue */
+	struct work_struct mt_work;
+	/* Queue index */
+	int work_queue_id;
+};
+
 /* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
 struct b43_wl {
 	/* Pointer to the active wireless device on this chip */
@@ -904,17 +913,21 @@
 	struct work_struct beacon_update_trigger;
 
 	/* The current QOS parameters for the 4 queues. */
-	struct b43_qos_params qos_params[4];
+	struct b43_qos_params qos_params[B43_QOS_QUEUE_NUM];
 
 	/* Work for adjustment of the transmission power.
 	 * This is scheduled when we determine that the actual TX output
 	 * power doesn't match what we want. */
 	struct work_struct txpower_adjust_work;
 
-	/* Packet transmit work */
-	struct work_struct tx_work;
+	/* Packet transmit work. */
+	struct b43_mt_work tx_work[B43_QOS_QUEUE_NUM];
+
 	/* Queue of packets to be transmitted. */
-	struct sk_buff_head tx_queue;
+	struct sk_buff_head tx_queue[B43_QOS_QUEUE_NUM];
+
+	/* Flag that implement the queues stopping. */
+	bool tx_queue_stopped[B43_QOS_QUEUE_NUM];
 
 	/* The device LEDs. */
 	struct b43_leds leds;
Index: wireless-testing-new/drivers/net/wireless/b43/main.c
===================================================================
--- wireless-testing-new.orig/drivers/net/wireless/b43/main.c	2011-12-12 16:15:45.134475457 +0100
+++ wireless-testing-new/drivers/net/wireless/b43/main.c	2011-12-15 16:29:26.154480397 +0100
@@ -3375,9 +3375,13 @@
 
 static void b43_tx_work(struct work_struct *work)
 {
-	struct b43_wl *wl = container_of(work, struct b43_wl, tx_work);
+	struct b43_mt_work *queue_work = container_of(work, struct b43_mt_work,
+						      mt_work);
+	struct b43_wl *wl = container_of(queue_work, struct b43_wl,
+					 tx_work[queue_work->work_queue_id]);
 	struct b43_wldev *dev;
 	struct sk_buff *skb;
+	int queue_num = queue_work->work_queue_id;
 	int err = 0;
 
 	mutex_lock(&wl->mutex);
@@ -3387,17 +3391,29 @@
 		return;
 	}
 
-	while (skb_queue_len(&wl->tx_queue)) {
-		skb = skb_dequeue(&wl->tx_queue);
+	while (skb_queue_len(&wl->tx_queue[queue_num])) {
+		skb = skb_dequeue(&wl->tx_queue[queue_num]);
 
 		if (b43_using_pio_transfers(dev))
 			err = b43_pio_tx(dev, skb);
 		else
 			err = b43_dma_tx(dev, skb);
+
+		if (err == -ENOSPC) {
+			wl->tx_queue_stopped[queue_num] = 1;
+			ieee80211_stop_queue(wl->hw,
+					     skb_get_queue_mapping(skb));
+			skb_queue_head(&wl->tx_queue[queue_num], skb);
+			break;
+		}
 		if (unlikely(err))
 			dev_kfree_skb(skb); /* Drop it */
+		err = 0;
 	}
 
+	if (!err)
+		wl->tx_queue_stopped[queue_num] = 0;
+
 #if B43_DEBUG
 	dev->tx_count++;
 #endif
@@ -3416,8 +3432,13 @@
 	}
 	B43_WARN_ON(skb_shinfo(skb)->nr_frags);
 
-	skb_queue_tail(&wl->tx_queue, skb);
-	ieee80211_queue_work(wl->hw, &wl->tx_work);
+	skb_queue_tail(&wl->tx_queue[skb->queue_mapping], skb);
+	if (!wl->tx_queue_stopped[skb->queue_mapping]) {
+		ieee80211_queue_work(wl->hw,
+				     &wl->tx_work[skb->queue_mapping].mt_work);
+	} else {
+		ieee80211_stop_queue(wl->hw, skb->queue_mapping);
+	}
 }
 
 static void b43_qos_params_upload(struct b43_wldev *dev,
@@ -4147,6 +4168,7 @@
 	struct b43_wl *wl;
 	struct b43_wldev *orig_dev;
 	u32 mask;
+	int queue_num;
 
 	if (!dev)
 		return NULL;
@@ -4158,7 +4180,10 @@
 	/* Cancel work. Unlock to avoid deadlocks. */
 	mutex_unlock(&wl->mutex);
 	cancel_delayed_work_sync(&dev->periodic_work);
-	cancel_work_sync(&wl->tx_work);
+
+	for (queue_num = 0; queue_num < B43_QOS_QUEUE_NUM; queue_num++)
+		cancel_work_sync(&wl->tx_work[queue_num].mt_work);
+
 	mutex_lock(&wl->mutex);
 	dev = wl->current_dev;
 	if (!dev || b43_status(dev) < B43_STAT_STARTED) {
@@ -4199,9 +4224,11 @@
 	mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
 	B43_WARN_ON(mask != 0xFFFFFFFF && mask);
 
-	/* Drain the TX queue */
-	while (skb_queue_len(&wl->tx_queue))
-		dev_kfree_skb(skb_dequeue(&wl->tx_queue));
+	/* Drain each TX queue */
+	for (queue_num = 0; queue_num < B43_QOS_QUEUE_NUM; queue_num++) {
+		while (skb_queue_len(&wl->tx_queue[queue_num]))
+			dev_kfree_skb(skb_dequeue(&wl->tx_queue[queue_num]));
+	}
 
 	b43_mac_suspend(dev);
 	b43_leds_exit(dev);
@@ -5245,6 +5272,7 @@
 	struct ieee80211_hw *hw;
 	struct b43_wl *wl;
 	char chip_name[6];
+	int queue_num;
 
 	hw = ieee80211_alloc_hw(sizeof(*wl), &b43_hw_ops);
 	if (!hw) {
@@ -5264,7 +5292,7 @@
 		BIT(NL80211_IFTYPE_WDS) |
 		BIT(NL80211_IFTYPE_ADHOC);
 
-	hw->queues = modparam_qos ? 4 : 1;
+	hw->queues = modparam_qos ? B43_QOS_QUEUE_NUM : 1;
 	wl->mac80211_initially_registered_queues = hw->queues;
 	hw->max_rates = 2;
 	SET_IEEE80211_DEV(hw, dev->dev);
@@ -5280,8 +5308,14 @@
 	INIT_LIST_HEAD(&wl->devlist);
 	INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work);
 	INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work);
-	INIT_WORK(&wl->tx_work, b43_tx_work);
-	skb_queue_head_init(&wl->tx_queue);
+
+	/* Initialize the work for each queues  */
+	for (queue_num = 0; queue_num < B43_QOS_QUEUE_NUM; queue_num++) {
+		INIT_WORK(&wl->tx_work[queue_num].mt_work, b43_tx_work);
+		wl->tx_work[queue_num].work_queue_id = queue_num;
+		skb_queue_head_init(&wl->tx_queue[queue_num]);
+		wl->tx_queue_stopped[queue_num] = 0;
+	}
 
 	snprintf(chip_name, ARRAY_SIZE(chip_name),
 		 (dev->chip_id > 0x9999) ? "%d" : "%04X", dev->chip_id);
Index: wireless-testing-new/drivers/net/wireless/b43/dma.c
===================================================================
--- wireless-testing-new.orig/drivers/net/wireless/b43/dma.c	2011-12-12 16:15:45.134475457 +0100
+++ wireless-testing-new/drivers/net/wireless/b43/dma.c	2011-12-15 16:24:47.134504245 +0100
@@ -1465,7 +1465,9 @@
 	if ((free_slots(ring) < TX_SLOTS_PER_FRAME) ||
 	    should_inject_overflow(ring)) {
 		/* This TX ring is full. */
-		ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
+		unsigned int skb_mapping = skb_get_queue_mapping(skb);
+		ieee80211_stop_queue(dev->wl->hw, skb_mapping);
+		dev->wl->tx_queue_stopped[skb_mapping] = 1;
 		ring->stopped = 1;
 		if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
 			b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index);
@@ -1584,12 +1586,22 @@
 	}
 	if (ring->stopped) {
 		B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME);
-		ieee80211_wake_queue(dev->wl->hw, ring->queue_prio);
 		ring->stopped = 0;
+	}
+
+	if (dev->wl->tx_queue_stopped[ring->queue_prio]) {
+		dev->wl->tx_queue_stopped[ring->queue_prio] = 0;
+	} else {
+		/* If the driver queue is running wake the corresponding
+		 * mac80211 queue. */
+		ieee80211_wake_queue(dev->wl->hw, ring->queue_prio);
 		if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
 			b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index);
 		}
 	}
+	/* Add work to the queue */
+	ieee80211_queue_work(dev->wl->hw,
+			     &dev->wl->tx_work[ring->queue_prio].mt_work);
 }
 
 static void dma_rx(struct b43_dmaring *ring, int *slot)

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH V2] b43: avoid packet losses in the dma worker code.
@ 2011-12-15 16:33 ` francesco.gringoli at ing.unibs.it
  0 siblings, 0 replies; 4+ messages in thread
From: francesco.gringoli at ing.unibs.it @ 2011-12-15 16:33 UTC (permalink / raw)
  To: m, linville, linux-wireless
  Cc: b43-dev, michele.orru, riccardo.paolillo, francesco.gringoli

This patch addresses a bug in the dma worker code that keeps draining
packets even when the hardware queues are full. In such cases packets
can not be passed down to the device and are erroneusly dropped by the
code.

This problem was already discussed here

http://www.mail-archive.com/b43-dev at lists.infradead.org/msg01413.html

and acknowledged by Michael.

The patch also introduces separate workers for each hardware queue
and dedicated buffers where storing packets from mac80211 before sending
them down to the hardware. Using different workers let bandwidth be
perfectly shared among the queues according to contention window parameters
defined at the air interface (EDCA settings).

Number of hardware queues is now defined in b43.h (B43_QOS_QUEUE_NUM).

Acknowledgements to Riccardo Paolillo <riccardo.paolillo@gmail.com> and
Michele Orru <michele.orru@hotmail.it>

Signed-off-by: Francesco Gringoli <francesco.gringoli@ing.unibs.it>
---

Index: wireless-testing-new/drivers/net/wireless/b43/b43.h
===================================================================
--- wireless-testing-new.orig/drivers/net/wireless/b43/b43.h	2011-12-12 16:15:45.134475457 +0100
+++ wireless-testing-new/drivers/net/wireless/b43/b43.h	2011-12-15 16:26:43.444536723 +0100
@@ -667,6 +667,7 @@
 };
 
 /* SHM offsets to the QOS data structures for the 4 different queues. */
+#define B43_QOS_QUEUE_NUM	4
 #define B43_QOS_PARAMS(queue)	(B43_SHM_SH_EDCFQ + \
 				 (B43_NR_QOSPARAMS * sizeof(u16) * (queue)))
 #define B43_QOS_BACKGROUND	B43_QOS_PARAMS(0)
@@ -845,6 +846,14 @@
 #endif
 };
 
+/* Multi-Queue work struct */
+struct b43_mt_work {
+	/* Work associated to the queue */
+	struct work_struct mt_work;
+	/* Queue index */
+	int work_queue_id;
+};
+
 /* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
 struct b43_wl {
 	/* Pointer to the active wireless device on this chip */
@@ -904,17 +913,21 @@
 	struct work_struct beacon_update_trigger;
 
 	/* The current QOS parameters for the 4 queues. */
-	struct b43_qos_params qos_params[4];
+	struct b43_qos_params qos_params[B43_QOS_QUEUE_NUM];
 
 	/* Work for adjustment of the transmission power.
 	 * This is scheduled when we determine that the actual TX output
 	 * power doesn't match what we want. */
 	struct work_struct txpower_adjust_work;
 
-	/* Packet transmit work */
-	struct work_struct tx_work;
+	/* Packet transmit work. */
+	struct b43_mt_work tx_work[B43_QOS_QUEUE_NUM];
+
 	/* Queue of packets to be transmitted. */
-	struct sk_buff_head tx_queue;
+	struct sk_buff_head tx_queue[B43_QOS_QUEUE_NUM];
+
+	/* Flag that implement the queues stopping. */
+	bool tx_queue_stopped[B43_QOS_QUEUE_NUM];
 
 	/* The device LEDs. */
 	struct b43_leds leds;
Index: wireless-testing-new/drivers/net/wireless/b43/main.c
===================================================================
--- wireless-testing-new.orig/drivers/net/wireless/b43/main.c	2011-12-12 16:15:45.134475457 +0100
+++ wireless-testing-new/drivers/net/wireless/b43/main.c	2011-12-15 16:29:26.154480397 +0100
@@ -3375,9 +3375,13 @@
 
 static void b43_tx_work(struct work_struct *work)
 {
-	struct b43_wl *wl = container_of(work, struct b43_wl, tx_work);
+	struct b43_mt_work *queue_work = container_of(work, struct b43_mt_work,
+						      mt_work);
+	struct b43_wl *wl = container_of(queue_work, struct b43_wl,
+					 tx_work[queue_work->work_queue_id]);
 	struct b43_wldev *dev;
 	struct sk_buff *skb;
+	int queue_num = queue_work->work_queue_id;
 	int err = 0;
 
 	mutex_lock(&wl->mutex);
@@ -3387,17 +3391,29 @@
 		return;
 	}
 
-	while (skb_queue_len(&wl->tx_queue)) {
-		skb = skb_dequeue(&wl->tx_queue);
+	while (skb_queue_len(&wl->tx_queue[queue_num])) {
+		skb = skb_dequeue(&wl->tx_queue[queue_num]);
 
 		if (b43_using_pio_transfers(dev))
 			err = b43_pio_tx(dev, skb);
 		else
 			err = b43_dma_tx(dev, skb);
+
+		if (err == -ENOSPC) {
+			wl->tx_queue_stopped[queue_num] = 1;
+			ieee80211_stop_queue(wl->hw,
+					     skb_get_queue_mapping(skb));
+			skb_queue_head(&wl->tx_queue[queue_num], skb);
+			break;
+		}
 		if (unlikely(err))
 			dev_kfree_skb(skb); /* Drop it */
+		err = 0;
 	}
 
+	if (!err)
+		wl->tx_queue_stopped[queue_num] = 0;
+
 #if B43_DEBUG
 	dev->tx_count++;
 #endif
@@ -3416,8 +3432,13 @@
 	}
 	B43_WARN_ON(skb_shinfo(skb)->nr_frags);
 
-	skb_queue_tail(&wl->tx_queue, skb);
-	ieee80211_queue_work(wl->hw, &wl->tx_work);
+	skb_queue_tail(&wl->tx_queue[skb->queue_mapping], skb);
+	if (!wl->tx_queue_stopped[skb->queue_mapping]) {
+		ieee80211_queue_work(wl->hw,
+				     &wl->tx_work[skb->queue_mapping].mt_work);
+	} else {
+		ieee80211_stop_queue(wl->hw, skb->queue_mapping);
+	}
 }
 
 static void b43_qos_params_upload(struct b43_wldev *dev,
@@ -4147,6 +4168,7 @@
 	struct b43_wl *wl;
 	struct b43_wldev *orig_dev;
 	u32 mask;
+	int queue_num;
 
 	if (!dev)
 		return NULL;
@@ -4158,7 +4180,10 @@
 	/* Cancel work. Unlock to avoid deadlocks. */
 	mutex_unlock(&wl->mutex);
 	cancel_delayed_work_sync(&dev->periodic_work);
-	cancel_work_sync(&wl->tx_work);
+
+	for (queue_num = 0; queue_num < B43_QOS_QUEUE_NUM; queue_num++)
+		cancel_work_sync(&wl->tx_work[queue_num].mt_work);
+
 	mutex_lock(&wl->mutex);
 	dev = wl->current_dev;
 	if (!dev || b43_status(dev) < B43_STAT_STARTED) {
@@ -4199,9 +4224,11 @@
 	mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
 	B43_WARN_ON(mask != 0xFFFFFFFF && mask);
 
-	/* Drain the TX queue */
-	while (skb_queue_len(&wl->tx_queue))
-		dev_kfree_skb(skb_dequeue(&wl->tx_queue));
+	/* Drain each TX queue */
+	for (queue_num = 0; queue_num < B43_QOS_QUEUE_NUM; queue_num++) {
+		while (skb_queue_len(&wl->tx_queue[queue_num]))
+			dev_kfree_skb(skb_dequeue(&wl->tx_queue[queue_num]));
+	}
 
 	b43_mac_suspend(dev);
 	b43_leds_exit(dev);
@@ -5245,6 +5272,7 @@
 	struct ieee80211_hw *hw;
 	struct b43_wl *wl;
 	char chip_name[6];
+	int queue_num;
 
 	hw = ieee80211_alloc_hw(sizeof(*wl), &b43_hw_ops);
 	if (!hw) {
@@ -5264,7 +5292,7 @@
 		BIT(NL80211_IFTYPE_WDS) |
 		BIT(NL80211_IFTYPE_ADHOC);
 
-	hw->queues = modparam_qos ? 4 : 1;
+	hw->queues = modparam_qos ? B43_QOS_QUEUE_NUM : 1;
 	wl->mac80211_initially_registered_queues = hw->queues;
 	hw->max_rates = 2;
 	SET_IEEE80211_DEV(hw, dev->dev);
@@ -5280,8 +5308,14 @@
 	INIT_LIST_HEAD(&wl->devlist);
 	INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work);
 	INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work);
-	INIT_WORK(&wl->tx_work, b43_tx_work);
-	skb_queue_head_init(&wl->tx_queue);
+
+	/* Initialize the work for each queues  */
+	for (queue_num = 0; queue_num < B43_QOS_QUEUE_NUM; queue_num++) {
+		INIT_WORK(&wl->tx_work[queue_num].mt_work, b43_tx_work);
+		wl->tx_work[queue_num].work_queue_id = queue_num;
+		skb_queue_head_init(&wl->tx_queue[queue_num]);
+		wl->tx_queue_stopped[queue_num] = 0;
+	}
 
 	snprintf(chip_name, ARRAY_SIZE(chip_name),
 		 (dev->chip_id > 0x9999) ? "%d" : "%04X", dev->chip_id);
Index: wireless-testing-new/drivers/net/wireless/b43/dma.c
===================================================================
--- wireless-testing-new.orig/drivers/net/wireless/b43/dma.c	2011-12-12 16:15:45.134475457 +0100
+++ wireless-testing-new/drivers/net/wireless/b43/dma.c	2011-12-15 16:24:47.134504245 +0100
@@ -1465,7 +1465,9 @@
 	if ((free_slots(ring) < TX_SLOTS_PER_FRAME) ||
 	    should_inject_overflow(ring)) {
 		/* This TX ring is full. */
-		ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
+		unsigned int skb_mapping = skb_get_queue_mapping(skb);
+		ieee80211_stop_queue(dev->wl->hw, skb_mapping);
+		dev->wl->tx_queue_stopped[skb_mapping] = 1;
 		ring->stopped = 1;
 		if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
 			b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index);
@@ -1584,12 +1586,22 @@
 	}
 	if (ring->stopped) {
 		B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME);
-		ieee80211_wake_queue(dev->wl->hw, ring->queue_prio);
 		ring->stopped = 0;
+	}
+
+	if (dev->wl->tx_queue_stopped[ring->queue_prio]) {
+		dev->wl->tx_queue_stopped[ring->queue_prio] = 0;
+	} else {
+		/* If the driver queue is running wake the corresponding
+		 * mac80211 queue. */
+		ieee80211_wake_queue(dev->wl->hw, ring->queue_prio);
 		if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
 			b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index);
 		}
 	}
+	/* Add work to the queue */
+	ieee80211_queue_work(dev->wl->hw,
+			     &dev->wl->tx_work[ring->queue_prio].mt_work);
 }
 
 static void dma_rx(struct b43_dmaring *ring, int *slot)

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH V2] b43: avoid packet losses in the dma worker code.
  2011-12-15 16:33 ` francesco.gringoli at ing.unibs.it
@ 2011-12-16  6:31   ` Rafał Miłecki
  -1 siblings, 0 replies; 4+ messages in thread
From: Rafał Miłecki @ 2011-12-16  6:31 UTC (permalink / raw)
  To: francesco.gringoli
  Cc: m, linville, linux-wireless, b43-dev, michele.orru, riccardo.paolillo

2011/12/15  <francesco.gringoli@ing.unibs.it>:
> This patch addresses a bug in the dma worker code that keeps draining
> packets even when the hardware queues are full. In such cases packets
> can not be passed down to the device and are erroneusly dropped by the
> code.
>
> This problem was already discussed here
>
> http://www.mail-archive.com/b43-dev@lists.infradead.org/msg01413.html
>
> and acknowledged by Michael.
>
> The patch also introduces separate workers for each hardware queue
> and dedicated buffers where storing packets from mac80211 before sending
> them down to the hardware. Using different workers let bandwidth be
> perfectly shared among the queues according to contention window parameters
> defined at the air interface (EDCA settings).
>
> Number of hardware queues is now defined in b43.h (B43_QOS_QUEUE_NUM).

Thanks for your changes Francesco. Funny, checkpatch doesn't detect
 braces were used for single-line instructions. Generally it looks fine
 :)

 I still would like to take a look at this solution in comparison to
 single worker. So let me repeat me request: do you still have patch
 implementing 1 worker solution? Could you share it?

-- 
Rafał

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH V2] b43: avoid packet losses in the dma worker code.
@ 2011-12-16  6:31   ` Rafał Miłecki
  0 siblings, 0 replies; 4+ messages in thread
From: Rafał Miłecki @ 2011-12-16  6:31 UTC (permalink / raw)
  To: francesco.gringoli
  Cc: m, linville, linux-wireless, b43-dev, michele.orru, riccardo.paolillo

2011/12/15  <francesco.gringoli@ing.unibs.it>:
> This patch addresses a bug in the dma worker code that keeps draining
> packets even when the hardware queues are full. In such cases packets
> can not be passed down to the device and are erroneusly dropped by the
> code.
>
> This problem was already discussed here
>
> http://www.mail-archive.com/b43-dev at lists.infradead.org/msg01413.html
>
> and acknowledged by Michael.
>
> The patch also introduces separate workers for each hardware queue
> and dedicated buffers where storing packets from mac80211 before sending
> them down to the hardware. Using different workers let bandwidth be
> perfectly shared among the queues according to contention window parameters
> defined at the air interface (EDCA settings).
>
> Number of hardware queues is now defined in b43.h (B43_QOS_QUEUE_NUM).

Thanks for your changes Francesco. Funny, checkpatch doesn't detect
 braces were used for single-line instructions. Generally it looks fine
 :)

 I still would like to take a look at this solution in comparison to
 single worker. So let me repeat me request: do you still have patch
 implementing 1 worker solution? Could you share it?

-- 
Rafa?

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2011-12-16  6:31 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-15 16:33 [PATCH V2] b43: avoid packet losses in the dma worker code francesco.gringoli
2011-12-15 16:33 ` francesco.gringoli at ing.unibs.it
2011-12-16  6:31 ` Rafał Miłecki
2011-12-16  6:31   ` Rafał Miłecki

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.