edf5051c71
by importing the upstream release as patches.
190 lines
5.9 KiB
Diff
190 lines
5.9 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Brian Behlendorf <behlendorf1@llnl.gov>
|
|
Date: Wed, 24 Jan 2018 11:33:47 -0800
|
|
Subject: [PATCH] Add cv_timedwait_io()
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Add missing helper function cv_timedwait_io(), it should be used
|
|
when waiting on IO with a specified timeout.
|
|
|
|
Reviewed-by: Tim Chase <tim@chase2k.com>
|
|
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
|
|
Closes #674
|
|
(cherry picked from commit ba003d46e3269ead9128b537f8f31c44bc3a974f)
|
|
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
|
---
|
|
include/sys/condvar.h | 2 ++
|
|
module/spl/spl-condvar.c | 58 +++++++++++++++++++++++++++++++++++++++++-------
|
|
config/spl-build.m4 | 21 ++++++++++++++++++
|
|
3 files changed, 73 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/include/sys/condvar.h b/include/sys/condvar.h
|
|
index 5479e75..5fcc906 100644
|
|
--- a/include/sys/condvar.h
|
|
+++ b/include/sys/condvar.h
|
|
@@ -56,6 +56,7 @@ extern void __cv_wait(kcondvar_t *, kmutex_t *);
|
|
extern void __cv_wait_io(kcondvar_t *, kmutex_t *);
|
|
extern void __cv_wait_sig(kcondvar_t *, kmutex_t *);
|
|
extern clock_t __cv_timedwait(kcondvar_t *, kmutex_t *, clock_t);
|
|
+extern clock_t __cv_timedwait_io(kcondvar_t *, kmutex_t *, clock_t);
|
|
extern clock_t __cv_timedwait_sig(kcondvar_t *, kmutex_t *, clock_t);
|
|
extern clock_t cv_timedwait_hires(kcondvar_t *, kmutex_t *, hrtime_t,
|
|
hrtime_t res, int flag);
|
|
@@ -71,6 +72,7 @@ extern void __cv_broadcast(kcondvar_t *c);
|
|
#define cv_wait_sig(cvp, mp) __cv_wait_sig(cvp, mp)
|
|
#define cv_wait_interruptible(cvp, mp) cv_wait_sig(cvp, mp)
|
|
#define cv_timedwait(cvp, mp, t) __cv_timedwait(cvp, mp, t)
|
|
+#define cv_timedwait_io(cvp, mp, t) __cv_timedwait_io(cvp, mp, t)
|
|
#define cv_timedwait_sig(cvp, mp, t) __cv_timedwait_sig(cvp, mp, t)
|
|
#define cv_timedwait_interruptible(cvp, mp, t) cv_timedwait_sig(cvp, mp, t)
|
|
#define cv_signal(cvp) __cv_signal(cvp)
|
|
diff --git a/module/spl/spl-condvar.c b/module/spl/spl-condvar.c
|
|
index 80c2ef0..4778fb2 100644
|
|
--- a/module/spl/spl-condvar.c
|
|
+++ b/module/spl/spl-condvar.c
|
|
@@ -136,6 +136,13 @@ __cv_wait(kcondvar_t *cvp, kmutex_t *mp)
|
|
}
|
|
EXPORT_SYMBOL(__cv_wait);
|
|
|
|
+void
|
|
+__cv_wait_io(kcondvar_t *cvp, kmutex_t *mp)
|
|
+{
|
|
+ cv_wait_common(cvp, mp, TASK_UNINTERRUPTIBLE, 1);
|
|
+}
|
|
+EXPORT_SYMBOL(__cv_wait_io);
|
|
+
|
|
void
|
|
__cv_wait_sig(kcondvar_t *cvp, kmutex_t *mp)
|
|
{
|
|
@@ -143,12 +150,34 @@ __cv_wait_sig(kcondvar_t *cvp, kmutex_t *mp)
|
|
}
|
|
EXPORT_SYMBOL(__cv_wait_sig);
|
|
|
|
-void
|
|
-__cv_wait_io(kcondvar_t *cvp, kmutex_t *mp)
|
|
+#if defined(HAVE_IO_SCHEDULE_TIMEOUT)
|
|
+#define spl_io_schedule_timeout(t) io_schedule_timeout(t)
|
|
+#else
|
|
+static void
|
|
+__cv_wakeup(unsigned long data)
|
|
{
|
|
- cv_wait_common(cvp, mp, TASK_UNINTERRUPTIBLE, 1);
|
|
+ wake_up_process((struct task_struct *)data);
|
|
}
|
|
-EXPORT_SYMBOL(__cv_wait_io);
|
|
+
|
|
+static long
|
|
+spl_io_schedule_timeout(long time_left)
|
|
+{
|
|
+ long expire_time = jiffies + time_left;
|
|
+ struct timer_list timer;
|
|
+
|
|
+ init_timer(&timer);
|
|
+ setup_timer(&timer, __cv_wakeup, (unsigned long)current);
|
|
+ timer.expires = expire_time;
|
|
+ add_timer(&timer);
|
|
+
|
|
+ io_schedule();
|
|
+
|
|
+ del_timer_sync(&timer);
|
|
+ time_left = expire_time - jiffies;
|
|
+
|
|
+ return (time_left < 0 ? 0 : time_left);
|
|
+}
|
|
+#endif
|
|
|
|
/*
|
|
* 'expire_time' argument is an absolute wall clock time in jiffies.
|
|
@@ -156,7 +185,7 @@ EXPORT_SYMBOL(__cv_wait_io);
|
|
*/
|
|
static clock_t
|
|
__cv_timedwait_common(kcondvar_t *cvp, kmutex_t *mp, clock_t expire_time,
|
|
- int state)
|
|
+ int state, int io)
|
|
{
|
|
DEFINE_WAIT(wait);
|
|
kmutex_t *m;
|
|
@@ -188,7 +217,10 @@ __cv_timedwait_common(kcondvar_t *cvp, kmutex_t *mp, clock_t expire_time,
|
|
* race where 'cvp->cv_waiters > 0' but the list is empty.
|
|
*/
|
|
mutex_exit(mp);
|
|
- time_left = schedule_timeout(time_left);
|
|
+ if (io)
|
|
+ time_left = spl_io_schedule_timeout(time_left);
|
|
+ else
|
|
+ time_left = schedule_timeout(time_left);
|
|
|
|
/* No more waiters a different mutex could be used */
|
|
if (atomic_dec_and_test(&cvp->cv_waiters)) {
|
|
@@ -214,14 +246,24 @@ __cv_timedwait_common(kcondvar_t *cvp, kmutex_t *mp, clock_t expire_time,
|
|
clock_t
|
|
__cv_timedwait(kcondvar_t *cvp, kmutex_t *mp, clock_t exp_time)
|
|
{
|
|
- return (__cv_timedwait_common(cvp, mp, exp_time, TASK_UNINTERRUPTIBLE));
|
|
+ return (__cv_timedwait_common(cvp, mp, exp_time,
|
|
+ TASK_UNINTERRUPTIBLE, 0));
|
|
}
|
|
EXPORT_SYMBOL(__cv_timedwait);
|
|
|
|
+clock_t
|
|
+__cv_timedwait_io(kcondvar_t *cvp, kmutex_t *mp, clock_t exp_time)
|
|
+{
|
|
+ return (__cv_timedwait_common(cvp, mp, exp_time,
|
|
+ TASK_UNINTERRUPTIBLE, 1));
|
|
+}
|
|
+EXPORT_SYMBOL(__cv_timedwait_io);
|
|
+
|
|
clock_t
|
|
__cv_timedwait_sig(kcondvar_t *cvp, kmutex_t *mp, clock_t exp_time)
|
|
{
|
|
- return (__cv_timedwait_common(cvp, mp, exp_time, TASK_INTERRUPTIBLE));
|
|
+ return (__cv_timedwait_common(cvp, mp, exp_time,
|
|
+ TASK_INTERRUPTIBLE, 0));
|
|
}
|
|
EXPORT_SYMBOL(__cv_timedwait_sig);
|
|
|
|
diff --git a/config/spl-build.m4 b/config/spl-build.m4
|
|
index 926abd5..afc8de6 100644
|
|
--- a/config/spl-build.m4
|
|
+++ b/config/spl-build.m4
|
|
@@ -52,6 +52,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
|
|
SPL_AC_KMEM_CACHE_CREATE_USERCOPY
|
|
SPL_AC_WAIT_QUEUE_ENTRY_T
|
|
SPL_AC_WAIT_QUEUE_HEAD_ENTRY
|
|
+ SPL_AC_IO_SCHEDULE_TIMEOUT
|
|
SPL_AC_KERNEL_WRITE
|
|
SPL_AC_KERNEL_READ
|
|
SPL_AC_KERNEL_TIMER_FUNCTION_TIMER_LIST
|
|
@@ -1598,6 +1599,26 @@ AC_DEFUN([SPL_AC_WAIT_QUEUE_HEAD_ENTRY], [
|
|
])
|
|
])
|
|
|
|
+dnl #
|
|
+dnl # 3.19 API change
|
|
+dnl # The io_schedule_timeout() function is present in all 2.6.32 kernels
|
|
+dnl # but it was not exported until Linux 3.19. The RHEL 7.x kernels which
|
|
+dnl # are based on a 3.10 kernel do export this symbol.
|
|
+dnl #
|
|
+AC_DEFUN([SPL_AC_IO_SCHEDULE_TIMEOUT], [
|
|
+ AC_MSG_CHECKING([whether io_schedule_timeout() is available])
|
|
+ SPL_LINUX_TRY_COMPILE_SYMBOL([
|
|
+ #include <linux/sched.h>
|
|
+ ], [
|
|
+ (void) io_schedule_timeout(1);
|
|
+ ], [io_schedule_timeout], [], [
|
|
+ AC_MSG_RESULT(yes)
|
|
+ AC_DEFINE(HAVE_IO_SCHEDULE_TIMEOUT, 1, [yes])
|
|
+ ],[
|
|
+ AC_MSG_RESULT(no)
|
|
+ ])
|
|
+])
|
|
+
|
|
dnl #
|
|
dnl # 4.14 API change
|
|
dnl # kernel_write() which was introduced in 3.9 was updated to take
|
|
--
|
|
2.14.2
|
|
|