[svn-commits] sruffell: branch linux/sruffell/dahdi-linux-chainedvb r7326 - /linux/team/sru...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Oct 2 16:42:39 CDT 2009


Author: sruffell
Date: Fri Oct  2 16:42:28 2009
New Revision: 7326

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=7326
Log:
wip: Working on fixing softunderruns.

Since we're racing against the hardware, we cannot guarantee that we won't get
to a place where the hardware has completed a packet that it was in process on
that we tried to race past.

Modified:
    linux/team/sruffell/dahdi-linux-chainedvb/drivers/dahdi/voicebus/voicebus.c

Modified: linux/team/sruffell/dahdi-linux-chainedvb/drivers/dahdi/voicebus/voicebus.c
URL: http://svnview.digium.com/svn/dahdi/linux/team/sruffell/dahdi-linux-chainedvb/drivers/dahdi/voicebus/voicebus.c?view=diff&rev=7326&r1=7325&r2=7326
==============================================================================
--- linux/team/sruffell/dahdi-linux-chainedvb/drivers/dahdi/voicebus/voicebus.c (original)
+++ linux/team/sruffell/dahdi-linux-chainedvb/drivers/dahdi/voicebus/voicebus.c Fri Oct  2 16:42:28 2009
@@ -808,6 +808,18 @@
 		return -EFAULT;
 	}
 
+#if 0
+	/* If we're on the idle buffer, but it isn't owned, we're in a
+	 * softunderrun condition that wasn't handled.
+	 */
+	if (unlikely(!OWNED(d->desc))) {
+		if (printk_ratelimit())
+			dev_err(&vb->pdev->dev, "tx descriptor overrun.\n");
+		voicebus_free(vb, vbb);
+		return -EFAULT;
+	}
+#endif
+
 	dl->tail = get_next_descriptor(dl, d);
 	d->pending = vbb;
 	d->desc->buffer2 = dl->tail->dma_addr;
@@ -910,13 +922,7 @@
 static bool vb_check_softunderrun(const struct voicebus *vb)
 {
 	const struct voicebus_chained_descriptor *const d = vb->txd.head;
-	if ((d->desc->buffer1 == vb->idle_vbb_dma_addr) && !OWNED(d->desc)) {
-		dev_dbg(&vb->pdev->dev, "UNDERRUN desc: %p buffer1: %08x idle: %08x\n",
-			d->desc, d->desc->buffer1, (u32)vb->idle_vbb_dma_addr);
-		return true;
-	} else {
-		return false;
-	}
+	return ((d->desc->buffer1 == vb->idle_vbb_dma_addr) && !OWNED(d->desc));
 }
 
 /**
@@ -945,13 +951,12 @@
 		++count;
 	}
 
-	if (debug)
-		dev_info(&vb->pdev->dev, "Behind by %d descriptors.\n", count);
-
-	count = 8;
+	dev_info(&vb->pdev->dev, "Behind by %d descriptors.\n", count);
+
+	count = 3;
 	while (--count) {
 		next = get_next_descriptor(dl, next);
-		/* SET_OWNED(next->desc); */ /* !!! this shouldn't be necessary */
+		SET_OWNED(next->desc); /* !!! this shouldn't be necessary */
 	}
 
 	vb->txd.tail = next;
@@ -1319,6 +1324,7 @@
 	}
 }
 
+static void *vbb_stash[DLIST_SIZE];
 /*!
  * \brief Actually process the completed transmit and receive buffers.
  *
@@ -1330,29 +1336,43 @@
 vb_deferred(struct voicebus *vb)
 {
 	void *vbb;
+	int buffer_count;
+	int i;
+	const struct device *const dev = &vb->pdev->dev;
 
 	int underrun = test_bit(TX_UNDERRUN, &vb->flags);
-	int limit = DLIST_SIZE;
 
 	start_vb_deferred(vb);
 
 	if (debug)
-		dev_dbg(&vb->pdev->dev, "Entering %s\n", __func__);
+		dev_dbg(dev, "Entering %s\n", __func__);
+
+	buffer_count = 0;
 	/* Always handle the transmit buffers first. */
 	while ((vbb = vb_get_completed_txb(vb))) {
+		vbb_stash[buffer_count] = vbb;
+		++buffer_count;
+	}
+
+	if (buffer_count > 2)
+		dev_info(dev, "Stashed %d buffers\n", buffer_count);
+
+	if (unlikely(vb_check_softunderrun(vb))) {
+		vb_recover_tx_descriptor_list(vb);
+		__vb_increase_latency(vb, 1);
+	}
+
+	for (i = 0; i < buffer_count; ++i) {
 		/* After the upper layer is done with the completed buffer, it
 		 * will call voicebus_transmit to add it back to the descriptor
 		 * ring itself. */
-		vb->handle_transmit(vbb, vb->context);
-		if (!(--limit))
-			break;
-	}
-
-	if (unlikely(vb_check_softunderrun(vb)))
-		vb_recover_tx_descriptor_list(vb);
-
+		vb->handle_transmit(vbb_stash[i], vb->context);
+	}
+
+	/* This is a hard underrun.  I.e., the hardware was able to completely
+	 * drain the transmit descriptor ring which means that interrupts were
+	 * locked for DLIST_SIZE ms. */
 	if (unlikely(underrun)) {
-		__vb_increase_latency(vb, 1);
 		vb_rx_demand_poll(vb);
 		vb_tx_demand_poll(vb);
 		clear_bit(TX_UNDERRUN, &vb->flags);




More information about the svn-commits mailing list