diff --git a/include/sys/condvar.h b/include/sys/condvar.h
index 709a86d390..62210357d4 100644
--- a/include/sys/condvar.h
+++ b/include/sys/condvar.h
@@ -51,6 +51,7 @@ typedef enum { CV_DEFAULT=0, CV_DRIVER } kcv_type_t;
 extern void __cv_init(kcondvar_t *cvp, char *name, kcv_type_t type, void *arg);
 extern void __cv_destroy(kcondvar_t *cvp);
 extern void __cv_wait(kcondvar_t *cvp, kmutex_t *mp);
+extern void __cv_wait_io(kcondvar_t *cvp, kmutex_t *mp);
 extern void __cv_wait_interruptible(kcondvar_t *cvp, kmutex_t *mp);
 extern clock_t __cv_timedwait(kcondvar_t *cvp, kmutex_t *mp, clock_t exp_time);
 extern clock_t __cv_timedwait_interruptible(kcondvar_t *cvp, kmutex_t *mp,
@@ -61,6 +62,7 @@ extern void __cv_broadcast(kcondvar_t *cvp);
 #define cv_init(cvp, name, type, arg)		__cv_init(cvp, name, type, arg)
 #define cv_destroy(cvp)				__cv_destroy(cvp)
 #define cv_wait(cvp, mp)			__cv_wait(cvp, mp)
+#define cv_wait_io(cvp, mp)			__cv_wait_io(cvp, mp)
 #define cv_wait_interruptible(cvp, mp)		__cv_wait_interruptible(cvp,mp)
 #define cv_timedwait(cvp, mp, t)		__cv_timedwait(cvp, mp, t)
 #define cv_timedwait_interruptible(cvp, mp, t)                                \
diff --git a/module/spl/spl-condvar.c b/module/spl/spl-condvar.c
index 6ed6579b30..fefe98598a 100644
--- a/module/spl/spl-condvar.c
+++ b/module/spl/spl-condvar.c
@@ -97,7 +97,7 @@ __cv_destroy(kcondvar_t *cvp)
 EXPORT_SYMBOL(__cv_destroy);
 
 static void
-cv_wait_common(kcondvar_t *cvp, kmutex_t *mp, int state)
+cv_wait_common(kcondvar_t *cvp, kmutex_t *mp, int state, int io)
 {
 	DEFINE_WAIT(wait);
 	SENTRY;
@@ -121,7 +121,10 @@ cv_wait_common(kcondvar_t *cvp, kmutex_t *mp, int state)
 	 * ensures we're linked in to the waiters list and avoids the
 	 * race where 'cvp->cv_waiters > 0' but the list is empty. */
 	mutex_exit(mp);
-	schedule();
+	if (io)
+		io_schedule();
+	else
+		schedule();
 	mutex_enter(mp);
 
 	/* No more waiters a different mutex could be used */
@@ -139,17 +142,24 @@ cv_wait_common(kcondvar_t *cvp, kmutex_t *mp, int state)
 void
 __cv_wait(kcondvar_t *cvp, kmutex_t *mp)
 {
-	cv_wait_common(cvp, mp, TASK_UNINTERRUPTIBLE);
+	cv_wait_common(cvp, mp, TASK_UNINTERRUPTIBLE, 0);
 }
 EXPORT_SYMBOL(__cv_wait);
 
 void
 __cv_wait_interruptible(kcondvar_t *cvp, kmutex_t *mp)
 {
-	cv_wait_common(cvp, mp, TASK_INTERRUPTIBLE);
+	cv_wait_common(cvp, mp, TASK_INTERRUPTIBLE, 0);
 }
 EXPORT_SYMBOL(__cv_wait_interruptible);
 
+void
+__cv_wait_io(kcondvar_t *cvp, kmutex_t *mp)
+{
+	cv_wait_common(cvp, mp, TASK_UNINTERRUPTIBLE, 1);
+}
+EXPORT_SYMBOL(__cv_wait_io);
+
 /* 'expire_time' argument is an absolute wall clock time in jiffies.
  * Return value is time left (expire_time - now) or -1 if timeout occurred.
  */