* [PATCH 0/3] prio_tree generalization
@ 2004-12-17 18:36 Werner Almesberger
2004-12-17 18:37 ` [PATCH 1/3] prio_tree: roll call to prio_tree_first into prio_tree_next Werner Almesberger
` (4 more replies)
0 siblings, 5 replies; 7+ messages in thread
From: Werner Almesberger @ 2004-12-17 18:36 UTC (permalink / raw)
To: linux-kernel; +Cc: Rajesh Venkatasubramanian, Andrew Morton
This patch set for 2.6.10-rc3-bk10 (*) generalizes the prio_tree
code such that other subsystems than just VMA can use it.
(*) I'm not sure which tree is the most useful base for this.
Should I use 2.6.10-rc3-mm* instead of -bk* ? (Or is it
already too late for 2.6.10 anyway ?)
While there are currently no other in-tree users than VMA,
the prio_tree algorithm will be useful for detecting overlapping
disk IO requests, which is a prerequisite for efficient handling
of barriers, which - besides being a good idea in general - in
turn is a prerequisite for useful disk IO priorities.
The three patches that follow are incremental and must be applied
in the order specified.
- Werner
--
_________________________________________________________________________
/ Werner Almesberger, Buenos Aires, Argentina werner@almesberger.net /
/_http://www.almesberger.net/____________________________________________/
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/3] prio_tree: roll call to prio_tree_first into prio_tree_next
2004-12-17 18:36 [PATCH 0/3] prio_tree generalization Werner Almesberger
@ 2004-12-17 18:37 ` Werner Almesberger
2004-12-17 18:39 ` [PATCH 2/3] prio_tree: generalization Werner Almesberger
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Werner Almesberger @ 2004-12-17 18:37 UTC (permalink / raw)
To: linux-kernel; +Cc: Rajesh Venkatasubramanian, Andrew Morton
Allow prio_tree_next to be used as the only function for tree
traversal, similar to how vma_prio_tree_next works.
This patch isn't needed for the generalization, but since it
affects the API, it's better to include it first.
- Werner
---------------------------------- cut here -----------------------------------
Signed-off-by: Werner Almesberger <werner@almesberger.net>
--- linux-2.6.10-rc3-bk10/include/linux/prio_tree.h.orig Fri Dec 17 01:05:14 2004
+++ linux-2.6.10-rc3-bk10/include/linux/prio_tree.h Fri Dec 17 00:38:47 2004
@@ -29,6 +29,7 @@ static inline void prio_tree_iter_init(s
iter->root = root;
iter->r_index = r_index;
iter->h_index = h_index;
+ iter->cur = NULL;
}
#define INIT_PRIO_TREE_ROOT(ptr) \
--- linux-2.6.10-rc3-bk10/mm/prio_tree.c.orig Fri Dec 17 01:05:29 2004
+++ linux-2.6.10-rc3-bk10/mm/prio_tree.c Fri Dec 17 00:39:02 2004
@@ -457,6 +457,9 @@ static struct prio_tree_node *prio_tree_
{
unsigned long r_index, h_index;
+ if (iter->cur == NULL)
+ return prio_tree_first(iter);
+
repeat:
while (prio_tree_left(iter, &r_index, &h_index))
if (overlap(iter, r_index, h_index))
@@ -620,7 +623,7 @@ struct vm_area_struct *vma_prio_tree_nex
/*
* First call is with NULL vma
*/
- ptr = prio_tree_first(iter);
+ ptr = prio_tree_next(iter);
if (ptr) {
next = prio_tree_entry(ptr, struct vm_area_struct,
shared.prio_tree_node);
--
_________________________________________________________________________
/ Werner Almesberger, Buenos Aires, Argentina werner@almesberger.net /
/_http://www.almesberger.net/____________________________________________/
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/3] prio_tree: generalization
2004-12-17 18:36 [PATCH 0/3] prio_tree generalization Werner Almesberger
2004-12-17 18:37 ` [PATCH 1/3] prio_tree: roll call to prio_tree_first into prio_tree_next Werner Almesberger
@ 2004-12-17 18:39 ` Werner Almesberger
2004-12-17 18:40 ` [PATCH 3/3] prio_tree: move general code from mm/ to lib/ Werner Almesberger
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Werner Almesberger @ 2004-12-17 18:39 UTC (permalink / raw)
To: linux-kernel; +Cc: Rajesh Venkatasubramanian, Andrew Morton
Export prio_tree functions such that they can be used by other
subsystems than only VMAs. Also adds a mode to prio_tree to use
it with keys explicitly included in the prio_tree meta-data.
The plan is to also consider converting VMAs to use explicit
keys, so that the old "raw" mode can be removed.
- Werner
---------------------------------- cut here -----------------------------------
Signed-off-by: Werner Almesberger <werner@almesberger.net>
--- linux-2.6.10-rc3-bk10/include/linux/prio_tree.h.roll_first Fri Dec 17 00:38:47 2004
+++ linux-2.6.10-rc3-bk10/include/linux/prio_tree.h Fri Dec 17 01:23:45 2004
@@ -1,15 +1,38 @@
#ifndef _LINUX_PRIO_TREE_H
#define _LINUX_PRIO_TREE_H
+/*
+ * K&R 2nd ed. A8.3 somewhat obliquely hints that initial sequences of struct
+ * fields with identical types should end up at the same location. We'll use
+ * this until we can scrap struct raw_prio_tree_node.
+ *
+ * Note: all this could be done more elegantly by using unnamed union/struct
+ * fields. However, gcc 2.95.3 and apparently also gcc 3.0.4 don't support this
+ * language extension.
+ */
+
+struct raw_prio_tree_node {
+ struct prio_tree_node *left;
+ struct prio_tree_node *right;
+ struct prio_tree_node *parent;
+};
+
struct prio_tree_node {
struct prio_tree_node *left;
struct prio_tree_node *right;
struct prio_tree_node *parent;
+ unsigned long start;
+ unsigned long last; /* last location _in_ interval */
};
struct prio_tree_root {
struct prio_tree_node *prio_tree_node;
- unsigned int index_bits;
+ unsigned short index_bits;
+ unsigned short raw;
+ /*
+ * 0: nodes are of type struct prio_tree_node
+ * 1: nodes are of type raw_prio_tree_node
+ */
};
struct prio_tree_iter {
@@ -32,12 +55,16 @@ static inline void prio_tree_iter_init(s
iter->cur = NULL;
}
-#define INIT_PRIO_TREE_ROOT(ptr) \
+#define __INIT_PRIO_TREE_ROOT(ptr, _raw) \
do { \
(ptr)->prio_tree_node = NULL; \
(ptr)->index_bits = 1; \
+ (ptr)->raw = (_raw); \
} while (0)
+#define INIT_PRIO_TREE_ROOT(ptr) __INIT_PRIO_TREE_ROOT(ptr, 0)
+#define INIT_RAW_PRIO_TREE_ROOT(ptr) __INIT_PRIO_TREE_ROOT(ptr, 1)
+
#define INIT_PRIO_TREE_NODE(ptr) \
do { \
(ptr)->left = (ptr)->right = (ptr)->parent = (ptr); \
@@ -74,4 +101,20 @@ static inline int prio_tree_right_empty(
return node->right == node;
}
+
+struct prio_tree_node *prio_tree_replace(struct prio_tree_root *root,
+ struct prio_tree_node *old, struct prio_tree_node *node);
+struct prio_tree_node *prio_tree_insert(struct prio_tree_root *root,
+ struct prio_tree_node *node);
+void prio_tree_remove(struct prio_tree_root *root, struct prio_tree_node *node);
+struct prio_tree_node *prio_tree_next(struct prio_tree_iter *iter);
+
+#define raw_prio_tree_replace(root, old, node) \
+ prio_tree_replace(root, (struct prio_tree_node *) (old), \
+ (struct prio_tree_node *) (node))
+#define raw_prio_tree_insert(root, node) \
+ prio_tree_insert(root, (struct prio_tree_node *) (node))
+#define raw_prio_tree_remove(root, node) \
+ prio_tree_remove(root, (struct prio_tree_node *) (node))
+
#endif /* _LINUX_PRIO_TREE_H */
--- linux-2.6.10-rc3-bk10/include/linux/mm.h.orig Thu Dec 16 23:59:14 2004
+++ linux-2.6.10-rc3-bk10/include/linux/mm.h Fri Dec 17 00:53:27 2004
@@ -85,7 +85,7 @@ struct vm_area_struct {
struct vm_area_struct *head;
} vm_set;
- struct prio_tree_node prio_tree_node;
+ struct raw_prio_tree_node prio_tree_node;
} shared;
/*
--- linux-2.6.10-rc3-bk10/mm/prio_tree.c.roll_first Fri Dec 17 00:39:02 2004
+++ linux-2.6.10-rc3-bk10/mm/prio_tree.c Fri Dec 17 01:24:01 2004
@@ -12,7 +12,6 @@
*/
#include <linux/init.h>
-#include <linux/module.h>
#include <linux/mm.h>
#include <linux/prio_tree.h>
@@ -49,18 +48,23 @@
/* avoid overflow */
#define HEAP_INDEX(vma) ((vma)->vm_pgoff + (VMA_SIZE(vma) - 1))
-#define GET_INDEX_VMA(vma, radix, heap) \
-do { \
- radix = RADIX_INDEX(vma); \
- heap = HEAP_INDEX(vma); \
-} while (0)
-
-#define GET_INDEX(node, radix, heap) \
-do { \
- struct vm_area_struct *__tmp = \
- prio_tree_entry(node, struct vm_area_struct, shared.prio_tree_node);\
- GET_INDEX_VMA(__tmp, radix, heap); \
-} while (0)
+
+static void get_index(const struct prio_tree_root *root,
+ const struct prio_tree_node *node,
+ unsigned long *radix, unsigned long *heap)
+{
+ if (root->raw) {
+ struct vm_area_struct *vma = prio_tree_entry(
+ node, struct vm_area_struct, shared.prio_tree_node);
+
+ *radix = RADIX_INDEX(vma);
+ *heap = HEAP_INDEX(vma);
+ }
+ else {
+ *radix = node->start;
+ *heap = node->last;
+ }
+}
static unsigned long index_bits_to_maxindex[BITS_PER_LONG];
@@ -81,8 +85,6 @@ static inline unsigned long prio_tree_ma
return index_bits_to_maxindex[bits - 1];
}
-static void prio_tree_remove(struct prio_tree_root *, struct prio_tree_node *);
-
/*
* Extend a priority search tree so that it can store a node with heap_index
* max_heap_index. In the worst case, this algorithm takes O((log n)^2).
@@ -138,7 +140,7 @@ static struct prio_tree_node *prio_tree_
/*
* Replace a prio_tree_node with a new node and return the old node
*/
-static struct prio_tree_node *prio_tree_replace(struct prio_tree_root *root,
+struct prio_tree_node *prio_tree_replace(struct prio_tree_root *root,
struct prio_tree_node *old, struct prio_tree_node *node)
{
INIT_PRIO_TREE_NODE(node);
@@ -182,7 +184,7 @@ static struct prio_tree_node *prio_tree_
* the tree, then returns the address of the prior node. Otherwise, inserts
* @node into the tree and returns @node.
*/
-static struct prio_tree_node *prio_tree_insert(struct prio_tree_root *root,
+struct prio_tree_node *prio_tree_insert(struct prio_tree_root *root,
struct prio_tree_node *node)
{
struct prio_tree_node *cur, *res = node;
@@ -190,7 +192,7 @@ static struct prio_tree_node *prio_tree_
unsigned long r_index, h_index, index, mask;
int size_flag = 0;
- GET_INDEX(node, radix_index, heap_index);
+ get_index(root, node, &radix_index, &heap_index);
if (prio_tree_empty(root) ||
heap_index > prio_tree_maxindex(root->index_bits))
@@ -200,7 +202,7 @@ static struct prio_tree_node *prio_tree_
mask = 1UL << (root->index_bits - 1);
while (mask) {
- GET_INDEX(cur, r_index, h_index);
+ get_index(root, cur, &r_index, &h_index);
if (r_index == radix_index && h_index == heap_index)
return cur;
@@ -259,8 +261,7 @@ static struct prio_tree_node *prio_tree_
* algorithm takes O(log n) time where 'log n' is the number of bits required
* to represent the maximum heap_index.
*/
-static void prio_tree_remove(struct prio_tree_root *root,
- struct prio_tree_node *node)
+void prio_tree_remove(struct prio_tree_root *root, struct prio_tree_node *node)
{
struct prio_tree_node *cur;
unsigned long r_index, h_index_right, h_index_left;
@@ -269,14 +270,14 @@ static void prio_tree_remove(struct prio
while (!prio_tree_left_empty(cur) || !prio_tree_right_empty(cur)) {
if (!prio_tree_left_empty(cur))
- GET_INDEX(cur->left, r_index, h_index_left);
+ get_index(root, cur->left, &r_index, &h_index_left);
else {
cur = cur->right;
continue;
}
if (!prio_tree_right_empty(cur))
- GET_INDEX(cur->right, r_index, h_index_right);
+ get_index(root, cur->right, &r_index, &h_index_right);
else {
cur = cur->left;
continue;
@@ -291,7 +292,7 @@ static void prio_tree_remove(struct prio
if (prio_tree_root(cur)) {
BUG_ON(root->prio_tree_node != cur);
- INIT_PRIO_TREE_ROOT(root);
+ __INIT_PRIO_TREE_ROOT(root, root->raw);
return;
}
@@ -318,7 +319,7 @@ static struct prio_tree_node *prio_tree_
if (prio_tree_left_empty(iter->cur))
return NULL;
- GET_INDEX(iter->cur->left, *r_index, *h_index);
+ get_index(iter->root, iter->cur->left, r_index, h_index);
if (iter->r_index <= *h_index) {
iter->cur = iter->cur->left;
@@ -359,7 +360,7 @@ static struct prio_tree_node *prio_tree_
if (iter->h_index < value)
return NULL;
- GET_INDEX(iter->cur->right, *r_index, *h_index);
+ get_index(iter->root, iter->cur->right, r_index, h_index);
if (iter->r_index <= *h_index) {
iter->cur = iter->cur->right;
@@ -425,7 +426,7 @@ static struct prio_tree_node *prio_tree_
if (prio_tree_empty(root))
return NULL;
- GET_INDEX(root->prio_tree_node, r_index, h_index);
+ get_index(root, root->prio_tree_node, &r_index, &h_index);
if (iter->r_index > h_index)
return NULL;
@@ -453,7 +454,7 @@ static struct prio_tree_node *prio_tree_
*
* Get the next prio_tree_node that overlaps with the input interval in iter
*/
-static struct prio_tree_node *prio_tree_next(struct prio_tree_iter *iter)
+struct prio_tree_node *prio_tree_next(struct prio_tree_iter *iter)
{
unsigned long r_index, h_index;
@@ -554,8 +555,8 @@ void vma_prio_tree_insert(struct vm_area
vma->shared.vm_set.head = NULL;
- ptr = prio_tree_insert(root, &vma->shared.prio_tree_node);
- if (ptr != &vma->shared.prio_tree_node) {
+ ptr = raw_prio_tree_insert(root, &vma->shared.prio_tree_node);
+ if (ptr != (struct prio_tree_node *) &vma->shared.prio_tree_node) {
old = prio_tree_entry(ptr, struct vm_area_struct,
shared.prio_tree_node);
vma_prio_tree_add(vma, old);
@@ -571,7 +572,7 @@ void vma_prio_tree_remove(struct vm_area
if (!vma->shared.vm_set.parent)
list_del_init(&vma->shared.vm_set.list);
else
- prio_tree_remove(root, &vma->shared.prio_tree_node);
+ raw_prio_tree_remove(root, &vma->shared.prio_tree_node);
} else {
/* Leave this BUG_ON till prio_tree patch stabilizes */
BUG_ON(vma->shared.vm_set.head->shared.vm_set.head != vma);
@@ -586,7 +587,7 @@ void vma_prio_tree_remove(struct vm_area
} else
new_head = NULL;
- prio_tree_replace(root, &vma->shared.prio_tree_node,
+ raw_prio_tree_replace(root, &vma->shared.prio_tree_node,
&head->shared.prio_tree_node);
head->shared.vm_set.head = new_head;
if (new_head)
--- linux-2.6.10-rc3-bk10/fs/inode.c.orig Fri Dec 17 00:58:27 2004
+++ linux-2.6.10-rc3-bk10/fs/inode.c Fri Dec 17 00:53:36 2004
@@ -201,7 +201,7 @@ void inode_init_once(struct inode *inode
atomic_set(&inode->i_data.truncate_count, 0);
INIT_LIST_HEAD(&inode->i_data.private_list);
spin_lock_init(&inode->i_data.private_lock);
- INIT_PRIO_TREE_ROOT(&inode->i_data.i_mmap);
+ INIT_RAW_PRIO_TREE_ROOT(&inode->i_data.i_mmap);
INIT_LIST_HEAD(&inode->i_data.i_mmap_nonlinear);
spin_lock_init(&inode->i_lock);
i_size_ordered_init(inode);
--
_________________________________________________________________________
/ Werner Almesberger, Buenos Aires, Argentina werner@almesberger.net /
/_http://www.almesberger.net/____________________________________________/
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 3/3] prio_tree: move general code from mm/ to lib/
2004-12-17 18:36 [PATCH 0/3] prio_tree generalization Werner Almesberger
2004-12-17 18:37 ` [PATCH 1/3] prio_tree: roll call to prio_tree_first into prio_tree_next Werner Almesberger
2004-12-17 18:39 ` [PATCH 2/3] prio_tree: generalization Werner Almesberger
@ 2004-12-17 18:40 ` Werner Almesberger
2004-12-17 19:52 ` [PATCH 0/3] prio_tree generalization Andrew Morton
2004-12-17 23:10 ` [PATCH 3/3] prio_tree: move general code from mm/ to lib/ David Howells
4 siblings, 0 replies; 7+ messages in thread
From: Werner Almesberger @ 2004-12-17 18:40 UTC (permalink / raw)
To: linux-kernel; +Cc: Rajesh Venkatasubramanian, Andrew Morton, David Howells
Last but not least, move the general prio_tree code from mm/
to lib/. This patch also duplicates some macros, which are used
in the VMA code for debugging purposes, so we can't properly
separate them yet.
Note that this patch conflicts with a patch in 2.6.10-rc3-mm1
(frv-better-mmap-support-in-uclinux.patch), which removes
mm/prio_tree in systems without an MMU. Not making that other
patch provide a dummy for prio_tree_init should resolve the
conflict. (That's just from reading the patch - I haven't
actually tried this.)
- Werner
---------------------------------- cut here -----------------------------------
Signed-off-by: Werner Almesberger <werner@almesberger.net>
--- linux-2.6.10-rc3-bk10/mm/prio_tree.c.gen Fri Dec 17 01:24:01 2004
+++ linux-2.6.10-rc3-bk10/mm/prio_tree.c Fri Dec 17 01:21:38 2004
@@ -11,477 +11,24 @@
* 02Feb2004 Initial version
*/
-#include <linux/init.h>
#include <linux/mm.h>
#include <linux/prio_tree.h>
/*
- * A clever mix of heap and radix trees forms a radix priority search tree (PST)
- * which is useful for storing intervals, e.g, we can consider a vma as a closed
- * interval of file pages [offset_begin, offset_end], and store all vmas that
- * map a file in a PST. Then, using the PST, we can answer a stabbing query,
- * i.e., selecting a set of stored intervals (vmas) that overlap with (map) a
- * given input interval X (a set of consecutive file pages), in "O(log n + m)"
- * time where 'log n' is the height of the PST, and 'm' is the number of stored
- * intervals (vmas) that overlap (map) with the input interval X (the set of
- * consecutive file pages).
- *
- * In our implementation, we store closed intervals of the form [radix_index,
- * heap_index]. We assume that always radix_index <= heap_index. McCreight's PST
- * is designed for storing intervals with unique radix indices, i.e., each
- * interval have different radix_index. However, this limitation can be easily
- * overcome by using the size, i.e., heap_index - radix_index, as part of the
- * index, so we index the tree using [(radix_index,size), heap_index].
- *
- * When the above-mentioned indexing scheme is used, theoretically, in a 32 bit
- * machine, the maximum height of a PST can be 64. We can use a balanced version
- * of the priority search tree to optimize the tree height, but the balanced
- * tree proposed by McCreight is too complex and memory-hungry for our purpose.
+ * See lib/prio_tree.c for details on the general radix priority search tree
+ * code.
*/
/*
- * The following macros are used for implementing prio_tree for i_mmap
+ * The following #defines are mirrored from lib/prio_tree.c. They're only used
+ * for debugging, and should be removed (along with the debugging code using
+ * them) when switching also VMAs to the regular prio_tree code.
*/
#define RADIX_INDEX(vma) ((vma)->vm_pgoff)
#define VMA_SIZE(vma) (((vma)->vm_end - (vma)->vm_start) >> PAGE_SHIFT)
/* avoid overflow */
-#define HEAP_INDEX(vma) ((vma)->vm_pgoff + (VMA_SIZE(vma) - 1))
-
-
-static void get_index(const struct prio_tree_root *root,
- const struct prio_tree_node *node,
- unsigned long *radix, unsigned long *heap)
-{
- if (root->raw) {
- struct vm_area_struct *vma = prio_tree_entry(
- node, struct vm_area_struct, shared.prio_tree_node);
-
- *radix = RADIX_INDEX(vma);
- *heap = HEAP_INDEX(vma);
- }
- else {
- *radix = node->start;
- *heap = node->last;
- }
-}
-
-static unsigned long index_bits_to_maxindex[BITS_PER_LONG];
-
-void __init prio_tree_init(void)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(index_bits_to_maxindex) - 1; i++)
- index_bits_to_maxindex[i] = (1UL << (i + 1)) - 1;
- index_bits_to_maxindex[ARRAY_SIZE(index_bits_to_maxindex) - 1] = ~0UL;
-}
-
-/*
- * Maximum heap_index that can be stored in a PST with index_bits bits
- */
-static inline unsigned long prio_tree_maxindex(unsigned int bits)
-{
- return index_bits_to_maxindex[bits - 1];
-}
-
-/*
- * Extend a priority search tree so that it can store a node with heap_index
- * max_heap_index. In the worst case, this algorithm takes O((log n)^2).
- * However, this function is used rarely and the common case performance is
- * not bad.
- */
-static struct prio_tree_node *prio_tree_expand(struct prio_tree_root *root,
- struct prio_tree_node *node, unsigned long max_heap_index)
-{
- struct prio_tree_node *first = NULL, *prev, *last = NULL;
-
- if (max_heap_index > prio_tree_maxindex(root->index_bits))
- root->index_bits++;
-
- while (max_heap_index > prio_tree_maxindex(root->index_bits)) {
- root->index_bits++;
-
- if (prio_tree_empty(root))
- continue;
-
- if (first == NULL) {
- first = root->prio_tree_node;
- prio_tree_remove(root, root->prio_tree_node);
- INIT_PRIO_TREE_NODE(first);
- last = first;
- } else {
- prev = last;
- last = root->prio_tree_node;
- prio_tree_remove(root, root->prio_tree_node);
- INIT_PRIO_TREE_NODE(last);
- prev->left = last;
- last->parent = prev;
- }
- }
-
- INIT_PRIO_TREE_NODE(node);
-
- if (first) {
- node->left = first;
- first->parent = node;
- } else
- last = node;
-
- if (!prio_tree_empty(root)) {
- last->left = root->prio_tree_node;
- last->left->parent = last;
- }
-
- root->prio_tree_node = node;
- return node;
-}
-
-/*
- * Replace a prio_tree_node with a new node and return the old node
- */
-struct prio_tree_node *prio_tree_replace(struct prio_tree_root *root,
- struct prio_tree_node *old, struct prio_tree_node *node)
-{
- INIT_PRIO_TREE_NODE(node);
-
- if (prio_tree_root(old)) {
- BUG_ON(root->prio_tree_node != old);
- /*
- * We can reduce root->index_bits here. However, it is complex
- * and does not help much to improve performance (IMO).
- */
- node->parent = node;
- root->prio_tree_node = node;
- } else {
- node->parent = old->parent;
- if (old->parent->left == old)
- old->parent->left = node;
- else
- old->parent->right = node;
- }
-
- if (!prio_tree_left_empty(old)) {
- node->left = old->left;
- old->left->parent = node;
- }
-
- if (!prio_tree_right_empty(old)) {
- node->right = old->right;
- old->right->parent = node;
- }
-
- return old;
-}
-
-/*
- * Insert a prio_tree_node @node into a radix priority search tree @root. The
- * algorithm typically takes O(log n) time where 'log n' is the number of bits
- * required to represent the maximum heap_index. In the worst case, the algo
- * can take O((log n)^2) - check prio_tree_expand.
- *
- * If a prior node with same radix_index and heap_index is already found in
- * the tree, then returns the address of the prior node. Otherwise, inserts
- * @node into the tree and returns @node.
- */
-struct prio_tree_node *prio_tree_insert(struct prio_tree_root *root,
- struct prio_tree_node *node)
-{
- struct prio_tree_node *cur, *res = node;
- unsigned long radix_index, heap_index;
- unsigned long r_index, h_index, index, mask;
- int size_flag = 0;
-
- get_index(root, node, &radix_index, &heap_index);
-
- if (prio_tree_empty(root) ||
- heap_index > prio_tree_maxindex(root->index_bits))
- return prio_tree_expand(root, node, heap_index);
-
- cur = root->prio_tree_node;
- mask = 1UL << (root->index_bits - 1);
-
- while (mask) {
- get_index(root, cur, &r_index, &h_index);
-
- if (r_index == radix_index && h_index == heap_index)
- return cur;
-
- if (h_index < heap_index ||
- (h_index == heap_index && r_index > radix_index)) {
- struct prio_tree_node *tmp = node;
- node = prio_tree_replace(root, cur, node);
- cur = tmp;
- /* swap indices */
- index = r_index;
- r_index = radix_index;
- radix_index = index;
- index = h_index;
- h_index = heap_index;
- heap_index = index;
- }
-
- if (size_flag)
- index = heap_index - radix_index;
- else
- index = radix_index;
-
- if (index & mask) {
- if (prio_tree_right_empty(cur)) {
- INIT_PRIO_TREE_NODE(node);
- cur->right = node;
- node->parent = cur;
- return res;
- } else
- cur = cur->right;
- } else {
- if (prio_tree_left_empty(cur)) {
- INIT_PRIO_TREE_NODE(node);
- cur->left = node;
- node->parent = cur;
- return res;
- } else
- cur = cur->left;
- }
-
- mask >>= 1;
-
- if (!mask) {
- mask = 1UL << (BITS_PER_LONG - 1);
- size_flag = 1;
- }
- }
- /* Should not reach here */
- BUG();
- return NULL;
-}
-
-/*
- * Remove a prio_tree_node @node from a radix priority search tree @root. The
- * algorithm takes O(log n) time where 'log n' is the number of bits required
- * to represent the maximum heap_index.
- */
-void prio_tree_remove(struct prio_tree_root *root, struct prio_tree_node *node)
-{
- struct prio_tree_node *cur;
- unsigned long r_index, h_index_right, h_index_left;
-
- cur = node;
-
- while (!prio_tree_left_empty(cur) || !prio_tree_right_empty(cur)) {
- if (!prio_tree_left_empty(cur))
- get_index(root, cur->left, &r_index, &h_index_left);
- else {
- cur = cur->right;
- continue;
- }
-
- if (!prio_tree_right_empty(cur))
- get_index(root, cur->right, &r_index, &h_index_right);
- else {
- cur = cur->left;
- continue;
- }
-
- /* both h_index_left and h_index_right cannot be 0 */
- if (h_index_left >= h_index_right)
- cur = cur->left;
- else
- cur = cur->right;
- }
-
- if (prio_tree_root(cur)) {
- BUG_ON(root->prio_tree_node != cur);
- __INIT_PRIO_TREE_ROOT(root, root->raw);
- return;
- }
-
- if (cur->parent->right == cur)
- cur->parent->right = cur->parent;
- else
- cur->parent->left = cur->parent;
-
- while (cur != node)
- cur = prio_tree_replace(root, cur->parent, cur);
-}
-
-/*
- * Following functions help to enumerate all prio_tree_nodes in the tree that
- * overlap with the input interval X [radix_index, heap_index]. The enumeration
- * takes O(log n + m) time where 'log n' is the height of the tree (which is
- * proportional to # of bits required to represent the maximum heap_index) and
- * 'm' is the number of prio_tree_nodes that overlap the interval X.
- */
-
-static struct prio_tree_node *prio_tree_left(struct prio_tree_iter *iter,
- unsigned long *r_index, unsigned long *h_index)
-{
- if (prio_tree_left_empty(iter->cur))
- return NULL;
-
- get_index(iter->root, iter->cur->left, r_index, h_index);
-
- if (iter->r_index <= *h_index) {
- iter->cur = iter->cur->left;
- iter->mask >>= 1;
- if (iter->mask) {
- if (iter->size_level)
- iter->size_level++;
- } else {
- if (iter->size_level) {
- BUG_ON(!prio_tree_left_empty(iter->cur));
- BUG_ON(!prio_tree_right_empty(iter->cur));
- iter->size_level++;
- iter->mask = ULONG_MAX;
- } else {
- iter->size_level = 1;
- iter->mask = 1UL << (BITS_PER_LONG - 1);
- }
- }
- return iter->cur;
- }
-
- return NULL;
-}
-
-static struct prio_tree_node *prio_tree_right(struct prio_tree_iter *iter,
- unsigned long *r_index, unsigned long *h_index)
-{
- unsigned long value;
-
- if (prio_tree_right_empty(iter->cur))
- return NULL;
-
- if (iter->size_level)
- value = iter->value;
- else
- value = iter->value | iter->mask;
-
- if (iter->h_index < value)
- return NULL;
-
- get_index(iter->root, iter->cur->right, r_index, h_index);
-
- if (iter->r_index <= *h_index) {
- iter->cur = iter->cur->right;
- iter->mask >>= 1;
- iter->value = value;
- if (iter->mask) {
- if (iter->size_level)
- iter->size_level++;
- } else {
- if (iter->size_level) {
- BUG_ON(!prio_tree_left_empty(iter->cur));
- BUG_ON(!prio_tree_right_empty(iter->cur));
- iter->size_level++;
- iter->mask = ULONG_MAX;
- } else {
- iter->size_level = 1;
- iter->mask = 1UL << (BITS_PER_LONG - 1);
- }
- }
- return iter->cur;
- }
-
- return NULL;
-}
-
-static struct prio_tree_node *prio_tree_parent(struct prio_tree_iter *iter)
-{
- iter->cur = iter->cur->parent;
- if (iter->mask == ULONG_MAX)
- iter->mask = 1UL;
- else if (iter->size_level == 1)
- iter->mask = 1UL;
- else
- iter->mask <<= 1;
- if (iter->size_level)
- iter->size_level--;
- if (!iter->size_level && (iter->value & iter->mask))
- iter->value ^= iter->mask;
- return iter->cur;
-}
-
-static inline int overlap(struct prio_tree_iter *iter,
- unsigned long r_index, unsigned long h_index)
-{
- return iter->h_index >= r_index && iter->r_index <= h_index;
-}
-
-/*
- * prio_tree_first:
- *
- * Get the first prio_tree_node that overlaps with the interval [radix_index,
- * heap_index]. Note that always radix_index <= heap_index. We do a pre-order
- * traversal of the tree.
- */
-static struct prio_tree_node *prio_tree_first(struct prio_tree_iter *iter)
-{
- struct prio_tree_root *root;
- unsigned long r_index, h_index;
-
- INIT_PRIO_TREE_ITER(iter);
-
- root = iter->root;
- if (prio_tree_empty(root))
- return NULL;
-
- get_index(root, root->prio_tree_node, &r_index, &h_index);
-
- if (iter->r_index > h_index)
- return NULL;
-
- iter->mask = 1UL << (root->index_bits - 1);
- iter->cur = root->prio_tree_node;
-
- while (1) {
- if (overlap(iter, r_index, h_index))
- return iter->cur;
-
- if (prio_tree_left(iter, &r_index, &h_index))
- continue;
-
- if (prio_tree_right(iter, &r_index, &h_index))
- continue;
-
- break;
- }
- return NULL;
-}
-
-/*
- * prio_tree_next:
- *
- * Get the next prio_tree_node that overlaps with the input interval in iter
- */
-struct prio_tree_node *prio_tree_next(struct prio_tree_iter *iter)
-{
- unsigned long r_index, h_index;
-
- if (iter->cur == NULL)
- return prio_tree_first(iter);
-
-repeat:
- while (prio_tree_left(iter, &r_index, &h_index))
- if (overlap(iter, r_index, h_index))
- return iter->cur;
-
- while (!prio_tree_right(iter, &r_index, &h_index)) {
- while (!prio_tree_root(iter->cur) &&
- iter->cur->parent->right == iter->cur)
- prio_tree_parent(iter);
-
- if (prio_tree_root(iter->cur))
- return NULL;
-
- prio_tree_parent(iter);
- }
-
- if (overlap(iter, r_index, h_index))
- return iter->cur;
-
- goto repeat;
-}
+#define HEAP_INDEX(vma) ((vma)->vm_pgoff + (VMA_SIZE(vma) - 1))
/*
* Radix priority search tree for address_space->i_mmap
--- linux-2.6.10-rc3-bk10/lib/Makefile.orig Fri Dec 17 01:09:52 2004
+++ linux-2.6.10-rc3-bk10/lib/Makefile Fri Dec 17 01:14:06 2004
@@ -5,7 +5,7 @@
lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \
bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \
kobject.o kref.o idr.o div64.o parser.o int_sqrt.o \
- bitmap.o extable.o kobject_uevent.o
+ bitmap.o extable.o kobject_uevent.o prio_tree.o
ifeq ($(CONFIG_DEBUG_KOBJECT),y)
CFLAGS_kobject.o += -DDEBUG
--- /dev/null Wed Jun 9 20:31:45 2004
+++ linux-2.6.10-rc3-bk10/lib/prio_tree.c Fri Dec 17 01:23:01 2004
@@ -0,0 +1,484 @@
+/*
+ * lib/prio_tree.c - priority search tree
+ *
+ * Copyright (C) 2004, Rajesh Venkatasubramanian <vrajesh@umich.edu>
+ *
+ * This file is released under the GPL v2.
+ *
+ * Based on the radix priority search tree proposed by Edward M. McCreight
+ * SIAM Journal of Computing, vol. 14, no.2, pages 257-276, May 1985
+ *
+ * 02Feb2004 Initial version
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/prio_tree.h>
+
+/*
+ * A clever mix of heap and radix trees forms a radix priority search tree (PST)
+ * which is useful for storing intervals, e.g, we can consider a vma as a closed
+ * interval of file pages [offset_begin, offset_end], and store all vmas that
+ * map a file in a PST. Then, using the PST, we can answer a stabbing query,
+ * i.e., selecting a set of stored intervals (vmas) that overlap with (map) a
+ * given input interval X (a set of consecutive file pages), in "O(log n + m)"
+ * time where 'log n' is the height of the PST, and 'm' is the number of stored
+ * intervals (vmas) that overlap (map) with the input interval X (the set of
+ * consecutive file pages).
+ *
+ * In our implementation, we store closed intervals of the form [radix_index,
+ * heap_index]. We assume that always radix_index <= heap_index. McCreight's PST
+ * is designed for storing intervals with unique radix indices, i.e., each
+ * interval have different radix_index. However, this limitation can be easily
+ * overcome by using the size, i.e., heap_index - radix_index, as part of the
+ * index, so we index the tree using [(radix_index,size), heap_index].
+ *
+ * When the above-mentioned indexing scheme is used, theoretically, in a 32 bit
+ * machine, the maximum height of a PST can be 64. We can use a balanced version
+ * of the priority search tree to optimize the tree height, but the balanced
+ * tree proposed by McCreight is too complex and memory-hungry for our purpose.
+ */
+
+/*
+ * The following macros are used for implementing prio_tree for i_mmap
+ */
+
+#define RADIX_INDEX(vma) ((vma)->vm_pgoff)
+#define VMA_SIZE(vma) (((vma)->vm_end - (vma)->vm_start) >> PAGE_SHIFT)
+/* avoid overflow */
+#define HEAP_INDEX(vma) ((vma)->vm_pgoff + (VMA_SIZE(vma) - 1))
+
+
+static void get_index(const struct prio_tree_root *root,
+ const struct prio_tree_node *node,
+ unsigned long *radix, unsigned long *heap)
+{
+ if (root->raw) {
+ struct vm_area_struct *vma = prio_tree_entry(
+ node, struct vm_area_struct, shared.prio_tree_node);
+
+ *radix = RADIX_INDEX(vma);
+ *heap = HEAP_INDEX(vma);
+ }
+ else {
+ *radix = node->start;
+ *heap = node->last;
+ }
+}
+
+static unsigned long index_bits_to_maxindex[BITS_PER_LONG];
+
+void __init prio_tree_init(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(index_bits_to_maxindex) - 1; i++)
+ index_bits_to_maxindex[i] = (1UL << (i + 1)) - 1;
+ index_bits_to_maxindex[ARRAY_SIZE(index_bits_to_maxindex) - 1] = ~0UL;
+}
+
+/*
+ * Maximum heap_index that can be stored in a PST with index_bits bits
+ */
+static inline unsigned long prio_tree_maxindex(unsigned int bits)
+{
+ return index_bits_to_maxindex[bits - 1];
+}
+
+/*
+ * Extend a priority search tree so that it can store a node with heap_index
+ * max_heap_index. In the worst case, this algorithm takes O((log n)^2).
+ * However, this function is used rarely and the common case performance is
+ * not bad.
+ */
+static struct prio_tree_node *prio_tree_expand(struct prio_tree_root *root,
+ struct prio_tree_node *node, unsigned long max_heap_index)
+{
+ struct prio_tree_node *first = NULL, *prev, *last = NULL;
+
+ if (max_heap_index > prio_tree_maxindex(root->index_bits))
+ root->index_bits++;
+
+ while (max_heap_index > prio_tree_maxindex(root->index_bits)) {
+ root->index_bits++;
+
+ if (prio_tree_empty(root))
+ continue;
+
+ if (first == NULL) {
+ first = root->prio_tree_node;
+ prio_tree_remove(root, root->prio_tree_node);
+ INIT_PRIO_TREE_NODE(first);
+ last = first;
+ } else {
+ prev = last;
+ last = root->prio_tree_node;
+ prio_tree_remove(root, root->prio_tree_node);
+ INIT_PRIO_TREE_NODE(last);
+ prev->left = last;
+ last->parent = prev;
+ }
+ }
+
+ INIT_PRIO_TREE_NODE(node);
+
+ if (first) {
+ node->left = first;
+ first->parent = node;
+ } else
+ last = node;
+
+ if (!prio_tree_empty(root)) {
+ last->left = root->prio_tree_node;
+ last->left->parent = last;
+ }
+
+ root->prio_tree_node = node;
+ return node;
+}
+
+/*
+ * Replace a prio_tree_node with a new node and return the old node
+ */
+struct prio_tree_node *prio_tree_replace(struct prio_tree_root *root,
+ struct prio_tree_node *old, struct prio_tree_node *node)
+{
+ INIT_PRIO_TREE_NODE(node);
+
+ if (prio_tree_root(old)) {
+ BUG_ON(root->prio_tree_node != old);
+ /*
+ * We can reduce root->index_bits here. However, it is complex
+ * and does not help much to improve performance (IMO).
+ */
+ node->parent = node;
+ root->prio_tree_node = node;
+ } else {
+ node->parent = old->parent;
+ if (old->parent->left == old)
+ old->parent->left = node;
+ else
+ old->parent->right = node;
+ }
+
+ if (!prio_tree_left_empty(old)) {
+ node->left = old->left;
+ old->left->parent = node;
+ }
+
+ if (!prio_tree_right_empty(old)) {
+ node->right = old->right;
+ old->right->parent = node;
+ }
+
+ return old;
+}
+
+/*
+ * Insert a prio_tree_node @node into a radix priority search tree @root. The
+ * algorithm typically takes O(log n) time where 'log n' is the number of bits
+ * required to represent the maximum heap_index. In the worst case, the algo
+ * can take O((log n)^2) - check prio_tree_expand.
+ *
+ * If a prior node with same radix_index and heap_index is already found in
+ * the tree, then returns the address of the prior node. Otherwise, inserts
+ * @node into the tree and returns @node.
+ */
+struct prio_tree_node *prio_tree_insert(struct prio_tree_root *root,
+ struct prio_tree_node *node)
+{
+ struct prio_tree_node *cur, *res = node;
+ unsigned long radix_index, heap_index;
+ unsigned long r_index, h_index, index, mask;
+ int size_flag = 0;
+
+ get_index(root, node, &radix_index, &heap_index);
+
+ if (prio_tree_empty(root) ||
+ heap_index > prio_tree_maxindex(root->index_bits))
+ return prio_tree_expand(root, node, heap_index);
+
+ cur = root->prio_tree_node;
+ mask = 1UL << (root->index_bits - 1);
+
+ while (mask) {
+ get_index(root, cur, &r_index, &h_index);
+
+ if (r_index == radix_index && h_index == heap_index)
+ return cur;
+
+ if (h_index < heap_index ||
+ (h_index == heap_index && r_index > radix_index)) {
+ struct prio_tree_node *tmp = node;
+ node = prio_tree_replace(root, cur, node);
+ cur = tmp;
+ /* swap indices */
+ index = r_index;
+ r_index = radix_index;
+ radix_index = index;
+ index = h_index;
+ h_index = heap_index;
+ heap_index = index;
+ }
+
+ if (size_flag)
+ index = heap_index - radix_index;
+ else
+ index = radix_index;
+
+ if (index & mask) {
+ if (prio_tree_right_empty(cur)) {
+ INIT_PRIO_TREE_NODE(node);
+ cur->right = node;
+ node->parent = cur;
+ return res;
+ } else
+ cur = cur->right;
+ } else {
+ if (prio_tree_left_empty(cur)) {
+ INIT_PRIO_TREE_NODE(node);
+ cur->left = node;
+ node->parent = cur;
+ return res;
+ } else
+ cur = cur->left;
+ }
+
+ mask >>= 1;
+
+ if (!mask) {
+ mask = 1UL << (BITS_PER_LONG - 1);
+ size_flag = 1;
+ }
+ }
+ /* Should not reach here */
+ BUG();
+ return NULL;
+}
+
+/*
+ * Remove a prio_tree_node @node from a radix priority search tree @root. The
+ * algorithm takes O(log n) time where 'log n' is the number of bits required
+ * to represent the maximum heap_index.
+ */
+void prio_tree_remove(struct prio_tree_root *root, struct prio_tree_node *node)
+{
+ struct prio_tree_node *cur;
+ unsigned long r_index, h_index_right, h_index_left;
+
+ cur = node;
+
+ while (!prio_tree_left_empty(cur) || !prio_tree_right_empty(cur)) {
+ if (!prio_tree_left_empty(cur))
+ get_index(root, cur->left, &r_index, &h_index_left);
+ else {
+ cur = cur->right;
+ continue;
+ }
+
+ if (!prio_tree_right_empty(cur))
+ get_index(root, cur->right, &r_index, &h_index_right);
+ else {
+ cur = cur->left;
+ continue;
+ }
+
+ /* both h_index_left and h_index_right cannot be 0 */
+ if (h_index_left >= h_index_right)
+ cur = cur->left;
+ else
+ cur = cur->right;
+ }
+
+ if (prio_tree_root(cur)) {
+ BUG_ON(root->prio_tree_node != cur);
+ __INIT_PRIO_TREE_ROOT(root, root->raw);
+ return;
+ }
+
+ if (cur->parent->right == cur)
+ cur->parent->right = cur->parent;
+ else
+ cur->parent->left = cur->parent;
+
+ while (cur != node)
+ cur = prio_tree_replace(root, cur->parent, cur);
+}
+
+/*
+ * Following functions help to enumerate all prio_tree_nodes in the tree that
+ * overlap with the input interval X [radix_index, heap_index]. The enumeration
+ * takes O(log n + m) time where 'log n' is the height of the tree (which is
+ * proportional to # of bits required to represent the maximum heap_index) and
+ * 'm' is the number of prio_tree_nodes that overlap the interval X.
+ */
+
+static struct prio_tree_node *prio_tree_left(struct prio_tree_iter *iter,
+ unsigned long *r_index, unsigned long *h_index)
+{
+ if (prio_tree_left_empty(iter->cur))
+ return NULL;
+
+ get_index(iter->root, iter->cur->left, r_index, h_index);
+
+ if (iter->r_index <= *h_index) {
+ iter->cur = iter->cur->left;
+ iter->mask >>= 1;
+ if (iter->mask) {
+ if (iter->size_level)
+ iter->size_level++;
+ } else {
+ if (iter->size_level) {
+ BUG_ON(!prio_tree_left_empty(iter->cur));
+ BUG_ON(!prio_tree_right_empty(iter->cur));
+ iter->size_level++;
+ iter->mask = ULONG_MAX;
+ } else {
+ iter->size_level = 1;
+ iter->mask = 1UL << (BITS_PER_LONG - 1);
+ }
+ }
+ return iter->cur;
+ }
+
+ return NULL;
+}
+
+static struct prio_tree_node *prio_tree_right(struct prio_tree_iter *iter,
+ unsigned long *r_index, unsigned long *h_index)
+{
+ unsigned long value;
+
+ if (prio_tree_right_empty(iter->cur))
+ return NULL;
+
+ if (iter->size_level)
+ value = iter->value;
+ else
+ value = iter->value | iter->mask;
+
+ if (iter->h_index < value)
+ return NULL;
+
+ get_index(iter->root, iter->cur->right, r_index, h_index);
+
+ if (iter->r_index <= *h_index) {
+ iter->cur = iter->cur->right;
+ iter->mask >>= 1;
+ iter->value = value;
+ if (iter->mask) {
+ if (iter->size_level)
+ iter->size_level++;
+ } else {
+ if (iter->size_level) {
+ BUG_ON(!prio_tree_left_empty(iter->cur));
+ BUG_ON(!prio_tree_right_empty(iter->cur));
+ iter->size_level++;
+ iter->mask = ULONG_MAX;
+ } else {
+ iter->size_level = 1;
+ iter->mask = 1UL << (BITS_PER_LONG - 1);
+ }
+ }
+ return iter->cur;
+ }
+
+ return NULL;
+}
+
+static struct prio_tree_node *prio_tree_parent(struct prio_tree_iter *iter)
+{
+ iter->cur = iter->cur->parent;
+ if (iter->mask == ULONG_MAX)
+ iter->mask = 1UL;
+ else if (iter->size_level == 1)
+ iter->mask = 1UL;
+ else
+ iter->mask <<= 1;
+ if (iter->size_level)
+ iter->size_level--;
+ if (!iter->size_level && (iter->value & iter->mask))
+ iter->value ^= iter->mask;
+ return iter->cur;
+}
+
+static inline int overlap(struct prio_tree_iter *iter,
+ unsigned long r_index, unsigned long h_index)
+{
+ return iter->h_index >= r_index && iter->r_index <= h_index;
+}
+
+/*
+ * prio_tree_first:
+ *
+ * Get the first prio_tree_node that overlaps with the interval [radix_index,
+ * heap_index]. Note that always radix_index <= heap_index. We do a pre-order
+ * traversal of the tree.
+ */
+static struct prio_tree_node *prio_tree_first(struct prio_tree_iter *iter)
+{
+ struct prio_tree_root *root;
+ unsigned long r_index, h_index;
+
+ INIT_PRIO_TREE_ITER(iter);
+
+ root = iter->root;
+ if (prio_tree_empty(root))
+ return NULL;
+
+ get_index(root, root->prio_tree_node, &r_index, &h_index);
+
+ if (iter->r_index > h_index)
+ return NULL;
+
+ iter->mask = 1UL << (root->index_bits - 1);
+ iter->cur = root->prio_tree_node;
+
+ while (1) {
+ if (overlap(iter, r_index, h_index))
+ return iter->cur;
+
+ if (prio_tree_left(iter, &r_index, &h_index))
+ continue;
+
+ if (prio_tree_right(iter, &r_index, &h_index))
+ continue;
+
+ break;
+ }
+ return NULL;
+}
+
+/*
+ * prio_tree_next:
+ *
+ * Get the next prio_tree_node that overlaps with the input interval in iter
+ */
+struct prio_tree_node *prio_tree_next(struct prio_tree_iter *iter)
+{
+ unsigned long r_index, h_index;
+
+ if (iter->cur == NULL)
+ return prio_tree_first(iter);
+
+repeat:
+ while (prio_tree_left(iter, &r_index, &h_index))
+ if (overlap(iter, r_index, h_index))
+ return iter->cur;
+
+ while (!prio_tree_right(iter, &r_index, &h_index)) {
+ while (!prio_tree_root(iter->cur) &&
+ iter->cur->parent->right == iter->cur)
+ prio_tree_parent(iter);
+
+ if (prio_tree_root(iter->cur))
+ return NULL;
+
+ prio_tree_parent(iter);
+ }
+
+ if (overlap(iter, r_index, h_index))
+ return iter->cur;
+
+ goto repeat;
+}
--
_________________________________________________________________________
/ Werner Almesberger, Buenos Aires, Argentina werner@almesberger.net /
/_http://www.almesberger.net/____________________________________________/
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 0/3] prio_tree generalization
2004-12-17 18:36 [PATCH 0/3] prio_tree generalization Werner Almesberger
` (2 preceding siblings ...)
2004-12-17 18:40 ` [PATCH 3/3] prio_tree: move general code from mm/ to lib/ Werner Almesberger
@ 2004-12-17 19:52 ` Andrew Morton
2004-12-17 23:10 ` [PATCH 3/3] prio_tree: move general code from mm/ to lib/ David Howells
4 siblings, 0 replies; 7+ messages in thread
From: Andrew Morton @ 2004-12-17 19:52 UTC (permalink / raw)
To: Werner Almesberger; +Cc: linux-kernel, vrajesh
Werner Almesberger <werner@almesberger.net> wrote:
>
> This patch set for 2.6.10-rc3-bk10 (*) generalizes the prio_tree
> code such that other subsystems than just VMA can use it.
>
> (*) I'm not sure which tree is the most useful base for this.
> Should I use 2.6.10-rc3-mm* instead of -bk* ? (Or is it
> already too late for 2.6.10 anyway ?)
Yes, 2.6.10 is in locked-down-try-to-get-the-bugs-out mode. I'll queue
these up for post-2.6.10.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 3/3] prio_tree: move general code from mm/ to lib/
2004-12-17 18:36 [PATCH 0/3] prio_tree generalization Werner Almesberger
` (3 preceding siblings ...)
2004-12-17 19:52 ` [PATCH 0/3] prio_tree generalization Andrew Morton
@ 2004-12-17 23:10 ` David Howells
2004-12-17 23:16 ` Werner Almesberger
4 siblings, 1 reply; 7+ messages in thread
From: David Howells @ 2004-12-17 23:10 UTC (permalink / raw)
To: Werner Almesberger; +Cc: linux-kernel, Rajesh Venkatasubramanian, Andrew Morton
Werner Almesberger <werner@almesberger.net> wrote:
>
> Note that this patch conflicts with a patch in 2.6.10-rc3-mm1
> (frv-better-mmap-support-in-uclinux.patch), which removes
> mm/prio_tree in systems without an MMU. Not making that other
> patch provide a dummy for prio_tree_init should resolve the
> conflict. (That's just from reading the patch - I haven't
> actually tried this.)
The prio_tree stuff can go back in for the nommu stuff. I've given Andrew a
patch to that effect (copied to LKML).
Subject: [PATCH] Cross-reference nommu VMAs with mappings
Date: Wed, 15 Dec 2004 15:55:35 +0000
David
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 3/3] prio_tree: move general code from mm/ to lib/
2004-12-17 23:10 ` [PATCH 3/3] prio_tree: move general code from mm/ to lib/ David Howells
@ 2004-12-17 23:16 ` Werner Almesberger
0 siblings, 0 replies; 7+ messages in thread
From: Werner Almesberger @ 2004-12-17 23:16 UTC (permalink / raw)
To: David Howells; +Cc: linux-kernel, Rajesh Venkatasubramanian, Andrew Morton
David Howells wrote:
> The prio_tree stuff can go back in for the nommu stuff. I've given Andrew a
> patch to that effect (copied to LKML).
Ah, found it. Great, so there should be no conflict anymore.
Thanks,
- Werner
--
_________________________________________________________________________
/ Werner Almesberger, Buenos Aires, Argentina werner@almesberger.net /
/_http://www.almesberger.net/____________________________________________/
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2004-12-17 23:17 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-12-17 18:36 [PATCH 0/3] prio_tree generalization Werner Almesberger
2004-12-17 18:37 ` [PATCH 1/3] prio_tree: roll call to prio_tree_first into prio_tree_next Werner Almesberger
2004-12-17 18:39 ` [PATCH 2/3] prio_tree: generalization Werner Almesberger
2004-12-17 18:40 ` [PATCH 3/3] prio_tree: move general code from mm/ to lib/ Werner Almesberger
2004-12-17 19:52 ` [PATCH 0/3] prio_tree generalization Andrew Morton
2004-12-17 23:10 ` [PATCH 3/3] prio_tree: move general code from mm/ to lib/ David Howells
2004-12-17 23:16 ` Werner Almesberger
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.