Updated micscif/micscif_rma_dma.c to use new timer API introduced in Linux 4.14.0.
authorAaron Taylor <ataylor@subgeniuskitty.com>
Sun, 2 May 2021 08:02:49 +0000 (01:02 -0700)
committerAaron Taylor <ataylor@subgeniuskitty.com>
Sun, 2 May 2021 08:02:49 +0000 (01:02 -0700)
See also:

  - https://lwn.net/Articles/735887/

  - https://stackoverflow.com/questions/53839625

micscif/micscif_rma_dma.c

index cf17321..9c4ea49 100644 (file)
@@ -822,11 +822,23 @@ error:
        return -ENOMEM;
 }
 
        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;
 #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)
  *
  */
  * 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);
        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)
 }
 
 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)
     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();
        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;
 #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.
                 */
                /* 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();
                        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;
                }
 #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)
        }
 error:
 #if !defined(WINDOWS) && !defined(CONFIG_PREEMPT)
-       del_softlockup_timer(&timer);
+       del_softlockup_timer(&tm_wrap.timer);
 #endif
        return ret;
 }
 #endif
        return ret;
 }