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

Conrad E. Meyer cem at FreeBSD.org
Sat Feb 13 22:51:27 UTC 2016


Author: cem
Date: Sat Feb 13 22:51:25 2016
New Revision: 295605
URL: https://svnweb.freebsd.org/changeset/base/295605

Log:
  ioat(4): On error detected in ithread, defer HW reset to taskqueue
  
  The I/OAT HW reset process may sleep, so it is invalid to perform a
  channel reset from the software interrupt thread.
  
  Sponsored by:	EMC / Isilon Storage Division

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	Sat Feb 13 22:51:17 2016	(r295604)
+++ head/sys/dev/ioat/ioat.c	Sat Feb 13 22:51:25 2016	(r295605)
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/rman.h>
 #include <sys/sbuf.h>
 #include <sys/sysctl.h>
+#include <sys/taskqueue.h>
 #include <sys/time.h>
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
@@ -92,6 +93,7 @@ static void ioat_submit_single(struct io
 static void ioat_comp_update_map(void *arg, bus_dma_segment_t *seg, int nseg,
     int error);
 static int ioat_reset_hw(struct ioat_softc *ioat);
+static void ioat_reset_hw_task(void *, int);
 static void ioat_setup_sysctl(device_t device);
 static int sysctl_handle_reset(SYSCTL_HANDLER_ARGS);
 static inline struct ioat_softc *ioat_get(struct ioat_softc *,
@@ -308,6 +310,7 @@ ioat_detach(device_t device)
 	ioat = DEVICE2SOFTC(device);
 
 	ioat_test_detach();
+	taskqueue_drain(taskqueue_thread, &ioat->reset_task);
 
 	mtx_lock(IOAT_REFLK);
 	ioat->quiescing = TRUE;
@@ -414,6 +417,7 @@ ioat3_attach(device_t device)
 	mtx_init(&ioat->submit_lock, "ioat_submit", NULL, MTX_DEF);
 	mtx_init(&ioat->cleanup_lock, "ioat_cleanup", NULL, MTX_DEF);
 	callout_init(&ioat->timer, 1);
+	TASK_INIT(&ioat->reset_task, 0, ioat_reset_hw_task, ioat);
 
 	/* Establish lock order for Witness */
 	mtx_lock(&ioat->submit_lock);
@@ -712,8 +716,23 @@ out:
 	mtx_unlock(&ioat->submit_lock);
 
 	ioat_log_message(0, "Resetting channel to recover from error\n");
+	error = taskqueue_enqueue(taskqueue_thread, &ioat->reset_task);
+	KASSERT(error == 0,
+	    ("%s: taskqueue_enqueue failed: %d", __func__, error));
+}
+
+static void
+ioat_reset_hw_task(void *ctx, int pending __unused)
+{
+	struct ioat_softc *ioat;
+	int error;
+
+	ioat = ctx;
+	ioat_log_message(1, "%s: Resetting channel\n", __func__);
+
 	error = ioat_reset_hw(ioat);
 	KASSERT(error == 0, ("%s: reset failed: %d", __func__, error));
+	(void)error;
 }
 
 /*

Modified: head/sys/dev/ioat/ioat_internal.h
==============================================================================
--- head/sys/dev/ioat/ioat_internal.h	Sat Feb 13 22:51:17 2016	(r295604)
+++ head/sys/dev/ioat/ioat_internal.h	Sat Feb 13 22:51:25 2016	(r295605)
@@ -29,6 +29,8 @@ __FBSDID("$FreeBSD$");
 #ifndef __IOAT_INTERNAL_H__
 #define __IOAT_INTERNAL_H__
 
+#include <sys/_task.h>
+
 #define	DEVICE2SOFTC(dev)	((struct ioat_softc *) device_get_softc(dev))
 #define	KTR_IOAT		KTR_SPARE3
 
@@ -405,6 +407,7 @@ struct ioat_softc {
 	bus_addr_t		comp_update_bus_addr;
 
 	struct callout		timer;
+	struct task		reset_task;
 
 	boolean_t		quiescing;
 	boolean_t		is_resize_pending;


More information about the svn-src-all mailing list