Created
March 22, 2023 21:58
-
-
Save glitsj16/46ba4eebbde9727577c2a2075dfda3c1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 308a45413e82f6be1bf10864f5f9eab6bf0dd799 Mon Sep 17 00:00:00 2001 | |
From: graysky <therealgraysky@proton.me> | |
Date: Wed, 5 Oct 2022 05:45:01 -0400 | |
Subject: [PATCH 8/8] clockevents, hrtimer: Make hrtimer granularity and | |
minimum hrtimeout configurable in sysctl. Set default granularity to 100us | |
and min timeout to 500us | |
--- | |
kernel/sysctl.c | 21 +++++++++++++++++ | |
kernel/time/clockevents.c | 3 ++- | |
kernel/time/hrtimer.c | 49 +++++++++++++++++++++++++++++++++++---- | |
3 files changed, 68 insertions(+), 5 deletions(-) | |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c | |
index c6d9dec11b74..1c806db94b22 100644 | |
--- a/kernel/sysctl.c | |
+++ b/kernel/sysctl.c | |
@@ -92,6 +92,9 @@ EXPORT_SYMBOL_GPL(sysctl_long_vals); | |
#if defined(CONFIG_SYSCTL) | |
/* Constants used for minimum and maximum */ | |
+static int ten_thousand = 10000; | |
+extern int hrtimer_granularity_us; | |
+extern int hrtimeout_min_us; | |
#ifdef CONFIG_PERF_EVENTS | |
static const int six_hundred_forty_kb = 640 * 1024; | |
@@ -1642,6 +1642,24 @@ | |
static struct ctl_table kern_table[] = { | |
{ | |
+ .procname = "hrtimer_granularity_us", | |
+ .data = &hrtimer_granularity_us, | |
+ .maxlen = sizeof(int), | |
+ .mode = 0644, | |
+ .proc_handler = &proc_dointvec_minmax, | |
+ .extra1 = SYSCTL_ONE, | |
+ .extra2 = &ten_thousand, | |
+ }, | |
+ { | |
+ .procname = "hrtimeout_min_us", | |
+ .data = &hrtimeout_min_us, | |
+ .maxlen = sizeof(int), | |
+ .mode = 0644, | |
+ .proc_handler = &proc_dointvec_minmax, | |
+ .extra1 = SYSCTL_ONE, | |
+ .extra2 = &ten_thousand, | |
+ }, | |
+ { | |
.procname = "panic", | |
.data = &panic_timeout, | |
.maxlen = sizeof(int), | |
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c | |
index 5d85014d59b5..50406e057791 100644 | |
--- a/kernel/time/clockevents.c | |
+++ b/kernel/time/clockevents.c | |
@@ -190,8 +190,9 @@ int clockevents_tick_resume(struct clock_event_device *dev) | |
#ifdef CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST | |
+int __read_mostly hrtimer_granularity_us = 100; | |
/* Limit min_delta to a jiffie */ | |
-#define MIN_DELTA_LIMIT (NSEC_PER_SEC / HZ) | |
+#define MIN_DELTA_LIMIT (hrtimer_granularity_us * NSEC_PER_USEC) | |
/** | |
* clockevents_increase_min_delta - raise minimum delta of a clock event device | |
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c | |
index f29c00e9709c..b2352612b8ea 100644 | |
--- a/kernel/time/hrtimer.c | |
+++ b/kernel/time/hrtimer.c | |
@@ -2393,7 +2393,7 @@ EXPORT_SYMBOL_GPL(schedule_hrtimeout); | |
long __sched schedule_msec_hrtimeout(long timeout) | |
{ | |
struct hrtimer_sleeper t; | |
- int delta, secs, jiffs; | |
+ int delta, jiffs; | |
ktime_t expires; | |
if (!timeout) { | |
@@ -2410,9 +2410,8 @@ long __sched schedule_msec_hrtimeout(long timeout) | |
if (jiffs > 4 || hrtimer_resolution >= NSEC_PER_SEC / HZ || pm_freezing) | |
return schedule_timeout(jiffs); | |
- secs = timeout / 1000; | |
delta = (timeout % 1000) * NSEC_PER_MSEC; | |
- expires = ktime_set(secs, delta); | |
+ expires = ktime_set(0, delta); | |
hrtimer_init_sleeper_on_stack(&t, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | |
hrtimer_set_expires_range_ns(&t.timer, expires, delta); | |
@@ -2434,9 +2433,51 @@ long __sched schedule_msec_hrtimeout(long timeout) | |
EXPORT_SYMBOL(schedule_msec_hrtimeout); | |
+#define USECS_PER_SEC 1000000 | |
+extern int hrtimer_granularity_us; | |
+ | |
+static inline long schedule_usec_hrtimeout(long timeout) | |
+{ | |
+ struct hrtimer_sleeper t; | |
+ ktime_t expires; | |
+ int delta; | |
+ | |
+ if (!timeout) { | |
+ __set_current_state(TASK_RUNNING); | |
+ return 0; | |
+ } | |
+ | |
+ if (hrtimer_resolution >= NSEC_PER_SEC / HZ) | |
+ return schedule_timeout(usecs_to_jiffies(timeout)); | |
+ | |
+ if (timeout < hrtimer_granularity_us) | |
+ timeout = hrtimer_granularity_us; | |
+ delta = (timeout % USECS_PER_SEC) * NSEC_PER_USEC; | |
+ expires = ktime_set(0, delta); | |
+ | |
+ hrtimer_init_sleeper_on_stack(&t, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | |
+ hrtimer_set_expires_range_ns(&t.timer, expires, delta); | |
+ | |
+ hrtimer_sleeper_start_expires(&t, HRTIMER_MODE_REL); | |
+ | |
+ if (likely(t.task)) | |
+ schedule(); | |
+ | |
+ hrtimer_cancel(&t.timer); | |
+ destroy_hrtimer_on_stack(&t.timer); | |
+ | |
+ __set_current_state(TASK_RUNNING); | |
+ | |
+ expires = hrtimer_expires_remaining(&t.timer); | |
+ timeout = ktime_to_us(expires); | |
+ return timeout < 0 ? 0 : timeout; | |
+} | |
+ | |
+int __read_mostly hrtimeout_min_us = 500; | |
+ | |
long __sched schedule_min_hrtimeout(void) | |
{ | |
- return schedule_msec_hrtimeout(1); | |
+ return usecs_to_jiffies(schedule_usec_hrtimeout(hrtimeout_min_us)); | |
} | |
EXPORT_SYMBOL(schedule_min_hrtimeout); | |
-- | |
2.39.0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment