1 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2 From: Tony Hutter <hutter2@llnl.gov>
3 Date: Thu, 21 Dec 2017 10:56:32 -0800
4 Subject: [PATCH] Linux 4.15 compat: timer updates
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
9 Use timer_setup() macro and new timeout function definition.
11 Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
12 Signed-off-by: Tony Hutter <hutter2@llnl.gov>
15 (cherry picked from commit 71513af020c0522560dc86668db46b49068787b3)
16 Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
18 module/spl/spl-taskq.c | 27 +++++++++++++++++++++++++--
19 config/spl-build.m4 | 34 ++++++++++++++++++++++++++++++++++
20 2 files changed, 59 insertions(+), 2 deletions(-)
22 diff --git a/module/spl/spl-taskq.c b/module/spl/spl-taskq.c
23 index 7cad9f7..89c53a5 100644
24 --- a/module/spl/spl-taskq.c
25 +++ b/module/spl/spl-taskq.c
26 @@ -209,9 +209,9 @@ task_done(taskq_t *tq, taskq_ent_t *t)
27 * add it to the priority list in order for immediate processing.
30 -task_expire(unsigned long data)
31 +task_expire_impl(taskq_ent_t *t)
33 - taskq_ent_t *w, *t = (taskq_ent_t *)data;
35 taskq_t *tq = t->tqent_taskq;
38 @@ -245,6 +245,21 @@ task_expire(unsigned long data)
39 wake_up(&tq->tq_work_waitq);
42 +#ifdef HAVE_KERNEL_TIMER_FUNCTION_TIMER_LIST
44 +task_expire(struct timer_list *tl)
46 + taskq_ent_t *t = from_timer(t, tl, tqent_timer);
47 + task_expire_impl(t);
51 +task_expire(unsigned long data)
53 + task_expire_impl((taskq_ent_t *)data);
58 * Returns the lowest incomplete taskqid_t. The taskqid_t may
59 * be queued on the pending list, on the priority list, on the
60 @@ -590,7 +605,9 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t flags)
64 +#ifndef HAVE_KERNEL_TIMER_FUNCTION_TIMER_LIST
65 t->tqent_timer.data = 0;
67 t->tqent_timer.function = NULL;
68 t->tqent_timer.expires = 0;
69 t->tqent_birth = jiffies;
70 @@ -640,7 +657,9 @@ taskq_dispatch_delay(taskq_t *tq, task_func_t func, void *arg,
74 +#ifndef HAVE_KERNEL_TIMER_FUNCTION_TIMER_LIST
75 t->tqent_timer.data = (unsigned long)t;
77 t->tqent_timer.function = task_expire;
78 t->tqent_timer.expires = (unsigned long)expire_time;
79 add_timer(&t->tqent_timer);
80 @@ -732,7 +751,11 @@ taskq_init_ent(taskq_ent_t *t)
82 spin_lock_init(&t->tqent_lock);
83 init_waitqueue_head(&t->tqent_waitq);
84 +#ifdef HAVE_KERNEL_TIMER_FUNCTION_TIMER_LIST
85 + timer_setup(&t->tqent_timer, NULL, 0);
87 init_timer(&t->tqent_timer);
89 INIT_LIST_HEAD(&t->tqent_list);
92 diff --git a/config/spl-build.m4 b/config/spl-build.m4
93 index accf675..25013b5 100644
94 --- a/config/spl-build.m4
95 +++ b/config/spl-build.m4
96 @@ -56,6 +56,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
97 SPL_AC_WAIT_QUEUE_HEAD_ENTRY
100 + SPL_AC_KERNEL_TIMER_FUNCTION_TIMER_LIST
103 AC_DEFUN([SPL_AC_MODULE_SYMVERS], [
104 @@ -1755,3 +1756,36 @@ AC_DEFUN([SPL_AC_KERNEL_READ], [
106 EXTRA_KCFLAGS="$tmp_flags"
110 +dnl # 4.15 API change
111 +dnl # https://lkml.org/lkml/2017/11/25/90
112 +dnl # Check if timer_list.func get passed a timer_list or an unsigned long
113 +dnl # (older kernels). Also sanity check the from_timer() and timer_setup()
114 +dnl # macros are available as well, since they will be used in the same newer
115 +dnl # kernels that support the new timer_list.func signature.
117 +AC_DEFUN([SPL_AC_KERNEL_TIMER_FUNCTION_TIMER_LIST], [
118 + AC_MSG_CHECKING([whether timer_list.function gets a timer_list])
119 + tmp_flags="$EXTRA_KCFLAGS"
120 + EXTRA_KCFLAGS="-Werror"
121 + SPL_LINUX_TRY_COMPILE([
122 + #include <linux/timer.h>
123 + void task_expire(struct timer_list *tl) {}
126 + #error "No from_timer() macro"
129 + struct timer_list timer;
130 + timer.function = task_expire;
131 + timer_setup(&timer, NULL, 0);
134 + AC_DEFINE(HAVE_KERNEL_TIMER_FUNCTION_TIMER_LIST, 1,
135 + [timer_list.function gets a timer_list])
139 + EXTRA_KCFLAGS="$tmp_flags"