aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorMister Oyster <oysterized@gmail.com>2017-06-02 13:06:55 +0200
committerMister Oyster <oysterized@gmail.com>2017-06-02 13:06:55 +0200
commit35cb977136a88ddec0cbf3c79a577316d9f5f6a8 (patch)
treec9cfe5a4a8b59ecc26be549fc63738fdfad5bfb0 /kernel
parent96d8fd737ead1c710882315112e261a0a53e0da9 (diff)
Revert "jiffies conversions: Use compile time constants when possible"
Build breaks when any of this code is included This reverts commit 9722cd7360077819a5af4937c0f742149fcec82c.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/time.c106
1 files changed, 94 insertions, 12 deletions
diff --git a/kernel/time.c b/kernel/time.c
index 27dc71b73..5d4d9a024 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -244,18 +244,41 @@ EXPORT_SYMBOL(current_fs_time);
/*
* Convert jiffies to milliseconds and back.
+ *
+ * Avoid unnecessary multiplications/divisions in the
+ * two most common HZ cases:
*/
-unsigned int __jiffies_to_msecs(const unsigned long j)
+unsigned int jiffies_to_msecs(const unsigned long j)
{
- return __inline_jiffies_to_msecs(j);
+#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
+ return (MSEC_PER_SEC / HZ) * j;
+#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
+ return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
+#else
+# if BITS_PER_LONG == 32
+ return (HZ_TO_MSEC_MUL32 * j) >> HZ_TO_MSEC_SHR32;
+# else
+ return (j * HZ_TO_MSEC_NUM) / HZ_TO_MSEC_DEN;
+# endif
+#endif
}
-EXPORT_SYMBOL(__jiffies_to_msecs);
+EXPORT_SYMBOL(jiffies_to_msecs);
-unsigned int __jiffies_to_usecs(const unsigned long j)
+unsigned int jiffies_to_usecs(const unsigned long j)
{
- return __inline_jiffies_to_usecs(j);
+#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
+ return (USEC_PER_SEC / HZ) * j;
+#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
+ return (j + (HZ / USEC_PER_SEC) - 1)/(HZ / USEC_PER_SEC);
+#else
+# if BITS_PER_LONG == 32
+ return (HZ_TO_USEC_MUL32 * j) >> HZ_TO_USEC_SHR32;
+# else
+ return (j * HZ_TO_USEC_NUM) / HZ_TO_USEC_DEN;
+# endif
+#endif
}
-EXPORT_SYMBOL(__jiffies_to_usecs);
+EXPORT_SYMBOL(jiffies_to_usecs);
/**
* timespec_trunc - Truncate timespec to a granularity
@@ -404,17 +427,76 @@ struct timeval ns_to_timeval(const s64 nsec)
}
EXPORT_SYMBOL(ns_to_timeval);
-unsigned long __msecs_to_jiffies(const unsigned int m)
+/*
+ * When we convert to jiffies then we interpret incoming values
+ * the following way:
+ *
+ * - negative values mean 'infinite timeout' (MAX_JIFFY_OFFSET)
+ *
+ * - 'too large' values [that would result in larger than
+ * MAX_JIFFY_OFFSET values] mean 'infinite timeout' too.
+ *
+ * - all other values are converted to jiffies by either multiplying
+ * the input value by a factor or dividing it with a factor
+ *
+ * We must also be careful about 32-bit overflows.
+ */
+unsigned long msecs_to_jiffies(const unsigned int m)
{
- return __inline_msecs_to_jiffies(m);
+ /*
+ * Negative value, means infinite timeout:
+ */
+ if ((int)m < 0)
+ return MAX_JIFFY_OFFSET;
+
+#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
+ /*
+ * HZ is equal to or smaller than 1000, and 1000 is a nice
+ * round multiple of HZ, divide with the factor between them,
+ * but round upwards:
+ */
+ return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ);
+#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
+ /*
+ * HZ is larger than 1000, and HZ is a nice round multiple of
+ * 1000 - simply multiply with the factor between them.
+ *
+ * But first make sure the multiplication result cannot
+ * overflow:
+ */
+ if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
+ return MAX_JIFFY_OFFSET;
+
+ return m * (HZ / MSEC_PER_SEC);
+#else
+ /*
+ * Generic case - multiply, round and divide. But first
+ * check that if we are doing a net multiplication, that
+ * we wouldn't overflow:
+ */
+ if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
+ return MAX_JIFFY_OFFSET;
+
+ return (MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32)
+ >> MSEC_TO_HZ_SHR32;
+#endif
}
-EXPORT_SYMBOL(__msecs_to_jiffies);
+EXPORT_SYMBOL(msecs_to_jiffies);
-unsigned long __usecs_to_jiffies(const unsigned int u)
+unsigned long usecs_to_jiffies(const unsigned int u)
{
- return __inline_usecs_to_jiffies(u);
+ if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET))
+ return MAX_JIFFY_OFFSET;
+#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
+ return (u + (USEC_PER_SEC / HZ) - 1) / (USEC_PER_SEC / HZ);
+#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
+ return u * (HZ / USEC_PER_SEC);
+#else
+ return (USEC_TO_HZ_MUL32 * u + USEC_TO_HZ_ADJ32)
+ >> USEC_TO_HZ_SHR32;
+#endif
}
-EXPORT_SYMBOL(__usecs_to_jiffies);
+EXPORT_SYMBOL(usecs_to_jiffies);
/*
* The TICK_NSEC - 1 rounds up the value to the next resolution. Note