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:
Greg Kroah-Hartman 2021-10-13 11:23:33 +02:00
parent 0e38ed1a85
commit b519e868c4
2 changed files with 25 additions and 18 deletions

View File

@ -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 */

View File

@ -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);