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)
 {
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to