Skip to content
Permalink
Browse files
Make hrtimer granularity and minimum hrtimeout configurable in sysctl…
…. Set default granularity to 100us and min timeout to 500us.
  • Loading branch information
ckolivas authored and heftig committed Apr 28, 2021
1 parent 437c8fb commit 17886fe82995e8dbfe595e1d5de8717f3ffc73ed
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 12 deletions.
@@ -128,7 +128,9 @@ extern int sched_interactive;
extern int sched_iso_cpu;
extern int sched_yield_type;
#endif
#ifdef CONFIG_PRINTK
extern int hrtimer_granularity_us;
extern int hrtimeout_min_us;
#if defined(CONFIG_PRINTK) || defined(CONFIG_SCHED_MUQSS)
static int ten_thousand = 10000;
#endif
#ifdef CONFIG_PERF_EVENTS
@@ -1901,7 +1903,24 @@ static struct ctl_table kern_table[] = {
},
#endif /* CONFIG_SMP && CONFIG_SCHEDSTATS */
#endif /* CONFIG_SCHED_MUQSS */

{
.procname = "hrtimer_granularity_us",
.data = &hrtimer_granularity_us,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_minmax,
.extra1 = &one,
.extra2 = &ten_thousand,
},
{
.procname = "hrtimeout_min_us",
.data = &hrtimeout_min_us,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_minmax,
.extra1 = &one,
.extra2 = &ten_thousand,
},
#if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL)
{
.procname = "sched_energy_aware",
@@ -190,13 +190,9 @@ int clockevents_tick_resume(struct clock_event_device *dev)

#ifdef CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST

#ifdef CONFIG_SCHED_MUQSS
int __read_mostly hrtimer_granularity_us = 100;
/* Limit min_delta to 100us */
#define MIN_DELTA_LIMIT (NSEC_PER_SEC / 10000)
#else
/* Limit min_delta to a jiffie */
#define MIN_DELTA_LIMIT (NSEC_PER_SEC / HZ)
#endif
#define MIN_DELTA_LIMIT (hrtimer_granularity_us * NSEC_PER_USEC)

/**
* clockevents_increase_min_delta - raise minimum delta of a clock event device
@@ -2244,7 +2244,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) {
@@ -2261,9 +2261,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);
@@ -2285,9 +2284,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);

0 comments on commit 17886fe

Please sign in to comment.