Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144586103
D29210.1775564659.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D29210.1775564659.diff
View Options
Index: sys/cam/cam.h
===================================================================
--- sys/cam/cam.h
+++ sys/cam/cam.h
@@ -94,8 +94,9 @@
u_int32_t generation;
int index;
#define CAM_UNQUEUED_INDEX -1
-#define CAM_ACTIVE_INDEX -2
-#define CAM_DONEQ_INDEX -3
+#define CAM_ACTIVE_INDEX -2
+#define CAM_DONEQ_INDEX -3
+#define CAM_ASYNC_INDEX -4
#define CAM_EXTRAQ_INDEX INT_MAX
} cam_pinfo;
Index: sys/cam/cam_xpt.c
===================================================================
--- sys/cam/cam_xpt.c
+++ sys/cam/cam_xpt.c
@@ -180,6 +180,7 @@
static struct cam_doneq cam_doneqs[MAXCPU];
static u_int __read_mostly cam_num_doneqs;
static struct proc *cam_proc;
+static struct cam_doneq cam_async;
SYSCTL_INT(_kern_cam, OID_AUTO, num_doneqs, CTLFLAG_RDTUN,
&cam_num_doneqs, 0, "Number of completion queues/threads");
@@ -271,6 +272,7 @@
static void camisr_runqueue(void);
static void xpt_done_process(struct ccb_hdr *ccb_h);
static void xpt_done_td(void *);
+static void xpt_async_td(void *);
static dev_match_ret xptbusmatch(struct dev_match_pattern *patterns,
u_int num_patterns, struct cam_eb *bus);
static dev_match_ret xptdevicematch(struct dev_match_pattern *patterns,
@@ -972,6 +974,15 @@
return (ENOMEM);
}
+ mtx_init(&cam_async.cam_doneq_mtx, "CAM async", NULL, MTX_DEF);
+ STAILQ_INIT(&cam_async.cam_doneq);
+ if (kproc_kthread_add(xpt_async_td, &cam_async,
+ &cam_proc, NULL, 0, 0, "cam", "async") != 0) {
+ printf("xpt_init: Cannot init async thread "
+ "- failing attach\n");
+ return (ENOMEM);
+ }
+
/*
* Register a callback for when interrupts are enabled.
*/
@@ -3146,8 +3157,16 @@
xpt_done(start_ccb);
break;
case XPT_ASYNC:
+ /*
+ * Queue the async operation so it can be run from a sleepable
+ * context.
+ */
start_ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(start_ccb);
+ mtx_lock(&cam_async.cam_doneq_mtx);
+ STAILQ_INSERT_TAIL(&cam_async.cam_doneq, &start_ccb->ccb_h, sim_links.stqe);
+ start_ccb->ccb_h.pinfo.index = CAM_ASYNC_INDEX;
+ mtx_unlock(&cam_async.cam_doneq_mtx);
+ wakeup(&cam_async.cam_doneq);
break;
default:
case XPT_SDEV_TYPE:
@@ -5472,6 +5491,37 @@
mtx_unlock(mtx);
}
+/*
+ * Parameterize instead and use xpt_done_td?
+ */
+static void
+xpt_async_td(void *arg)
+{
+ struct cam_doneq *queue = arg;
+ struct ccb_hdr *ccb_h;
+ STAILQ_HEAD(, ccb_hdr) doneq;
+
+ STAILQ_INIT(&doneq);
+ mtx_lock(&queue->cam_doneq_mtx);
+ while (1) {
+ while (STAILQ_EMPTY(&queue->cam_doneq)) {
+ queue->cam_doneq_sleep = 1;
+ msleep(&queue->cam_doneq, &queue->cam_doneq_mtx,
+ PRIBIO, "-", 0);
+ queue->cam_doneq_sleep = 0;
+ }
+ STAILQ_CONCAT(&doneq, &queue->cam_doneq);
+ mtx_unlock(&queue->cam_doneq_mtx);
+
+ while ((ccb_h = STAILQ_FIRST(&doneq)) != NULL) {
+ STAILQ_REMOVE_HEAD(&doneq, sim_links.stqe);
+ xpt_done_process(ccb_h);
+ }
+
+ mtx_lock(&queue->cam_doneq_mtx);
+ }
+}
+
void
xpt_done_td(void *arg)
{
Index: sys/cam/nvme/nvme_xpt.c
===================================================================
--- sys/cam/nvme/nvme_xpt.c
+++ sys/cam/nvme/nvme_xpt.c
@@ -762,7 +762,7 @@
*/
static void
nvme_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target,
- struct cam_ed *device, void *async_arg)
+ struct cam_ed *device, void *async_arg)
{
/*
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Apr 7, 12:24 PM (9 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28294658
Default Alt Text
D29210.1775564659.diff (3 KB)
Attached To
Mode
D29210: cam: Run all XPT_ASYNC ccbs in a dedicated thread
Attached
Detach File
Event Timeline
Log In to Comment