Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 28 Oct 2016 23:53:38 +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: r308070 - head/sys/dev/ioat
Message-ID:  <201610282353.u9SNrcwP094399@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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)
 {



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