]> git.proxmox.com Git - zfsonlinux.git/blob - spl-patches/0005-Add-cv_timedwait_io.patch
update SPL to 0.7.7
[zfsonlinux.git] / spl-patches / 0005-Add-cv_timedwait_io.patch
1 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2 From: Brian Behlendorf <behlendorf1@llnl.gov>
3 Date: Wed, 24 Jan 2018 11:33:47 -0800
4 Subject: [PATCH] Add cv_timedwait_io()
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 Add missing helper function cv_timedwait_io(), it should be used
10 when waiting on IO with a specified timeout.
11
12 Reviewed-by: Tim Chase <tim@chase2k.com>
13 Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
14 Closes #674
15 (cherry picked from commit ba003d46e3269ead9128b537f8f31c44bc3a974f)
16 Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
17 ---
18 include/sys/condvar.h | 2 ++
19 module/spl/spl-condvar.c | 58 +++++++++++++++++++++++++++++++++++++++++-------
20 config/spl-build.m4 | 21 ++++++++++++++++++
21 3 files changed, 73 insertions(+), 8 deletions(-)
22
23 diff --git a/include/sys/condvar.h b/include/sys/condvar.h
24 index 5479e75..5fcc906 100644
25 --- a/include/sys/condvar.h
26 +++ b/include/sys/condvar.h
27 @@ -56,6 +56,7 @@ extern void __cv_wait(kcondvar_t *, kmutex_t *);
28 extern void __cv_wait_io(kcondvar_t *, kmutex_t *);
29 extern void __cv_wait_sig(kcondvar_t *, kmutex_t *);
30 extern clock_t __cv_timedwait(kcondvar_t *, kmutex_t *, clock_t);
31 +extern clock_t __cv_timedwait_io(kcondvar_t *, kmutex_t *, clock_t);
32 extern clock_t __cv_timedwait_sig(kcondvar_t *, kmutex_t *, clock_t);
33 extern clock_t cv_timedwait_hires(kcondvar_t *, kmutex_t *, hrtime_t,
34 hrtime_t res, int flag);
35 @@ -71,6 +72,7 @@ extern void __cv_broadcast(kcondvar_t *c);
36 #define cv_wait_sig(cvp, mp) __cv_wait_sig(cvp, mp)
37 #define cv_wait_interruptible(cvp, mp) cv_wait_sig(cvp, mp)
38 #define cv_timedwait(cvp, mp, t) __cv_timedwait(cvp, mp, t)
39 +#define cv_timedwait_io(cvp, mp, t) __cv_timedwait_io(cvp, mp, t)
40 #define cv_timedwait_sig(cvp, mp, t) __cv_timedwait_sig(cvp, mp, t)
41 #define cv_timedwait_interruptible(cvp, mp, t) cv_timedwait_sig(cvp, mp, t)
42 #define cv_signal(cvp) __cv_signal(cvp)
43 diff --git a/module/spl/spl-condvar.c b/module/spl/spl-condvar.c
44 index 80c2ef0..4778fb2 100644
45 --- a/module/spl/spl-condvar.c
46 +++ b/module/spl/spl-condvar.c
47 @@ -136,6 +136,13 @@ __cv_wait(kcondvar_t *cvp, kmutex_t *mp)
48 }
49 EXPORT_SYMBOL(__cv_wait);
50
51 +void
52 +__cv_wait_io(kcondvar_t *cvp, kmutex_t *mp)
53 +{
54 + cv_wait_common(cvp, mp, TASK_UNINTERRUPTIBLE, 1);
55 +}
56 +EXPORT_SYMBOL(__cv_wait_io);
57 +
58 void
59 __cv_wait_sig(kcondvar_t *cvp, kmutex_t *mp)
60 {
61 @@ -143,12 +150,34 @@ __cv_wait_sig(kcondvar_t *cvp, kmutex_t *mp)
62 }
63 EXPORT_SYMBOL(__cv_wait_sig);
64
65 -void
66 -__cv_wait_io(kcondvar_t *cvp, kmutex_t *mp)
67 +#if defined(HAVE_IO_SCHEDULE_TIMEOUT)
68 +#define spl_io_schedule_timeout(t) io_schedule_timeout(t)
69 +#else
70 +static void
71 +__cv_wakeup(unsigned long data)
72 {
73 - cv_wait_common(cvp, mp, TASK_UNINTERRUPTIBLE, 1);
74 + wake_up_process((struct task_struct *)data);
75 }
76 -EXPORT_SYMBOL(__cv_wait_io);
77 +
78 +static long
79 +spl_io_schedule_timeout(long time_left)
80 +{
81 + long expire_time = jiffies + time_left;
82 + struct timer_list timer;
83 +
84 + init_timer(&timer);
85 + setup_timer(&timer, __cv_wakeup, (unsigned long)current);
86 + timer.expires = expire_time;
87 + add_timer(&timer);
88 +
89 + io_schedule();
90 +
91 + del_timer_sync(&timer);
92 + time_left = expire_time - jiffies;
93 +
94 + return (time_left < 0 ? 0 : time_left);
95 +}
96 +#endif
97
98 /*
99 * 'expire_time' argument is an absolute wall clock time in jiffies.
100 @@ -156,7 +185,7 @@ EXPORT_SYMBOL(__cv_wait_io);
101 */
102 static clock_t
103 __cv_timedwait_common(kcondvar_t *cvp, kmutex_t *mp, clock_t expire_time,
104 - int state)
105 + int state, int io)
106 {
107 DEFINE_WAIT(wait);
108 kmutex_t *m;
109 @@ -188,7 +217,10 @@ __cv_timedwait_common(kcondvar_t *cvp, kmutex_t *mp, clock_t expire_time,
110 * race where 'cvp->cv_waiters > 0' but the list is empty.
111 */
112 mutex_exit(mp);
113 - time_left = schedule_timeout(time_left);
114 + if (io)
115 + time_left = spl_io_schedule_timeout(time_left);
116 + else
117 + time_left = schedule_timeout(time_left);
118
119 /* No more waiters a different mutex could be used */
120 if (atomic_dec_and_test(&cvp->cv_waiters)) {
121 @@ -214,14 +246,24 @@ __cv_timedwait_common(kcondvar_t *cvp, kmutex_t *mp, clock_t expire_time,
122 clock_t
123 __cv_timedwait(kcondvar_t *cvp, kmutex_t *mp, clock_t exp_time)
124 {
125 - return (__cv_timedwait_common(cvp, mp, exp_time, TASK_UNINTERRUPTIBLE));
126 + return (__cv_timedwait_common(cvp, mp, exp_time,
127 + TASK_UNINTERRUPTIBLE, 0));
128 }
129 EXPORT_SYMBOL(__cv_timedwait);
130
131 +clock_t
132 +__cv_timedwait_io(kcondvar_t *cvp, kmutex_t *mp, clock_t exp_time)
133 +{
134 + return (__cv_timedwait_common(cvp, mp, exp_time,
135 + TASK_UNINTERRUPTIBLE, 1));
136 +}
137 +EXPORT_SYMBOL(__cv_timedwait_io);
138 +
139 clock_t
140 __cv_timedwait_sig(kcondvar_t *cvp, kmutex_t *mp, clock_t exp_time)
141 {
142 - return (__cv_timedwait_common(cvp, mp, exp_time, TASK_INTERRUPTIBLE));
143 + return (__cv_timedwait_common(cvp, mp, exp_time,
144 + TASK_INTERRUPTIBLE, 0));
145 }
146 EXPORT_SYMBOL(__cv_timedwait_sig);
147
148 diff --git a/config/spl-build.m4 b/config/spl-build.m4
149 index 926abd5..afc8de6 100644
150 --- a/config/spl-build.m4
151 +++ b/config/spl-build.m4
152 @@ -52,6 +52,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
153 SPL_AC_KMEM_CACHE_CREATE_USERCOPY
154 SPL_AC_WAIT_QUEUE_ENTRY_T
155 SPL_AC_WAIT_QUEUE_HEAD_ENTRY
156 + SPL_AC_IO_SCHEDULE_TIMEOUT
157 SPL_AC_KERNEL_WRITE
158 SPL_AC_KERNEL_READ
159 SPL_AC_KERNEL_TIMER_FUNCTION_TIMER_LIST
160 @@ -1598,6 +1599,26 @@ AC_DEFUN([SPL_AC_WAIT_QUEUE_HEAD_ENTRY], [
161 ])
162 ])
163
164 +dnl #
165 +dnl # 3.19 API change
166 +dnl # The io_schedule_timeout() function is present in all 2.6.32 kernels
167 +dnl # but it was not exported until Linux 3.19. The RHEL 7.x kernels which
168 +dnl # are based on a 3.10 kernel do export this symbol.
169 +dnl #
170 +AC_DEFUN([SPL_AC_IO_SCHEDULE_TIMEOUT], [
171 + AC_MSG_CHECKING([whether io_schedule_timeout() is available])
172 + SPL_LINUX_TRY_COMPILE_SYMBOL([
173 + #include <linux/sched.h>
174 + ], [
175 + (void) io_schedule_timeout(1);
176 + ], [io_schedule_timeout], [], [
177 + AC_MSG_RESULT(yes)
178 + AC_DEFINE(HAVE_IO_SCHEDULE_TIMEOUT, 1, [yes])
179 + ],[
180 + AC_MSG_RESULT(no)
181 + ])
182 +])
183 +
184 dnl #
185 dnl # 4.14 API change
186 dnl # kernel_write() which was introduced in 3.9 was updated to take
187 --
188 2.14.2
189