Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 Aug 2016 14:51:07 +0000 (UTC)
From:      "Conrad E. Meyer" <cem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r304602 - head/sys/dev/ioat
Message-ID:  <201608221451.u7MEp7li072575@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cem
Date: Mon Aug 22 14:51:07 2016
New Revision: 304602
URL: https://svnweb.freebsd.org/changeset/base/304602

Log:
  ioat(4): Don't process events past queue head
  
  Fix a race where the completion routine could overrun the active ring
  area in some situations.

Modified:
  head/sys/dev/ioat/ioat.c

Modified: head/sys/dev/ioat/ioat.c
==============================================================================
--- head/sys/dev/ioat/ioat.c	Mon Aug 22 13:43:25 2016	(r304601)
+++ head/sys/dev/ioat/ioat.c	Mon Aug 22 14:51:07 2016	(r304602)
@@ -678,19 +678,12 @@ ioat_process_events(struct ioat_softc *i
 	}
 
 	completed = 0;
-	comp_update = *ioat->comp_update;
+	comp_update = ioat_get_chansts(ioat);
+	CTR4(KTR_IOAT, "%s channel=%u hw_status=0x%lx last_seen=0x%lx",
+	    __func__, ioat->chan_idx, comp_update, ioat->last_seen);
 	status = comp_update & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_MASK;
 
-	if (status == ioat->last_seen) {
-		/*
-		 * If we landed in process_events and nothing has been
-		 * completed, check for a timeout due to channel halt.
-		 */
-		comp_update = ioat_get_chansts(ioat);
-		goto out;
-	}
-
-	while (1) {
+	while (ioat_get_active(ioat) > 0) {
 		desc = ioat_get_ring_entry(ioat, ioat->tail);
 		dmadesc = &desc->bus_dmadesc;
 		CTR4(KTR_IOAT, "channel=%u completing desc %u ok  cb %p(%p)",
@@ -704,17 +697,13 @@ ioat_process_events(struct ioat_softc *i
 		ioat->tail++;
 		if (desc->hw_desc_bus_addr == status)
 			break;
-
-		KASSERT(ioat_get_active(ioat) > 0, ("overrunning ring t:%u "
-		    "h:%u st:0x%016lx last_seen:%016lx completed:%u\n",
-		    ioat->tail, ioat->head, comp_update, ioat->last_seen,
-		    completed));
 	}
 
-	ioat->last_seen = desc->hw_desc_bus_addr;
-	ioat->stats.descriptors_processed += completed;
+	if (completed != 0) {
+		ioat->last_seen = desc->hw_desc_bus_addr;
+		ioat->stats.descriptors_processed += completed;
+	}
 
-out:
 	ioat_write_chanctrl(ioat, IOAT_CHANCTRL_RUN);
 
 	/* Perform a racy check first; only take the locks if it passes. */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201608221451.u7MEp7li072575>