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