Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F161562150
D36624.id110886.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D36624.id110886.diff
View Options
Index: share/man/man3/tree.3
===================================================================
--- share/man/man3/tree.3
+++ share/man/man3/tree.3
@@ -97,6 +97,8 @@
.Nm RB_FOREACH_REVERSE_SAFE ,
.Nm RB_INIT ,
.Nm RB_INSERT ,
+.Nm RB_INSERT_NEXT ,
+.Nm RB_INSERT_PREV ,
.Nm RB_REMOVE ,
.Nm RB_REINSERT ,
.Nm RB_AUGMENT
@@ -193,6 +195,10 @@
.Ft "struct TYPE *"
.Fn RB_INSERT NAME "RB_HEAD *head" "struct TYPE *elm"
.Ft "struct TYPE *"
+.Fn RB_INSERT_NEXT NAME "RB_HEAD *head" "struct TYPE *elm" "struct TYPE *next"
+.Ft "struct TYPE *"
+.Fn RB_INSERT_PREV NAME "RB_HEAD *head" "struct TYPE *elm" "struct TYPE *prev"
+.Ft "struct TYPE *"
.Fn RB_REMOVE NAME "RB_HEAD *head" "struct TYPE *elm"
.Ft "struct TYPE *"
.Fn RB_REINSERT NAME "RB_HEAD *head" "struct TYPE *elm"
@@ -515,6 +521,18 @@
into the tree.
.Pp
The
+.Fn RB_INSERT_NEXT
+macro inserts the new element
+.Fa elm
+into the tree immediately after a given element.
+.Pp
+The
+.Fn RB_INSERT_PREV
+macro inserts the new element
+.Fa elm
+into the tree immediately before a given element.
+.Pp
+The
.Fn RB_REMOVE
macro removes the element
.Fa elm
Index: sys/dev/iommu/iommu.h
===================================================================
--- sys/dev/iommu/iommu.h
+++ sys/dev/iommu/iommu.h
@@ -109,6 +109,7 @@
struct iommu_map_entries_tailq unload_entries; /* (d) Entries to
unload */
struct iommu_gas_entries_tree rb_root; /* (d) */
+ struct iommu_map_entry *start_gap; /* (d) */
iommu_gaddr_t end; /* (c) Highest address + 1 in
the guest AS */
struct iommu_map_entry *first_place, *last_place; /* (d) */
Index: sys/dev/iommu/iommu_gas.c
===================================================================
--- sys/dev/iommu/iommu_gas.c
+++ sys/dev/iommu/iommu_gas.c
@@ -219,6 +219,12 @@
iommu_gas_rb_remove(struct iommu_domain *domain, struct iommu_map_entry *entry)
{
+ /*
+ * The predecessor to the removed entry may become the new greatest
+ * lower bound on free gaps.
+ */
+ if (entry->end <= domain->start_gap->end)
+ domain->start_gap = iommu_gas_entries_tree_RB_PREV(entry);
RB_REMOVE(iommu_gas_entries_tree, &domain->rb_root, entry);
}
@@ -262,6 +268,7 @@
begin->flags = IOMMU_MAP_ENTRY_PLACE | IOMMU_MAP_ENTRY_UNMAPPED;
iommu_gas_rb_insert(domain, begin);
+ domain->start_gap = begin;
domain->first_place = begin;
domain->last_place = end;
domain->flags |= IOMMU_DOMAIN_GAS_INITED;
@@ -283,7 +290,7 @@
KASSERT(entry->flags ==
(IOMMU_MAP_ENTRY_PLACE | IOMMU_MAP_ENTRY_UNMAPPED),
("start entry flags %p", domain));
- RB_REMOVE(iommu_gas_entries_tree, &domain->rb_root, entry);
+ iommu_gas_rb_remove(domain, entry);
iommu_gas_free_entry(entry);
entry = RB_MAX(iommu_gas_entries_tree, &domain->rb_root);
@@ -292,15 +299,14 @@
KASSERT(entry->flags ==
(IOMMU_MAP_ENTRY_PLACE | IOMMU_MAP_ENTRY_UNMAPPED),
("end entry flags %p", domain));
- RB_REMOVE(iommu_gas_entries_tree, &domain->rb_root, entry);
+ iommu_gas_rb_remove(domain, entry);
iommu_gas_free_entry(entry);
RB_FOREACH_SAFE(entry, iommu_gas_entries_tree, &domain->rb_root,
entry1) {
KASSERT((entry->flags & IOMMU_MAP_ENTRY_RMRR) != 0,
("non-RMRR entry left %p", domain));
- RB_REMOVE(iommu_gas_entries_tree, &domain->rb_root,
- entry);
+ iommu_gas_rb_remove(domain, entry);
iommu_gas_free_entry(entry);
}
}
@@ -380,9 +386,9 @@
entry->start = start;
entry->end = start + roundup2(size + offset, IOMMU_PAGE_SIZE);
entry->flags = IOMMU_MAP_ENTRY_MAP;
- found = iommu_gas_rb_insert(a->domain, entry);
- KASSERT(found, ("found dup %p start %jx size %jx",
- a->domain, (uintmax_t)start, (uintmax_t)size));
+ /* The new entry may be a new, greater lower bound on free gaps. */
+ if (start <= a->domain->start_gap->end + 3 * IOMMU_PAGE_SIZE)
+ a->domain->start_gap = entry;
return (true);
}
@@ -431,32 +437,36 @@
* Find the first entry in the lower region that could abut a big-enough
* range.
*/
- curr = RB_ROOT(&a->domain->rb_root);
- first = NULL;
- while (curr != NULL && curr->free_down >= min_free) {
- first = curr;
- curr = RB_LEFT(curr, rb_entry);
- }
+ first = a->domain->start_gap;
+ while (first != NULL && first->free_down < min_free)
+ first = RB_PARENT(first, rb_entry);
/*
* Walk the big-enough ranges until one satisfies alignment
* requirements, or violates lowaddr address requirement.
*/
+ domain = a->domain;
addr = a->common->lowaddr + 1;
for (curr = first; curr != NULL;
curr = iommu_gas_next(curr, min_free)) {
if ((first = RB_LEFT(curr, rb_entry)) != NULL &&
iommu_gas_match_one(a, first->last, curr->start,
- 0, addr))
+ 0, addr)) {
+ RB_INSERT_PREV(iommu_gas_entries_tree,
+ &domain->rb_root, curr, a->entry);
return (0);
+ }
if (curr->end >= addr) {
/* All remaining ranges >= addr */
break;
}
if ((first = RB_RIGHT(curr, rb_entry)) != NULL &&
iommu_gas_match_one(a, curr->end, first->first,
- 0, addr))
+ 0, addr)) {
+ RB_INSERT_NEXT(iommu_gas_entries_tree,
+ &domain->rb_root, curr, a->entry);
return (0);
+ }
}
/*
@@ -481,17 +491,22 @@
* Walk the remaining big-enough ranges until one satisfies alignment
* requirements.
*/
- domain = a->domain;
for (curr = first; curr != NULL;
curr = iommu_gas_next(curr, min_free)) {
if ((first = RB_LEFT(curr, rb_entry)) != NULL &&
iommu_gas_match_one(a, first->last, curr->start,
- addr + 1, domain->end))
+ addr + 1, domain->end)) {
+ RB_INSERT_PREV(iommu_gas_entries_tree,
+ &domain->rb_root, curr, a->entry);
return (0);
+ }
if ((first = RB_RIGHT(curr, rb_entry)) != NULL &&
iommu_gas_match_one(a, curr->end, first->first,
- addr + 1, domain->end))
+ addr + 1, domain->end)) {
+ RB_INSERT_NEXT(iommu_gas_entries_tree,
+ &domain->rb_root, curr, a->entry);
return (0);
+ }
}
return (ENOMEM);
Index: sys/sys/tree.h
===================================================================
--- sys/sys/tree.h
+++ sys/sys/tree.h
@@ -414,12 +414,15 @@
RB_PROTOTYPE_RANK(name, type, attr) \
RB_PROTOTYPE_INSERT_COLOR(name, type, attr); \
RB_PROTOTYPE_REMOVE_COLOR(name, type, attr); \
+ RB_PROTOTYPE_INSERT_FINISH(name, type, attr); \
RB_PROTOTYPE_INSERT(name, type, attr); \
RB_PROTOTYPE_REMOVE(name, type, attr); \
RB_PROTOTYPE_FIND(name, type, attr); \
RB_PROTOTYPE_NFIND(name, type, attr); \
RB_PROTOTYPE_NEXT(name, type, attr); \
+ RB_PROTOTYPE_INSERT_NEXT(name, type, attr); \
RB_PROTOTYPE_PREV(name, type, attr); \
+ RB_PROTOTYPE_INSERT_PREV(name, type, attr); \
RB_PROTOTYPE_MINMAX(name, type, attr); \
RB_PROTOTYPE_REINSERT(name, type, attr);
#ifdef _RB_DIAGNOSTIC
@@ -436,6 +439,9 @@
struct type *, struct type *)
#define RB_PROTOTYPE_REMOVE(name, type, attr) \
attr struct type *name##_RB_REMOVE(struct name *, struct type *)
+#define RB_PROTOTYPE_INSERT_FINISH(name, type, attr) \
+ attr struct type *name##_RB_INSERT_FINISH(struct name *, \
+ struct type *, struct type **, struct type *)
#define RB_PROTOTYPE_INSERT(name, type, attr) \
attr struct type *name##_RB_INSERT(struct name *, struct type *)
#define RB_PROTOTYPE_FIND(name, type, attr) \
@@ -444,8 +450,14 @@
attr struct type *name##_RB_NFIND(struct name *, struct type *)
#define RB_PROTOTYPE_NEXT(name, type, attr) \
attr struct type *name##_RB_NEXT(struct type *)
+#define RB_PROTOTYPE_INSERT_NEXT(name, type, attr) \
+ attr struct type *name##_RB_INSERT_NEXT(struct name *, \
+ struct type *, struct type *)
#define RB_PROTOTYPE_PREV(name, type, attr) \
attr struct type *name##_RB_PREV(struct type *)
+#define RB_PROTOTYPE_INSERT_PREV(name, type, attr) \
+ attr struct type *name##_RB_INSERT_PREV(struct name *, \
+ struct type *, struct type *)
#define RB_PROTOTYPE_MINMAX(name, type, attr) \
attr struct type *name##_RB_MINMAX(struct name *, int)
#define RB_PROTOTYPE_REINSERT(name, type, attr) \
@@ -462,12 +474,15 @@
RB_GENERATE_RANK(name, type, field, attr) \
RB_GENERATE_INSERT_COLOR(name, type, field, attr) \
RB_GENERATE_REMOVE_COLOR(name, type, field, attr) \
+ RB_GENERATE_INSERT_FINISH(name, type, field, attr) \
RB_GENERATE_INSERT(name, type, field, cmp, attr) \
RB_GENERATE_REMOVE(name, type, field, attr) \
RB_GENERATE_FIND(name, type, field, cmp, attr) \
RB_GENERATE_NFIND(name, type, field, cmp, attr) \
RB_GENERATE_NEXT(name, type, field, attr) \
+ RB_GENERATE_INSERT_NEXT(name, type, field, attr) \
RB_GENERATE_PREV(name, type, field, attr) \
+ RB_GENERATE_INSERT_PREV(name, type, field, attr) \
RB_GENERATE_MINMAX(name, type, field, attr) \
RB_GENERATE_REINSERT(name, type, field, cmp, attr)
@@ -786,6 +801,24 @@
return (out); \
}
+#define RB_GENERATE_INSERT_FINISH(name, type, field, attr) \
+/* Inserts a node into the RB tree */ \
+attr struct type * \
+name##_RB_INSERT_FINISH(struct name *head, struct type *parent, \
+ struct type **pptr, struct type *elm) \
+{ \
+ struct type *tmp = NULL; \
+ \
+ RB_SET(elm, parent, field); \
+ *pptr = elm; \
+ if (parent != NULL) \
+ tmp = name##_RB_INSERT_COLOR(head, parent, elm); \
+ _RB_AUGMENT_WALK(elm, tmp, field); \
+ if (tmp != NULL) \
+ RB_AUGMENT_CHECK(tmp); \
+ return (NULL); \
+}
+
#define RB_GENERATE_INSERT(name, type, field, cmp, attr) \
/* Inserts a node into the RB tree */ \
attr struct type * \
@@ -805,14 +838,7 @@
else \
return (parent); \
} \
- RB_SET(elm, parent, field); \
- *tmpp = elm; \
- if (parent != NULL) \
- tmp = name##_RB_INSERT_COLOR(head, parent, elm); \
- _RB_AUGMENT_WALK(elm, tmp, field); \
- if (tmp != NULL) \
- RB_AUGMENT_CHECK(tmp); \
- return (NULL); \
+ return (name##_RB_INSERT_FINISH(head, parent, tmpp, elm)); \
}
#define RB_GENERATE_FIND(name, type, field, cmp, attr) \
@@ -874,6 +900,22 @@
return (elm); \
}
+#define RB_GENERATE_INSERT_NEXT(name, type, field, attr) \
+/* Inserts a node into the next position in the RB tree */ \
+attr struct type * \
+name##_RB_INSERT_NEXT(struct name *head, \
+ struct type *elm, struct type *next) \
+{ \
+ struct type *tmp; \
+ struct type **tmpp = &RB_RIGHT(elm, field); \
+ \
+ while ((tmp = *tmpp) != NULL) { \
+ elm = tmp; \
+ tmpp = &RB_LEFT(elm, field); \
+ } \
+ return (name##_RB_INSERT_FINISH(head, elm, tmpp, next)); \
+}
+
#define RB_GENERATE_PREV(name, type, field, attr) \
/* ARGSUSED */ \
attr struct type * \
@@ -892,6 +934,22 @@
return (elm); \
}
+#define RB_GENERATE_INSERT_PREV(name, type, field, attr) \
+/* Inserts a node into the prev position in the RB tree */ \
+attr struct type * \
+name##_RB_INSERT_PREV(struct name *head, \
+ struct type *elm, struct type *prev) \
+{ \
+ struct type *tmp; \
+ struct type **tmpp = &RB_LEFT(elm, field); \
+ \
+ while ((tmp = *tmpp) != NULL) { \
+ elm = tmp; \
+ tmpp = &RB_RIGHT(elm, field); \
+ } \
+ return (name##_RB_INSERT_FINISH(head, elm, tmpp, prev)); \
+}
+
#define RB_GENERATE_MINMAX(name, type, field, attr) \
attr struct type * \
name##_RB_MINMAX(struct name *head, int val) \
@@ -928,6 +986,8 @@
#define RB_INF 1
#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
+#define RB_INSERT_NEXT(name, x, y, z) name##_RB_INSERT_NEXT(x, y, z)
+#define RB_INSERT_PREV(name, x, y, z) name##_RB_INSERT_PREV(x, y, z)
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jul 5, 9:37 PM (18 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34725020
Default Alt Text
D36624.id110886.diff (11 KB)
Attached To
Mode
D36624: iommu_gas: start space search from first free space
Attached
Detach File
Event Timeline
Log In to Comment