mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge tag 'timers-core-2025-11-30' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer core updates from Thomas Gleixner:
- Prevent a thundering herd problem when the timekeeper CPU is delayed
and a large number of CPUs compete to acquire jiffies_lock to do the
update. Limit it to one CPU with a separate "uncontended" atomic
variable.
- A set of improvements for the timer migration mechanism:
- Support imbalanced NUMA trees correctly
- Support dynamic exclusion of CPUs from the migrator duty to allow
the cpuset/isolation mechanism to exclude them from handling
timers of remote idle CPUs
- The usual small updates, cleanups and enhancements
* tag 'timers-core-2025-11-30' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
timers/migration: Exclude isolated cpus from hierarchy
cpumask: Add initialiser to use cleanup helpers
sched/isolation: Force housekeeping if isolcpus and nohz_full don't leave any
cgroup/cpuset: Rename update_unbound_workqueue_cpumask() to update_isolation_cpumasks()
timers/migration: Use scoped_guard on available flag set/clear
timers/migration: Add mask for CPUs available in the hierarchy
timers/migration: Rename 'online' bit to 'available'
selftests/timers/nanosleep: Add tests for return of remaining time
selftests/timers: Clean up kernel version check in posix_timers
time: Fix a few typos in time[r] related code comments
time: tick-oneshot: Add missing Return and parameter descriptions to kernel-doc
hrtimer: Store time as ktime_t in restart block
timers/migration: Remove dead code handling idle CPU checking for remote timers
timers/migration: Remove unused "cpu" parameter from tmigr_get_group()
timers/migration: Assert that hotplug preparing CPU is part of stable active hierarchy
timers/migration: Fix imbalanced NUMA trees
timers/migration: Remove locking on group connection
timers/migration: Convert "while" loops to use "for"
tick/sched: Limit non-timekeeper CPUs calling jiffies update
This commit is contained in:
@@ -1022,6 +1022,7 @@ static __always_inline unsigned int cpumask_size(void)
|
||||
|
||||
#define this_cpu_cpumask_var_ptr(x) this_cpu_read(x)
|
||||
#define __cpumask_var_read_mostly __read_mostly
|
||||
#define CPUMASK_VAR_NULL NULL
|
||||
|
||||
bool alloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags, int node);
|
||||
|
||||
@@ -1068,6 +1069,7 @@ static __always_inline bool cpumask_available(cpumask_var_t mask)
|
||||
|
||||
#define this_cpu_cpumask_var_ptr(x) this_cpu_ptr(x)
|
||||
#define __cpumask_var_read_mostly
|
||||
#define CPUMASK_VAR_NULL {}
|
||||
|
||||
static __always_inline bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags)
|
||||
{
|
||||
|
||||
@@ -68,7 +68,7 @@ void usleep_range_state(unsigned long min, unsigned long max,
|
||||
* @min: Minimum time in microseconds to sleep
|
||||
* @max: Maximum time in microseconds to sleep
|
||||
*
|
||||
* For basic information please refere to usleep_range_state().
|
||||
* For basic information please refer to usleep_range_state().
|
||||
*
|
||||
* The task will be in the state TASK_UNINTERRUPTIBLE during the sleep.
|
||||
*/
|
||||
@@ -82,10 +82,10 @@ static inline void usleep_range(unsigned long min, unsigned long max)
|
||||
* @min: Minimum time in microseconds to sleep
|
||||
* @max: Maximum time in microseconds to sleep
|
||||
*
|
||||
* For basic information please refere to usleep_range_state().
|
||||
* For basic information please refer to usleep_range_state().
|
||||
*
|
||||
* The sleeping task has the state TASK_IDLE during the sleep to prevent
|
||||
* contribution to the load avarage.
|
||||
* contribution to the load average.
|
||||
*/
|
||||
static inline void usleep_range_idle(unsigned long min, unsigned long max)
|
||||
{
|
||||
@@ -96,7 +96,7 @@ static inline void usleep_range_idle(unsigned long min, unsigned long max)
|
||||
* ssleep - wrapper for seconds around msleep
|
||||
* @seconds: Requested sleep duration in seconds
|
||||
*
|
||||
* Please refere to msleep() for detailed information.
|
||||
* Please refer to msleep() for detailed information.
|
||||
*/
|
||||
static inline void ssleep(unsigned int seconds)
|
||||
{
|
||||
|
||||
@@ -43,7 +43,7 @@ struct restart_block {
|
||||
struct __kernel_timespec __user *rmtp;
|
||||
struct old_timespec32 __user *compat_rmtp;
|
||||
};
|
||||
u64 expires;
|
||||
ktime_t expires;
|
||||
} nanosleep;
|
||||
/* For poll */
|
||||
struct {
|
||||
|
||||
@@ -188,4 +188,13 @@ int timers_dead_cpu(unsigned int cpu);
|
||||
#define timers_dead_cpu NULL
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON)
|
||||
extern int tmigr_isolated_exclude_cpumask(struct cpumask *exclude_cpumask);
|
||||
#else
|
||||
static inline int tmigr_isolated_exclude_cpumask(struct cpumask *exclude_cpumask)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -173,14 +173,14 @@ DEFINE_EVENT(tmigr_cpugroup, tmigr_cpu_active,
|
||||
TP_ARGS(tmc)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(tmigr_cpugroup, tmigr_cpu_online,
|
||||
DEFINE_EVENT(tmigr_cpugroup, tmigr_cpu_available,
|
||||
|
||||
TP_PROTO(struct tmigr_cpu *tmc),
|
||||
|
||||
TP_ARGS(tmc)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(tmigr_cpugroup, tmigr_cpu_offline,
|
||||
DEFINE_EVENT(tmigr_cpugroup, tmigr_cpu_unavailable,
|
||||
|
||||
TP_PROTO(struct tmigr_cpu *tmc),
|
||||
|
||||
|
||||
@@ -1391,7 +1391,7 @@ static bool partition_xcpus_del(int old_prs, struct cpuset *parent,
|
||||
return isolcpus_updated;
|
||||
}
|
||||
|
||||
static void update_unbound_workqueue_cpumask(bool isolcpus_updated)
|
||||
static void update_isolation_cpumasks(bool isolcpus_updated)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -1402,6 +1402,9 @@ static void update_unbound_workqueue_cpumask(bool isolcpus_updated)
|
||||
|
||||
ret = workqueue_unbound_exclude_cpumask(isolated_cpus);
|
||||
WARN_ON_ONCE(ret < 0);
|
||||
|
||||
ret = tmigr_isolated_exclude_cpumask(isolated_cpus);
|
||||
WARN_ON_ONCE(ret < 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1555,7 +1558,7 @@ static int remote_partition_enable(struct cpuset *cs, int new_prs,
|
||||
list_add(&cs->remote_sibling, &remote_children);
|
||||
cpumask_copy(cs->effective_xcpus, tmp->new_cpus);
|
||||
spin_unlock_irq(&callback_lock);
|
||||
update_unbound_workqueue_cpumask(isolcpus_updated);
|
||||
update_isolation_cpumasks(isolcpus_updated);
|
||||
cpuset_force_rebuild();
|
||||
cs->prs_err = 0;
|
||||
|
||||
@@ -1596,7 +1599,7 @@ static void remote_partition_disable(struct cpuset *cs, struct tmpmasks *tmp)
|
||||
compute_excpus(cs, cs->effective_xcpus);
|
||||
reset_partition_data(cs);
|
||||
spin_unlock_irq(&callback_lock);
|
||||
update_unbound_workqueue_cpumask(isolcpus_updated);
|
||||
update_isolation_cpumasks(isolcpus_updated);
|
||||
cpuset_force_rebuild();
|
||||
|
||||
/*
|
||||
@@ -1665,7 +1668,7 @@ static void remote_cpus_update(struct cpuset *cs, struct cpumask *xcpus,
|
||||
if (xcpus)
|
||||
cpumask_copy(cs->exclusive_cpus, xcpus);
|
||||
spin_unlock_irq(&callback_lock);
|
||||
update_unbound_workqueue_cpumask(isolcpus_updated);
|
||||
update_isolation_cpumasks(isolcpus_updated);
|
||||
if (adding || deleting)
|
||||
cpuset_force_rebuild();
|
||||
|
||||
@@ -2023,7 +2026,7 @@ write_error:
|
||||
WARN_ON_ONCE(parent->nr_subparts < 0);
|
||||
}
|
||||
spin_unlock_irq(&callback_lock);
|
||||
update_unbound_workqueue_cpumask(isolcpus_updated);
|
||||
update_isolation_cpumasks(isolcpus_updated);
|
||||
|
||||
if ((old_prs != new_prs) && (cmd == partcmd_update))
|
||||
update_partition_exclusive_flag(cs, new_prs);
|
||||
@@ -3043,7 +3046,7 @@ out:
|
||||
else if (isolcpus_updated)
|
||||
isolated_cpus_update(old_prs, new_prs, cs->effective_xcpus);
|
||||
spin_unlock_irq(&callback_lock);
|
||||
update_unbound_workqueue_cpumask(isolcpus_updated);
|
||||
update_isolation_cpumasks(isolcpus_updated);
|
||||
|
||||
/* Force update if switching back to member & update effective_xcpus */
|
||||
update_cpumasks_hier(cs, &tmpmask, !new_prs);
|
||||
|
||||
@@ -167,6 +167,29 @@ static int __init housekeeping_setup(char *str, unsigned long flags)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the combination of nohz_full and isolcpus=domain,
|
||||
* necessary to avoid problems with the timer migration
|
||||
* hierarchy. managed_irq is ignored by this check since it
|
||||
* isn't considered in the timer migration logic.
|
||||
*/
|
||||
iter_flags = housekeeping.flags & (HK_FLAG_KERNEL_NOISE | HK_FLAG_DOMAIN);
|
||||
type = find_first_bit(&iter_flags, HK_TYPE_MAX);
|
||||
/*
|
||||
* Pass the check if none of these flags were previously set or
|
||||
* are not in the current selection.
|
||||
*/
|
||||
iter_flags = flags & (HK_FLAG_KERNEL_NOISE | HK_FLAG_DOMAIN);
|
||||
first_cpu = (type == HK_TYPE_MAX || !iter_flags) ? 0 :
|
||||
cpumask_first_and_and(cpu_present_mask,
|
||||
housekeeping_staging, housekeeping.cpumasks[type]);
|
||||
if (first_cpu >= min(nr_cpu_ids, setup_max_cpus)) {
|
||||
pr_warn("Housekeeping: must include one present CPU "
|
||||
"neither in nohz_full= nor in isolcpus=domain, "
|
||||
"ignoring setting %s\n", str);
|
||||
goto free_housekeeping_staging;
|
||||
}
|
||||
|
||||
iter_flags = flags & ~housekeeping.flags;
|
||||
|
||||
for_each_set_bit(type, &iter_flags, HK_TYPE_MAX)
|
||||
|
||||
@@ -2145,7 +2145,7 @@ static long __sched hrtimer_nanosleep_restart(struct restart_block *restart)
|
||||
int ret;
|
||||
|
||||
hrtimer_setup_sleeper_on_stack(&t, restart->nanosleep.clockid, HRTIMER_MODE_ABS);
|
||||
hrtimer_set_expires_tv64(&t.timer, restart->nanosleep.expires);
|
||||
hrtimer_set_expires(&t.timer, restart->nanosleep.expires);
|
||||
ret = do_nanosleep(&t, HRTIMER_MODE_ABS);
|
||||
destroy_hrtimer_on_stack(&t.timer);
|
||||
return ret;
|
||||
@@ -2172,7 +2172,7 @@ long hrtimer_nanosleep(ktime_t rqtp, const enum hrtimer_mode mode,
|
||||
|
||||
restart = ¤t->restart_block;
|
||||
restart->nanosleep.clockid = t.timer.base->clockid;
|
||||
restart->nanosleep.expires = hrtimer_get_expires_tv64(&t.timer);
|
||||
restart->nanosleep.expires = hrtimer_get_expires(&t.timer);
|
||||
set_restart_fn(restart, hrtimer_nanosleep_restart);
|
||||
out:
|
||||
destroy_hrtimer_on_stack(&t.timer);
|
||||
|
||||
@@ -1557,7 +1557,7 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,
|
||||
* Report back to the user the time still remaining.
|
||||
*/
|
||||
restart = ¤t->restart_block;
|
||||
restart->nanosleep.expires = expires;
|
||||
restart->nanosleep.expires = ns_to_ktime(expires);
|
||||
if (restart->nanosleep.type != TT_NONE)
|
||||
error = nanosleep_copyout(restart, &it.it_value);
|
||||
}
|
||||
@@ -1599,7 +1599,7 @@ static long posix_cpu_nsleep_restart(struct restart_block *restart_block)
|
||||
clockid_t which_clock = restart_block->nanosleep.clockid;
|
||||
struct timespec64 t;
|
||||
|
||||
t = ns_to_timespec64(restart_block->nanosleep.expires);
|
||||
t = ktime_to_timespec64(restart_block->nanosleep.expires);
|
||||
|
||||
return do_cpu_nanosleep(which_clock, TIMER_ABSTIME, &t);
|
||||
}
|
||||
|
||||
@@ -1242,7 +1242,7 @@ SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock,
|
||||
* sys_clock_settime(). The kernel internal timekeeping is always using
|
||||
* nanoseconds precision independent of the clocksource device which is
|
||||
* used to read the time from. The resolution of that device only
|
||||
* affects the presicion of the time returned by sys_clock_gettime().
|
||||
* affects the precision of the time returned by sys_clock_gettime().
|
||||
*
|
||||
* Returns:
|
||||
* 0 Success. @tp contains the resolution
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
|
||||
/**
|
||||
* tick_program_event - program the CPU local timer device for the next event
|
||||
* @expires: the time at which the next timer event should occur
|
||||
* @force: flag to force reprograming even if the event time hasn't changed
|
||||
*
|
||||
* Return: 0 on success, negative error code on failure
|
||||
*/
|
||||
int tick_program_event(ktime_t expires, int force)
|
||||
{
|
||||
@@ -57,6 +61,13 @@ void tick_resume_oneshot(void)
|
||||
|
||||
/**
|
||||
* tick_setup_oneshot - setup the event device for oneshot mode (hres or nohz)
|
||||
* @newdev: Pointer to the clock event device to configure
|
||||
* @handler: Function to be called when the event device triggers an interrupt
|
||||
* @next_event: Initial expiry time for the next event (in ktime)
|
||||
*
|
||||
* Configures the specified clock event device for onshot mode,
|
||||
* assigns the given handler as its event callback, and programs
|
||||
* the device to trigger at the specified next event time.
|
||||
*/
|
||||
void tick_setup_oneshot(struct clock_event_device *newdev,
|
||||
void (*handler)(struct clock_event_device *),
|
||||
@@ -69,6 +80,10 @@ void tick_setup_oneshot(struct clock_event_device *newdev,
|
||||
|
||||
/**
|
||||
* tick_switch_to_oneshot - switch to oneshot mode
|
||||
* @handler: function to call when an event occurs on the tick device
|
||||
*
|
||||
* Return: 0 on success, -EINVAL if the tick device is not present,
|
||||
* not functional, or does not support oneshot mode.
|
||||
*/
|
||||
int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *))
|
||||
{
|
||||
@@ -101,7 +116,7 @@ int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *))
|
||||
/**
|
||||
* tick_oneshot_mode_active - check whether the system is in oneshot mode
|
||||
*
|
||||
* returns 1 when either nohz or highres are enabled. otherwise 0.
|
||||
* Return: 1 when either nohz or highres are enabled, otherwise 0.
|
||||
*/
|
||||
int tick_oneshot_mode_active(void)
|
||||
{
|
||||
@@ -120,6 +135,9 @@ int tick_oneshot_mode_active(void)
|
||||
* tick_init_highres - switch to high resolution mode
|
||||
*
|
||||
* Called with interrupts disabled.
|
||||
*
|
||||
* Return: 0 on success, -EINVAL if the tick device cannot switch
|
||||
* to oneshot/high-resolution mode.
|
||||
*/
|
||||
int tick_init_highres(void)
|
||||
{
|
||||
|
||||
@@ -201,6 +201,27 @@ static inline void tick_sched_flag_clear(struct tick_sched *ts,
|
||||
ts->flags &= ~flag;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allow only one non-timekeeper CPU at a time update jiffies from
|
||||
* the timer tick.
|
||||
*
|
||||
* Returns true if update was run.
|
||||
*/
|
||||
static bool tick_limited_update_jiffies64(struct tick_sched *ts, ktime_t now)
|
||||
{
|
||||
static atomic_t in_progress;
|
||||
int inp;
|
||||
|
||||
inp = atomic_read(&in_progress);
|
||||
if (inp || !atomic_try_cmpxchg(&in_progress, &inp, 1))
|
||||
return false;
|
||||
|
||||
if (ts->last_tick_jiffies == jiffies)
|
||||
tick_do_update_jiffies64(now);
|
||||
atomic_set(&in_progress, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
#define MAX_STALLED_JIFFIES 5
|
||||
|
||||
static void tick_sched_do_timer(struct tick_sched *ts, ktime_t now)
|
||||
@@ -239,10 +260,11 @@ static void tick_sched_do_timer(struct tick_sched *ts, ktime_t now)
|
||||
ts->stalled_jiffies = 0;
|
||||
ts->last_tick_jiffies = READ_ONCE(jiffies);
|
||||
} else {
|
||||
if (++ts->stalled_jiffies == MAX_STALLED_JIFFIES) {
|
||||
tick_do_update_jiffies64(now);
|
||||
ts->stalled_jiffies = 0;
|
||||
ts->last_tick_jiffies = READ_ONCE(jiffies);
|
||||
if (++ts->stalled_jiffies >= MAX_STALLED_JIFFIES) {
|
||||
if (tick_limited_update_jiffies64(ts, now)) {
|
||||
ts->stalled_jiffies = 0;
|
||||
ts->last_tick_jiffies = READ_ONCE(jiffies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+332
-169
File diff suppressed because it is too large
Load Diff
@@ -97,7 +97,7 @@ struct tmigr_group {
|
||||
*/
|
||||
struct tmigr_cpu {
|
||||
raw_spinlock_t lock;
|
||||
bool online;
|
||||
bool available;
|
||||
bool idle;
|
||||
bool remote;
|
||||
struct tmigr_group *tmgroup;
|
||||
|
||||
@@ -116,6 +116,56 @@ int nanosleep_test(int clockid, long long ns)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dummy_event_handler(int val)
|
||||
{
|
||||
/* No action needed */
|
||||
}
|
||||
|
||||
static int nanosleep_test_remaining(int clockid)
|
||||
{
|
||||
struct timespec rqtp = {}, rmtp = {};
|
||||
struct itimerspec itimer = {};
|
||||
struct sigaction sa = {};
|
||||
timer_t timer;
|
||||
int ret;
|
||||
|
||||
sa.sa_handler = dummy_event_handler;
|
||||
ret = sigaction(SIGALRM, &sa, NULL);
|
||||
if (ret)
|
||||
return -1;
|
||||
|
||||
ret = timer_create(clockid, NULL, &timer);
|
||||
if (ret)
|
||||
return -1;
|
||||
|
||||
itimer.it_value.tv_nsec = NSEC_PER_SEC / 4;
|
||||
ret = timer_settime(timer, 0, &itimer, NULL);
|
||||
if (ret)
|
||||
return -1;
|
||||
|
||||
rqtp.tv_nsec = NSEC_PER_SEC / 2;
|
||||
ret = clock_nanosleep(clockid, 0, &rqtp, &rmtp);
|
||||
if (ret != EINTR)
|
||||
return -1;
|
||||
|
||||
ret = timer_delete(timer);
|
||||
if (ret)
|
||||
return -1;
|
||||
|
||||
sa.sa_handler = SIG_DFL;
|
||||
ret = sigaction(SIGALRM, &sa, NULL);
|
||||
if (ret)
|
||||
return -1;
|
||||
|
||||
if (!in_order((struct timespec) {}, rmtp))
|
||||
return -1;
|
||||
|
||||
if (!in_order(rmtp, rqtp))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
long long length;
|
||||
@@ -150,6 +200,11 @@ int main(int argc, char **argv)
|
||||
}
|
||||
length *= 100;
|
||||
}
|
||||
ret = nanosleep_test_remaining(clockid);
|
||||
if (ret < 0) {
|
||||
ksft_test_result_fail("%-31s\n", clockstring(clockid));
|
||||
ksft_exit_fail();
|
||||
}
|
||||
ksft_test_result_pass("%-31s\n", clockstring(clockid));
|
||||
next:
|
||||
ret = 0;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <time.h>
|
||||
#include <include/vdso/time64.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "../kselftest.h"
|
||||
|
||||
@@ -670,8 +671,14 @@ static void check_timer_create_exact(void)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
bool run_sig_ign_tests = ksft_min_kernel_version(6, 13);
|
||||
|
||||
ksft_print_header();
|
||||
ksft_set_plan(19);
|
||||
if (run_sig_ign_tests) {
|
||||
ksft_set_plan(19);
|
||||
} else {
|
||||
ksft_set_plan(10);
|
||||
}
|
||||
|
||||
ksft_print_msg("Testing posix timers. False negative may happen on CPU execution \n");
|
||||
ksft_print_msg("based timers if other threads run on the CPU...\n");
|
||||
@@ -695,15 +702,20 @@ int main(int argc, char **argv)
|
||||
check_timer_create(CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID");
|
||||
check_timer_distribution();
|
||||
|
||||
check_sig_ign(0);
|
||||
check_sig_ign(1);
|
||||
check_rearm();
|
||||
check_delete();
|
||||
check_sigev_none(CLOCK_MONOTONIC, "CLOCK_MONOTONIC");
|
||||
check_sigev_none(CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID");
|
||||
check_gettime(CLOCK_MONOTONIC, "CLOCK_MONOTONIC");
|
||||
check_gettime(CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID");
|
||||
check_gettime(CLOCK_THREAD_CPUTIME_ID, "CLOCK_THREAD_CPUTIME_ID");
|
||||
if (run_sig_ign_tests) {
|
||||
check_sig_ign(0);
|
||||
check_sig_ign(1);
|
||||
check_rearm();
|
||||
check_delete();
|
||||
check_sigev_none(CLOCK_MONOTONIC, "CLOCK_MONOTONIC");
|
||||
check_sigev_none(CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID");
|
||||
check_gettime(CLOCK_MONOTONIC, "CLOCK_MONOTONIC");
|
||||
check_gettime(CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID");
|
||||
check_gettime(CLOCK_THREAD_CPUTIME_ID, "CLOCK_THREAD_CPUTIME_ID");
|
||||
} else {
|
||||
ksft_print_msg("Skipping SIG_IGN tests on kernel < 6.13\n");
|
||||
}
|
||||
|
||||
check_overrun(CLOCK_MONOTONIC, "CLOCK_MONOTONIC");
|
||||
check_overrun(CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID");
|
||||
check_overrun(CLOCK_THREAD_CPUTIME_ID, "CLOCK_THREAD_CPUTIME_ID");
|
||||
|
||||
Reference in New Issue
Block a user