Author: hselasky
Date: Wed Jun 20 06:35:37 2018
New Revision: 335411
URL: https://svnweb.freebsd.org/changeset/base/335411

Log:
  MFC r334482:
  Improve high resolution timer support in the LinuxKPI.
  
  Submitted by: Johannes Lundberg <johal...@gmail.com>
  Sponsored by: Mellanox Technologies
  Sponsored by: Limelight Networks

Modified:
  stable/11/sys/compat/linuxkpi/common/include/linux/hrtimer.h
  stable/11/sys/compat/linuxkpi/common/src/linux_hrtimer.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/compat/linuxkpi/common/include/linux/hrtimer.h
==============================================================================
--- stable/11/sys/compat/linuxkpi/common/include/linux/hrtimer.h        Wed Jun 
20 06:34:31 2018        (r335410)
+++ stable/11/sys/compat/linuxkpi/common/include/linux/hrtimer.h        Wed Jun 
20 06:35:37 2018        (r335411)
@@ -37,6 +37,7 @@
 
 enum hrtimer_mode {
        HRTIMER_MODE_REL,
+       HRTIMER_MODE_REL_PINNED = HRTIMER_MODE_REL,
 };
 
 enum hrtimer_restart {
@@ -48,31 +49,42 @@ struct hrtimer {
        enum hrtimer_restart (*function)(struct hrtimer *);
        struct mtx mtx;
        struct callout callout;
+       s64 expires;    /* relative time in nanoseconds */
+       s64 precision;  /* in nanoseconds */
 };
 
 #define        hrtimer_active(hrtimer) linux_hrtimer_active(hrtimer)
 #define        hrtimer_cancel(hrtimer) linux_hrtimer_cancel(hrtimer)
+
 #define        hrtimer_init(hrtimer, clock, mode) do {                 \
        CTASSERT((clock) == CLOCK_MONOTONIC);                   \
        CTASSERT((mode) == HRTIMER_MODE_REL);                   \
        linux_hrtimer_init(hrtimer);                            \
 } while (0)
+
 #define        hrtimer_set_expires(hrtimer, time)                      \
        linux_hrtimer_set_expires(hrtimer, time)
+
 #define        hrtimer_start(hrtimer, time, mode) do {                 \
        CTASSERT((mode) == HRTIMER_MODE_REL);                   \
        linux_hrtimer_start(hrtimer, time);                     \
 } while (0)
+
 #define        hrtimer_start_range_ns(hrtimer, time, prec, mode) do {  \
        CTASSERT((mode) == HRTIMER_MODE_REL);                   \
        linux_hrtimer_start_range_ns(hrtimer, time, prec);      \
 } while (0)
 
+#define        hrtimer_forward_now(hrtimer, interval) do {             \
+       linux_hrtimer_forward_now(hrtimer, interval);           \
+} while (0)
+
 bool   linux_hrtimer_active(struct hrtimer *);
 int    linux_hrtimer_cancel(struct hrtimer *);
 void   linux_hrtimer_init(struct hrtimer *);
 void   linux_hrtimer_set_expires(struct hrtimer *, ktime_t);
 void   linux_hrtimer_start(struct hrtimer *, ktime_t);
 void   linux_hrtimer_start_range_ns(struct hrtimer *, ktime_t, int64_t);
+void   linux_hrtimer_forward_now(struct hrtimer *, ktime_t);
 
 #endif /* _LINUX_HRTIMER_H_ */

Modified: stable/11/sys/compat/linuxkpi/common/src/linux_hrtimer.c
==============================================================================
--- stable/11/sys/compat/linuxkpi/common/src/linux_hrtimer.c    Wed Jun 20 
06:34:31 2018        (r335410)
+++ stable/11/sys/compat/linuxkpi/common/src/linux_hrtimer.c    Wed Jun 20 
06:35:37 2018        (r335411)
@@ -45,8 +45,13 @@ hrtimer_call_handler(void *arg)
 
        hrtimer = arg;
        ret = hrtimer->function(hrtimer);
-       MPASS(ret == HRTIMER_NORESTART);
-       callout_deactivate(&hrtimer->callout);
+
+       if (ret == HRTIMER_RESTART) {
+               callout_schedule_sbt(&hrtimer->callout,
+                   nstosbt(hrtimer->expires), nstosbt(hrtimer->precision), 0);
+       } else {
+               callout_deactivate(&hrtimer->callout);
+       }
 }
 
 bool
@@ -57,6 +62,7 @@ linux_hrtimer_active(struct hrtimer *hrtimer)
        mtx_lock(&hrtimer->mtx);
        ret = callout_active(&hrtimer->callout);
        mtx_unlock(&hrtimer->mtx);
+
        return (ret);
 }
 
@@ -75,15 +81,16 @@ void
 linux_hrtimer_init(struct hrtimer *hrtimer)
 {
 
-       hrtimer->function = NULL;
-       mtx_init(&hrtimer->mtx, "hrtimer", NULL, MTX_DEF | MTX_RECURSE);
+       memset(hrtimer, 0, sizeof(*hrtimer));
+       mtx_init(&hrtimer->mtx, "hrtimer", NULL,
+           MTX_DEF | MTX_RECURSE | MTX_NOWITNESS);
        callout_init_mtx(&hrtimer->callout, &hrtimer->mtx, 0);
 }
 
 void
-linux_hrtimer_set_expires(struct hrtimer *hrtimer __unused,
-    ktime_t time __unused)
+linux_hrtimer_set_expires(struct hrtimer *hrtimer, ktime_t time)
 {
+       hrtimer->expires = ktime_to_ns(time);
 }
 
 void
@@ -94,11 +101,24 @@ linux_hrtimer_start(struct hrtimer *hrtimer, ktime_t t
 }
 
 void
-linux_hrtimer_start_range_ns(struct hrtimer *hrtimer, ktime_t time, int64_t 
nsec)
+linux_hrtimer_start_range_ns(struct hrtimer *hrtimer, ktime_t time,
+    int64_t nsec)
 {
 
        mtx_lock(&hrtimer->mtx);
-       callout_reset_sbt(&hrtimer->callout, nstosbt(time), nstosbt(nsec),
-           hrtimer_call_handler, hrtimer, 0);
+       hrtimer->precision = nsec;
+       callout_reset_sbt(&hrtimer->callout, nstosbt(ktime_to_ns(time)),
+           nstosbt(nsec), hrtimer_call_handler, hrtimer, 0);
        mtx_unlock(&hrtimer->mtx);
 }
+
+void
+linux_hrtimer_forward_now(struct hrtimer *hrtimer, ktime_t interval)
+{
+
+       mtx_lock(&hrtimer->mtx);
+       callout_reset_sbt(&hrtimer->callout, nstosbt(ktime_to_ns(interval)),
+           nstosbt(hrtimer->precision), hrtimer_call_handler, hrtimer, 0);
+       mtx_unlock(&hrtimer->mtx);
+}
+
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to