Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull core timer updates from Thomas Gleixner: "Timers and timekeeping updates: - A large overhaul of the posix CPU timer code which is a preparation for moving the CPU timer expiry out into task work so it can be properly accounted on the task/process. An update to the bogus permission checks will come later during the merge window as feedback was not complete before heading of for travel. - Switch the timerqueue code to use cached rbtrees and get rid of the homebrewn caching of the leftmost node. - Consolidate hrtimer_init() + hrtimer_init_sleeper() calls into a single function - Implement the separation of hrtimers to be forced to expire in hard interrupt context even when PREEMPT_RT is enabled and mark the affected timers accordingly. - Implement a mechanism for hrtimers and the timer wheel to protect RT against priority inversion and live lock issues when a (hr)timer which should be canceled is currently executing the callback. Instead of infinitely spinning, the task which tries to cancel the timer blocks on a per cpu base expiry lock which is held and released by the (hr)timer expiry code. - Enable the Hyper-V TSC page based sched_clock for Hyper-V guests resulting in faster access to timekeeping functions. - Updates to various clocksource/clockevent drivers and their device tree bindings. - The usual small improvements all over the place" * 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (101 commits) posix-cpu-timers: Fix permission check regression posix-cpu-timers: Always clear head pointer on dequeue hrtimer: Add a missing bracket and hide `migration_base' on !SMP posix-cpu-timers: Make expiry_active check actually work correctly posix-timers: Unbreak CONFIG_POSIX_TIMERS=n build tick: Mark sched_timer to expire in hard interrupt context hrtimer: Add kernel doc annotation for HRTIMER_MODE_HARD x86/hyperv: Hide pv_ops access for CONFIG_PARAVIRT=n posix-cpu-timers: Utilize timerqueue for storage posix-cpu-timers: Move state tracking to struct posix_cputimers posix-cpu-timers: Deduplicate rlimit handling posix-cpu-timers: Remove pointless comparisons posix-cpu-timers: Get rid of 64bit divisions posix-cpu-timers: Consolidate timer expiry further posix-cpu-timers: Get rid of zero checks rlimit: Rewrite non-sensical RLIMIT_CPU comment posix-cpu-timers: Respect INFINITY for hard RTTIME limit posix-cpu-timers: Switch thread group sampling to array posix-cpu-timers: Restructure expiry array posix-cpu-timers: Remove cputime_expires ...
This commit is contained in:
@@ -26,9 +26,10 @@
|
||||
*/
|
||||
bool timerqueue_add(struct timerqueue_head *head, struct timerqueue_node *node)
|
||||
{
|
||||
struct rb_node **p = &head->head.rb_node;
|
||||
struct rb_node **p = &head->rb_root.rb_root.rb_node;
|
||||
struct rb_node *parent = NULL;
|
||||
struct timerqueue_node *ptr;
|
||||
struct timerqueue_node *ptr;
|
||||
bool leftmost = true;
|
||||
|
||||
/* Make sure we don't add nodes that are already added */
|
||||
WARN_ON_ONCE(!RB_EMPTY_NODE(&node->node));
|
||||
@@ -36,19 +37,17 @@ bool timerqueue_add(struct timerqueue_head *head, struct timerqueue_node *node)
|
||||
while (*p) {
|
||||
parent = *p;
|
||||
ptr = rb_entry(parent, struct timerqueue_node, node);
|
||||
if (node->expires < ptr->expires)
|
||||
if (node->expires < ptr->expires) {
|
||||
p = &(*p)->rb_left;
|
||||
else
|
||||
} else {
|
||||
p = &(*p)->rb_right;
|
||||
leftmost = false;
|
||||
}
|
||||
}
|
||||
rb_link_node(&node->node, parent, p);
|
||||
rb_insert_color(&node->node, &head->head);
|
||||
rb_insert_color_cached(&node->node, &head->rb_root, leftmost);
|
||||
|
||||
if (!head->next || node->expires < head->next->expires) {
|
||||
head->next = node;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return leftmost;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(timerqueue_add);
|
||||
|
||||
@@ -65,15 +64,10 @@ bool timerqueue_del(struct timerqueue_head *head, struct timerqueue_node *node)
|
||||
{
|
||||
WARN_ON_ONCE(RB_EMPTY_NODE(&node->node));
|
||||
|
||||
/* update next pointer */
|
||||
if (head->next == node) {
|
||||
struct rb_node *rbn = rb_next(&node->node);
|
||||
|
||||
head->next = rb_entry_safe(rbn, struct timerqueue_node, node);
|
||||
}
|
||||
rb_erase(&node->node, &head->head);
|
||||
rb_erase_cached(&node->node, &head->rb_root);
|
||||
RB_CLEAR_NODE(&node->node);
|
||||
return head->next != NULL;
|
||||
|
||||
return !RB_EMPTY_ROOT(&head->rb_root.rb_root);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(timerqueue_del);
|
||||
|
||||
|
Reference in New Issue
Block a user