Skip to content

Commit

Permalink
clockevents, hrtimer: Make hrtimer granularity and minimum hrtimeout …
Browse files Browse the repository at this point in the history
…configurable in sysctl. Set default granularity to 100us and min timeout to 500us

Rebased-by: Alexandre Frade <kernel@xanmod.org>
  • Loading branch information
ckolivas authored and xanmod committed Nov 4, 2021
1 parent 5e67c25 commit 4fdad1c
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 7 deletions.
22 changes: 20 additions & 2 deletions kernel/sysctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ static unsigned long long_max = LONG_MAX;
static int one_hundred = 100;
static int two_hundred = 200;
static int one_thousand = 1000;
#ifdef CONFIG_PRINTK
static int ten_thousand = 10000;
#endif
extern int hrtimer_granularity_us;
extern int hrtimeout_min_us;
#ifdef CONFIG_PERF_EVENTS
static int six_hundred_forty_kb = 640 * 1024;
#endif
Expand Down Expand Up @@ -1771,6 +1771,24 @@ int proc_do_static_key(struct ctl_table *table, int write,
}

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 = "sched_child_runs_first",
.data = &sysctl_sched_child_runs_first,
Expand Down
3 changes: 2 additions & 1 deletion kernel/time/clockevents.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
49 changes: 45 additions & 4 deletions kernel/time/hrtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -2392,7 +2392,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) {
Expand All @@ -2409,9 +2409,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);
Expand All @@ -2433,9 +2432,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);
Expand Down

0 comments on commit 4fdad1c

Please sign in to comment.