Revert "lib/timerqueue: Rely on rbtree semantics for next timer"
This reverts commit b9a1ac8e7c
which is
commit 511885d7061eda3eb1faf3f57dcc936ff75863f1 upstream.
It breaks the abi and does not resolve an issue that is relevant to
Android devices, so it can be reverted.
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: I7b35b10c18f91bd132bf33de3572e272591976ae
This commit is contained in:
parent
0e38ed1a85
commit
b519e868c4
@ -12,7 +12,8 @@ struct timerqueue_node {
|
||||
};
|
||||
|
||||
struct timerqueue_head {
|
||||
struct rb_root_cached rb_root;
|
||||
struct rb_root head;
|
||||
struct timerqueue_node *next;
|
||||
};
|
||||
|
||||
|
||||
@ -28,14 +29,13 @@ extern struct timerqueue_node *timerqueue_iterate_next(
|
||||
*
|
||||
* @head: head of timerqueue
|
||||
*
|
||||
* Returns a pointer to the timer node that has the earliest expiration time.
|
||||
* Returns a pointer to the timer node that has the
|
||||
* earliest expiration time.
|
||||
*/
|
||||
static inline
|
||||
struct timerqueue_node *timerqueue_getnext(struct timerqueue_head *head)
|
||||
{
|
||||
struct rb_node *leftmost = rb_first_cached(&head->rb_root);
|
||||
|
||||
return rb_entry(leftmost, struct timerqueue_node, node);
|
||||
return head->next;
|
||||
}
|
||||
|
||||
static inline void timerqueue_init(struct timerqueue_node *node)
|
||||
@ -45,6 +45,7 @@ static inline void timerqueue_init(struct timerqueue_node *node)
|
||||
|
||||
static inline void timerqueue_init_head(struct timerqueue_head *head)
|
||||
{
|
||||
head->rb_root = RB_ROOT_CACHED;
|
||||
head->head = RB_ROOT;
|
||||
head->next = NULL;
|
||||
}
|
||||
#endif /* _LINUX_TIMERQUEUE_H */
|
||||
|
@ -39,10 +39,9 @@
|
||||
*/
|
||||
bool timerqueue_add(struct timerqueue_head *head, struct timerqueue_node *node)
|
||||
{
|
||||
struct rb_node **p = &head->rb_root.rb_root.rb_node;
|
||||
struct rb_node **p = &head->head.rb_node;
|
||||
struct rb_node *parent = NULL;
|
||||
struct timerqueue_node *ptr;
|
||||
bool leftmost = true;
|
||||
struct timerqueue_node *ptr;
|
||||
|
||||
/* Make sure we don't add nodes that are already added */
|
||||
WARN_ON_ONCE(!RB_EMPTY_NODE(&node->node));
|
||||
@ -50,17 +49,19 @@ 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_cached(&node->node, &head->rb_root, leftmost);
|
||||
rb_insert_color(&node->node, &head->head);
|
||||
|
||||
return leftmost;
|
||||
if (!head->next || node->expires < head->next->expires) {
|
||||
head->next = node;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(timerqueue_add);
|
||||
|
||||
@ -77,10 +78,15 @@ bool timerqueue_del(struct timerqueue_head *head, struct timerqueue_node *node)
|
||||
{
|
||||
WARN_ON_ONCE(RB_EMPTY_NODE(&node->node));
|
||||
|
||||
rb_erase_cached(&node->node, &head->rb_root);
|
||||
RB_CLEAR_NODE(&node->node);
|
||||
/* update next pointer */
|
||||
if (head->next == node) {
|
||||
struct rb_node *rbn = rb_next(&node->node);
|
||||
|
||||
return !RB_EMPTY_ROOT(&head->rb_root.rb_root);
|
||||
head->next = rb_entry_safe(rbn, struct timerqueue_node, node);
|
||||
}
|
||||
rb_erase(&node->node, &head->head);
|
||||
RB_CLEAR_NODE(&node->node);
|
||||
return head->next != NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(timerqueue_del);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user