From: Aaron Taylor Date: Sun, 2 May 2021 08:02:49 +0000 (-0700) Subject: Updated micscif/micscif_rma_dma.c to use new timer API introduced in Linux 4.14.0. X-Git-Tag: first-build~5 X-Git-Url: https://git.subgeniuskitty.com/xeon-phi-kernel-module/.git/commitdiff_plain/446ac8fd5bb540e0073bc58deaed4507d3d5a2e6 Updated micscif/micscif_rma_dma.c to use new timer API introduced in Linux 4.14.0. See also: - https://lwn.net/Articles/735887/ - https://stackoverflow.com/questions/53839625 --- diff --git a/micscif/micscif_rma_dma.c b/micscif/micscif_rma_dma.c index cf17321..9c4ea49 100644 --- a/micscif/micscif_rma_dma.c +++ b/micscif/micscif_rma_dma.c @@ -822,11 +822,23 @@ error: return -ENOMEM; } +// The timer API introduced in Linux 4.14.0 includes a from_timer() macro built +// atop the container_of() macro. As the kernel moves away from using +// timer_list.data, it quasi-assumes that the timer_list struct will be +// contained in some larger struct that also contains the data, hence this +// softlockup_wrapper struct since it allows us to avoid any serious code +// changes to the driver. +struct softlockup_wrapper { + struct timer_list timer; + unsigned long timer_fired; +}; + #if !defined(WINDOWS) && !defined(CONFIG_PREEMPT) static int softlockup_threshold = 60; -static void avert_softlockup(unsigned long data) +static void avert_softlockup(struct timer_list *timer) { - *(unsigned long*)data = 1; + struct softlockup_wrapper *container= from_timer(container, timer, timer); + container->timer_fired = 1; } /* @@ -838,11 +850,10 @@ static void avert_softlockup(unsigned long data) * timers are run at softirq context) * */ -static inline void add_softlockup_timer(struct timer_list *timer, unsigned long *data) +static inline void add_softlockup_timer(struct timer_list *timer) { - setup_timer(timer, avert_softlockup, (unsigned long) data); timer->expires = jiffies + usecs_to_jiffies(softlockup_threshold * 1000000 / 3); - add_timer(timer); + timer_setup(timer, avert_softlockup, 0); } static inline void del_softlockup_timer(struct timer_list *timer) @@ -874,10 +885,10 @@ int micscif_rma_list_cpu_copy(struct mic_copy_work *work) uint64_t src_start_offset, dst_start_offset; int ret = 0; #if !defined(WINDOWS) && !defined(CONFIG_PREEMPT) - unsigned long timer_fired = 0; - struct timer_list timer; + struct softlockup_wrapper tm_wrap; int cpu = smp_processor_id(); - add_softlockup_timer(&timer, &timer_fired); + tm_wrap.timer_fired = 0; + add_softlockup_timer(&tm_wrap.timer); #endif remaining_len = work->len; @@ -889,13 +900,13 @@ int micscif_rma_list_cpu_copy(struct mic_copy_work *work) /* Ideally we should call schedule only if we didn't sleep * in between. But there is no way to know that. */ - if (timer_fired) { - timer_fired = 0; + if (tm_wrap.timer_fired) { + tm_wrap.timer_fired = 0; if (smp_processor_id() == cpu) touch_softlockup_watchdog(); else cpu = smp_processor_id(); - add_softlockup_timer(&timer, &timer_fired); + add_softlockup_timer(&tm_wrap.timer); } #endif src_cache_off = src_offset & ~PAGE_MASK; @@ -977,7 +988,7 @@ int micscif_rma_list_cpu_copy(struct mic_copy_work *work) } error: #if !defined(WINDOWS) && !defined(CONFIG_PREEMPT) - del_softlockup_timer(&timer); + del_softlockup_timer(&tm_wrap.timer); #endif return ret; }