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-head
mailing list