linux/timer.h: Adapt to Dragonfly
authorFrançois Tigeot <ftigeot@wolfpond.org>
Tue, 22 Apr 2014 18:15:34 +0000 (20:15 +0200)
committerFrançois Tigeot <ftigeot@wolfpond.org>
Tue, 22 Apr 2014 18:16:00 +0000 (20:16 +0200)
* Protect callout structures from concurrent operations on MP machines

* Expand the API for use with drm code from Linux 3.8.x

sys/dev/drm/include/linux/timer.h

index a497334..18abcf4 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright (c) 2010 Isilon Systems, Inc.
  * Copyright (c) 2010 iX Systems, Inc.
  * Copyright (c) 2010 Panasas, Inc.
+ * Copyright (c) 2014 François Tigeot
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/callout.h>
+#include <sys/thread.h>
 
 struct timer_list {
        struct callout  timer_callout;
        void            (*function)(unsigned long);
        unsigned long   data;
        unsigned long   expires;
+       struct lwkt_token timer_token;
 };
 
 static inline void
@@ -54,28 +57,43 @@ _timer_fn(void *context)
 do {                                                                   \
        (timer)->function = (func);                                     \
        (timer)->data = (dat);                                          \
-       callout_init(&(timer)->timer_callout, CALLOUT_MPSAFE);          \
+       lwkt_token_init(&(timer)->timer_token, "timer token");  \
+       callout_init_mp(&(timer)->timer_callout);                       \
 } while (0)
 
 #define        init_timer(timer)                                               \
 do {                                                                   \
        (timer)->function = NULL;                                       \
        (timer)->data = 0;                                              \
-       callout_init(&(timer)->timer_callout, CALLOUT_MPSAFE);          \
+       lwkt_token_init(&(timer)->timer_token, "timer token");  \
+       callout_init_mp(&(timer)->timer_callout);                       \
 } while (0)
 
 #define        mod_timer(timer, exp)                                           \
 do {                                                                   \
        (timer)->expires = (exp);                                       \
+       lwkt_gettoken(&(timer)->timer_token);                           \
        callout_reset(&(timer)->timer_callout, (exp) - jiffies,         \
            _timer_fn, (timer));                                        \
+       lwkt_reltoken(&(timer)->timer_token);                           \
 } while (0)
 
 #define        add_timer(timer)                                                \
+       lwkt_gettoken(&(timer)->timer_token);                           \
        callout_reset(&(timer)->timer_callout,                          \
-           (timer)->expires - jiffies, _timer_fn, (timer))
+           (timer)->expires - jiffies, _timer_fn, (timer));            \
+       lwkt_reltoken(&(timer)->timer_token);
+
+static inline void
+del_timer(struct timer_list *timer)
+{
+       lwkt_gettoken(&(timer)->timer_token);
+       callout_stop(&(timer)->timer_callout);
+       lwkt_reltoken(&(timer)->timer_token);
+
+       lwkt_token_uninit(&(timer)->timer_token);
+}
 
-#define        del_timer(timer)        callout_stop(&(timer)->timer_callout)
 #define        del_timer_sync(timer)   callout_drain(&(timer)->timer_callout)
 
 #define        timer_pending(timer)    callout_pending(&(timer)->timer_callout)
@@ -86,4 +104,10 @@ round_jiffies(unsigned long j)
        return roundup(j, hz);
 }
 
+static inline unsigned long
+round_jiffies_up(unsigned long j)
+{
+       return roundup(j, hz);
+}
+
 #endif /* _LINUX_TIMER_H_ */