diff options
Diffstat (limited to 'lib/timerqueue.c')
-rw-r--r-- | lib/timerqueue.c | 30 |
1 files changed, 12 insertions, 18 deletions
diff --git a/lib/timerqueue.c b/lib/timerqueue.c index bc7e64df27df..c52710964593 100644 --- a/lib/timerqueue.c +++ b/lib/timerqueue.c | |||
@@ -26,9 +26,10 @@ | |||
26 | */ | 26 | */ |
27 | bool timerqueue_add(struct timerqueue_head *head, struct timerqueue_node *node) | 27 | bool timerqueue_add(struct timerqueue_head *head, struct timerqueue_node *node) |
28 | { | 28 | { |
29 | struct rb_node **p = &head->head.rb_node; | 29 | struct rb_node **p = &head->rb_root.rb_root.rb_node; |
30 | struct rb_node *parent = NULL; | 30 | struct rb_node *parent = NULL; |
31 | struct timerqueue_node *ptr; | 31 | struct timerqueue_node *ptr; |
32 | bool leftmost = true; | ||
32 | 33 | ||
33 | /* Make sure we don't add nodes that are already added */ | 34 | /* Make sure we don't add nodes that are already added */ |
34 | WARN_ON_ONCE(!RB_EMPTY_NODE(&node->node)); | 35 | WARN_ON_ONCE(!RB_EMPTY_NODE(&node->node)); |
@@ -36,19 +37,17 @@ bool timerqueue_add(struct timerqueue_head *head, struct timerqueue_node *node) | |||
36 | while (*p) { | 37 | while (*p) { |
37 | parent = *p; | 38 | parent = *p; |
38 | ptr = rb_entry(parent, struct timerqueue_node, node); | 39 | ptr = rb_entry(parent, struct timerqueue_node, node); |
39 | if (node->expires < ptr->expires) | 40 | if (node->expires < ptr->expires) { |
40 | p = &(*p)->rb_left; | 41 | p = &(*p)->rb_left; |
41 | else | 42 | } else { |
42 | p = &(*p)->rb_right; | 43 | p = &(*p)->rb_right; |
44 | leftmost = false; | ||
45 | } | ||
43 | } | 46 | } |
44 | rb_link_node(&node->node, parent, p); | 47 | rb_link_node(&node->node, parent, p); |
45 | rb_insert_color(&node->node, &head->head); | 48 | rb_insert_color_cached(&node->node, &head->rb_root, leftmost); |
46 | 49 | ||
47 | if (!head->next || node->expires < head->next->expires) { | 50 | return leftmost; |
48 | head->next = node; | ||
49 | return true; | ||
50 | } | ||
51 | return false; | ||
52 | } | 51 | } |
53 | EXPORT_SYMBOL_GPL(timerqueue_add); | 52 | EXPORT_SYMBOL_GPL(timerqueue_add); |
54 | 53 | ||
@@ -65,15 +64,10 @@ bool timerqueue_del(struct timerqueue_head *head, struct timerqueue_node *node) | |||
65 | { | 64 | { |
66 | WARN_ON_ONCE(RB_EMPTY_NODE(&node->node)); | 65 | WARN_ON_ONCE(RB_EMPTY_NODE(&node->node)); |
67 | 66 | ||
68 | /* update next pointer */ | 67 | rb_erase_cached(&node->node, &head->rb_root); |
69 | if (head->next == node) { | ||
70 | struct rb_node *rbn = rb_next(&node->node); | ||
71 | |||
72 | head->next = rb_entry_safe(rbn, struct timerqueue_node, node); | ||
73 | } | ||
74 | rb_erase(&node->node, &head->head); | ||
75 | RB_CLEAR_NODE(&node->node); | 68 | RB_CLEAR_NODE(&node->node); |
76 | return head->next != NULL; | 69 | |
70 | return !RB_EMPTY_ROOT(&head->rb_root.rb_root); | ||
77 | } | 71 | } |
78 | EXPORT_SYMBOL_GPL(timerqueue_del); | 72 | EXPORT_SYMBOL_GPL(timerqueue_del); |
79 | 73 | ||