svn commit: r358699 - in stable/12/sys/compat/linuxkpi/common: include/linux src
Hans Petter Selasky
hselasky at FreeBSD.org
Fri Mar 6 13:57:02 UTC 2020
Author: hselasky
Date: Fri Mar 6 13:57:00 2020
New Revision: 358699
URL: https://svnweb.freebsd.org/changeset/base/358699
Log:
MFC r358387:
Extend the range of the return value from nsecs_to_jiffies64() to support
Mesa's drm_syncobj usage, in the LinuxKPI.
While at it optimise the jiffies conversion functions to avoid repeated
and constant calculations.
Submitted by: Greg V <greg at unrelenting.technology>
Differential Revision: https://reviews.freebsd.org/D23846
Sponsored by: Mellanox Technologies
Modified:
stable/12/sys/compat/linuxkpi/common/include/linux/jiffies.h
stable/12/sys/compat/linuxkpi/common/src/linux_compat.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/sys/compat/linuxkpi/common/include/linux/jiffies.h
==============================================================================
--- stable/12/sys/compat/linuxkpi/common/include/linux/jiffies.h Fri Mar 6 12:37:04 2020 (r358698)
+++ stable/12/sys/compat/linuxkpi/common/include/linux/jiffies.h Fri Mar 6 13:57:00 2020 (r358699)
@@ -54,6 +54,18 @@
#define HZ hz
+extern uint64_t lkpi_nsec2hz_rem;
+extern uint64_t lkpi_nsec2hz_div;
+extern uint64_t lkpi_nsec2hz_max;
+
+extern uint64_t lkpi_usec2hz_rem;
+extern uint64_t lkpi_usec2hz_div;
+extern uint64_t lkpi_usec2hz_max;
+
+extern uint64_t lkpi_msec2hz_rem;
+extern uint64_t lkpi_msec2hz_div;
+extern uint64_t lkpi_msec2hz_max;
+
static inline int
timespec_to_jiffies(const struct timespec *ts)
{
@@ -70,12 +82,11 @@ timespec_to_jiffies(const struct timespec *ts)
static inline int
msecs_to_jiffies(uint64_t msec)
{
- uint64_t msec_max, result;
+ uint64_t result;
- msec_max = -1ULL / (uint64_t)hz;
- if (msec > msec_max)
- msec = msec_max;
- result = howmany(msec * (uint64_t)hz, 1000ULL);
+ if (msec > lkpi_msec2hz_max)
+ msec = lkpi_msec2hz_max;
+ result = howmany(msec * lkpi_msec2hz_rem, lkpi_msec2hz_div);
if (result > MAX_JIFFY_OFFSET)
result = MAX_JIFFY_OFFSET;
@@ -85,12 +96,11 @@ msecs_to_jiffies(uint64_t msec)
static inline int
usecs_to_jiffies(uint64_t usec)
{
- uint64_t usec_max, result;
+ uint64_t result;
- usec_max = -1ULL / (uint64_t)hz;
- if (usec > usec_max)
- usec = usec_max;
- result = howmany(usec * (uint64_t)hz, 1000000ULL);
+ if (usec > lkpi_usec2hz_max)
+ usec = lkpi_usec2hz_max;
+ result = howmany(usec * lkpi_usec2hz_rem, lkpi_usec2hz_div);
if (result > MAX_JIFFY_OFFSET)
result = MAX_JIFFY_OFFSET;
@@ -100,23 +110,24 @@ usecs_to_jiffies(uint64_t usec)
static inline uint64_t
nsecs_to_jiffies64(uint64_t nsec)
{
- uint64_t nsec_max, result;
- nsec_max = -1ULL / (uint64_t)hz;
- if (nsec > nsec_max)
- nsec = nsec_max;
- result = howmany(nsec * (uint64_t)hz, 1000000000ULL);
- if (result > MAX_JIFFY_OFFSET)
- result = MAX_JIFFY_OFFSET;
-
- return (result);
+ if (nsec > lkpi_nsec2hz_max)
+ nsec = lkpi_nsec2hz_max;
+ return (howmany(nsec * lkpi_nsec2hz_rem, lkpi_nsec2hz_div));
}
-static inline uint64_t
-nsecs_to_jiffies(uint64_t n)
+static inline unsigned long
+nsecs_to_jiffies(uint64_t nsec)
{
- return (usecs_to_jiffies(howmany(n, 1000ULL)));
+ if (sizeof(unsigned long) >= sizeof(uint64_t)) {
+ if (nsec > lkpi_nsec2hz_max)
+ nsec = lkpi_nsec2hz_max;
+ } else {
+ if (nsec > (lkpi_nsec2hz_max >> 32))
+ nsec = (lkpi_nsec2hz_max >> 32);
+ }
+ return (howmany(nsec * lkpi_nsec2hz_rem, lkpi_nsec2hz_div));
}
static inline uint64_t
Modified: stable/12/sys/compat/linuxkpi/common/src/linux_compat.c
==============================================================================
--- stable/12/sys/compat/linuxkpi/common/src/linux_compat.c Fri Mar 6 12:37:04 2020 (r358698)
+++ stable/12/sys/compat/linuxkpi/common/src/linux_compat.c Fri Mar 6 13:57:00 2020 (r358699)
@@ -1934,9 +1934,38 @@ del_timer(struct timer_list *timer)
return (1);
}
+/* greatest common divisor, Euclid equation */
+static uint64_t
+lkpi_gcd_64(uint64_t a, uint64_t b)
+{
+ uint64_t an;
+ uint64_t bn;
+
+ while (b != 0) {
+ an = b;
+ bn = a % b;
+ a = an;
+ b = bn;
+ }
+ return (a);
+}
+
+uint64_t lkpi_nsec2hz_rem;
+uint64_t lkpi_nsec2hz_div = 1000000000ULL;
+uint64_t lkpi_nsec2hz_max;
+
+uint64_t lkpi_usec2hz_rem;
+uint64_t lkpi_usec2hz_div = 1000000ULL;
+uint64_t lkpi_usec2hz_max;
+
+uint64_t lkpi_msec2hz_rem;
+uint64_t lkpi_msec2hz_div = 1000ULL;
+uint64_t lkpi_msec2hz_max;
+
static void
linux_timer_init(void *arg)
{
+ uint64_t gcd;
/*
* Compute an internal HZ value which can divide 2**32 to
@@ -1947,6 +1976,27 @@ linux_timer_init(void *arg)
while (linux_timer_hz_mask < (unsigned long)hz)
linux_timer_hz_mask *= 2;
linux_timer_hz_mask--;
+
+ /* compute some internal constants */
+
+ lkpi_nsec2hz_rem = hz;
+ lkpi_usec2hz_rem = hz;
+ lkpi_msec2hz_rem = hz;
+
+ gcd = lkpi_gcd_64(lkpi_nsec2hz_rem, lkpi_nsec2hz_div);
+ lkpi_nsec2hz_rem /= gcd;
+ lkpi_nsec2hz_div /= gcd;
+ lkpi_nsec2hz_max = -1ULL / lkpi_nsec2hz_rem;
+
+ gcd = lkpi_gcd_64(lkpi_usec2hz_rem, lkpi_usec2hz_div);
+ lkpi_usec2hz_rem /= gcd;
+ lkpi_usec2hz_div /= gcd;
+ lkpi_usec2hz_max = -1ULL / lkpi_usec2hz_rem;
+
+ gcd = lkpi_gcd_64(lkpi_msec2hz_rem, lkpi_msec2hz_div);
+ lkpi_msec2hz_rem /= gcd;
+ lkpi_msec2hz_div /= gcd;
+ lkpi_msec2hz_max = -1ULL / lkpi_msec2hz_rem;
}
SYSINIT(linux_timer, SI_SUB_DRIVERS, SI_ORDER_FIRST, linux_timer_init, NULL);
More information about the svn-src-all
mailing list