svn commit: r308070 - head/sys/dev/ioat

Conrad E. Meyer cem at FreeBSD.org
Fri Oct 28 23:53:39 UTC 2016


Author: cem
Date: Fri Oct 28 23:53:37 2016
New Revision: 308070
URL: https://svnweb.freebsd.org/changeset/base/308070

Log:
  ioat(4): Use memory completion rather than device register
  
  The CHANSTS register is a split 64-bit register on CBDMA units before
  hardware v3.3.  If a torn read happens during ioat_process_events(),
  software cannot know when to stop completing descriptors correctly.
  
  So, just use the device-pushed main memory channel status instead.
  
  Remove the ioat_get_active() seatbelt as well.  It does nothing if the
  completion address is valid.
  
  Sponsored by:	Dell EMC Isilon

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

Modified: head/sys/dev/ioat/ioat.c
==============================================================================
--- head/sys/dev/ioat/ioat.c	Fri Oct 28 23:53:36 2016	(r308069)
+++ head/sys/dev/ioat/ioat.c	Fri Oct 28 23:53:37 2016	(r308070)
@@ -677,7 +677,7 @@ ioat_process_events(struct ioat_softc *i
 	}
 
 	completed = 0;
-	comp_update = ioat_get_chansts(ioat);
+	comp_update = *ioat->comp_update;
 	status = comp_update & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_MASK;
 
 	if (status == ioat->last_seen) {
@@ -691,7 +691,7 @@ ioat_process_events(struct ioat_softc *i
 	    __func__, ioat->chan_idx, comp_update, ioat->last_seen);
 
 	desc = ioat_get_ring_entry(ioat, ioat->tail - 1);
-	while (desc->hw_desc_bus_addr != status && ioat_get_active(ioat) > 0) {
+	while (desc->hw_desc_bus_addr != status) {
 		desc = ioat_get_ring_entry(ioat, ioat->tail);
 		dmadesc = &desc->bus_dmadesc;
 		CTR5(KTR_IOAT, "channel=%u completing desc idx %u (%p) ok  cb %p(%p)",

Modified: head/sys/dev/ioat/ioat_internal.h
==============================================================================
--- head/sys/dev/ioat/ioat_internal.h	Fri Oct 28 23:53:36 2016	(r308069)
+++ head/sys/dev/ioat/ioat_internal.h	Fri Oct 28 23:53:37 2016	(r308070)
@@ -523,6 +523,15 @@ struct ioat_softc {
 void ioat_test_attach(void);
 void ioat_test_detach(void);
 
+/*
+ * XXX DO NOT USE this routine for obtaining the current completed descriptor.
+ *
+ * The double_4 read on ioat<3.3 appears to result in torn reads.  And v3.2
+ * hardware is still commonplace (Broadwell Xeon has it).  Instead, use the
+ * device-pushed *comp_update.
+ *
+ * It is safe to use ioat_get_chansts() for the low status bits.
+ */
 static inline uint64_t
 ioat_get_chansts(struct ioat_softc *ioat)
 {


More information about the svn-src-all mailing list