Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F157614046
D46314.id142133.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D46314.id142133.diff
View Options
Index: sys/amd64/amd64/pmap.c
===================================================================
--- sys/amd64/amd64/pmap.c
+++ sys/amd64/amd64/pmap.c
@@ -11464,8 +11464,8 @@
static bool
pmap_pkru_same(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, pt_entry_t *pte)
{
- struct pmap_pkru_range *next_ppr, *ppr;
- vm_offset_t va;
+ struct pctrie_iter ranges;
+ struct pmap_pkru_range *ppr;
u_int keyidx;
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
@@ -11476,20 +11476,14 @@
sva >= VM_MAXUSER_ADDRESS)
return (true);
MPASS(eva <= VM_MAXUSER_ADDRESS);
- ppr = rangeset_lookup(&pmap->pm_pkru, sva);
- if (ppr == NULL) {
- ppr = rangeset_next(&pmap->pm_pkru, sva);
- return (ppr == NULL ||
- ppr->pkru_rs_el.re_start >= eva);
- }
+ ppr = rangeset_lookup_iter(&ranges, &pmap->pm_pkru, sva);
+ if (ppr == NULL)
+ return (rangeset_empty_iter(&ranges, sva, eva));
keyidx = ppr->pkru_keyidx;
- while ((va = ppr->pkru_rs_el.re_end) < eva) {
- next_ppr = rangeset_next(&pmap->pm_pkru, va);
- if (next_ppr == NULL ||
- va != next_ppr->pkru_rs_el.re_start ||
- keyidx != next_ppr->pkru_keyidx)
+ while (ppr->pkru_rs_el.re_end < eva) {
+ if ((ppr = rangeset_next_iter(&ranges)) == NULL ||
+ keyidx != ppr->pkru_keyidx)
return (false);
- ppr = next_ppr;
}
*pte |= X86_PG_PKU(keyidx);
return (true);
Index: sys/arm64/arm64/pmap.c
===================================================================
--- sys/arm64/arm64/pmap.c
+++ sys/arm64/arm64/pmap.c
@@ -9365,8 +9365,8 @@
static bool
pmap_bti_same(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, pt_entry_t *pte)
{
- struct rs_el *next_rs, *rs;
- vm_offset_t va;
+ struct pctrie_iter ranges;
+ struct rs_el *rs;
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
KASSERT(ADDR_IS_CANONICAL(sva),
@@ -9383,18 +9383,12 @@
if (pmap->pm_bti == NULL)
return (true);
PMAP_ASSERT_STAGE1(pmap);
- rs = rangeset_lookup(pmap->pm_bti, sva);
- if (rs == NULL) {
- rs = rangeset_next(pmap->pm_bti, sva);
- return (rs == NULL ||
- rs->re_start >= eva);
- }
- while ((va = rs->re_end) < eva) {
- next_rs = rangeset_next(pmap->pm_bti, va);
- if (next_rs == NULL ||
- va != next_rs->re_start)
+ rs = rangeset_lookup_iter(&ranges, pmap->pm_bti, sva);
+ if (rs == NULL)
+ return (rangeset_empty_iter(&ranges, sva, eva));
+ while (rs->re_end < eva) {
+ if ((rs = rangeset_next_iter(&ranges)) == NULL)
return (false);
- rs = next_rs;
}
*pte |= ATTR_S1_GP;
return (true);
Index: sys/kern/subr_rangeset.c
===================================================================
--- sys/kern/subr_rangeset.c
+++ sys/kern/subr_rangeset.c
@@ -262,18 +262,40 @@
}
void *
-rangeset_next(struct rangeset *rs, uint64_t place)
+rangeset_lookup_iter(struct pctrie_iter *ranges, struct rangeset *rs,
+ uint64_t start)
{
+ struct rs_el *r;
rangeset_check(rs);
- return (RANGESET_PCTRIE_LOOKUP_GE(&rs->rs_trie, place));
+ pctrie_iter_init(ranges, &rs->rs_trie);
+ r = RANGESET_PCTRIE_ITER_LOOKUP_LE(ranges, start);
+ if (r != NULL && r->re_end < start)
+ return (r);
+ return (NULL);
+}
+
+bool
+rangeset_empty_iter(struct pctrie_iter *ranges, uint64_t start, uint64_t end)
+{
+ return (RANGESET_PCTRIE_ITER_LOOKUP_GE_LIMIT(
+ ranges, start + 1, end) == NULL);
+}
+
+void *
+rangeset_next_iter(struct pctrie_iter *ranges)
+{
+ struct rs_el *r;
+
+ r = RANGESET_PCTRIE_ITER_VALUE(ranges);
+ return (RANGESET_PCTRIE_ITER_LOOKUP(ranges, r->re_end));
}
int
rangeset_copy(struct rangeset *dst_rs, struct rangeset *src_rs)
{
+ struct pctrie_iter ranges;
struct rs_el *src_r, *dst_r;
- uint64_t cursor;
int error;
MPASS(pctrie_is_empty(&dst_rs->rs_trie));
@@ -281,10 +303,9 @@
MPASS(dst_rs->rs_dup_data == src_rs->rs_dup_data);
error = 0;
- for (cursor = 0;; cursor = src_r->re_start + 1) {
- src_r = RANGESET_PCTRIE_LOOKUP_GE(&src_rs->rs_trie, cursor);
- if (src_r == NULL)
- break;
+ pctrie_iter_init(&ranges, &src_rs->rs_trie);
+ for (src_r = RANGESET_PCTRIE_ITER_LOOKUP_GE(&ranges, 0);
+ src_r != NULL; src_r = RANGESET_PCTRIE_ITER_STEP_GE(&ranges)) {
dst_r = dst_rs->rs_dup_data(dst_rs->rs_data_ctx, src_r);
if (dst_r == NULL) {
error = ENOMEM;
@@ -303,13 +324,13 @@
static void
rangeset_check(struct rangeset *rs)
{
+ struct pctrie_iter ranges;
struct rs_el *r, *rp;
- uint64_t cursor;
- for (cursor = 0, rp = NULL;; cursor = r->re_start + 1, rp = r) {
- r = RANGESET_PCTRIE_LOOKUP_GE(&rs->rs_trie, cursor);
- if (r == NULL)
- break;
+ pctrie_iter_init(&ranges, &rs->rs_trie);
+ for (rp = NULL,
+ r = RANGESET_PCTRIE_ITER_LOOKUP_GE(&ranges, 0);
+ r != NULL; rp = r, r = RANGESET_PCTRIE_ITER_STEP_GE(&ranges)) {
KASSERT(r->re_start < r->re_end,
("invalid interval rs %p elem %p (%#jx, %#jx)",
rs, r, (uintmax_t)r->re_start, (uintmax_t)r->re_end));
@@ -332,9 +353,9 @@
DB_SHOW_COMMAND(rangeset, rangeset_show_fn)
{
+ struct pctrie_iter ranges;
struct rangeset *rs;
struct rs_el *r;
- uint64_t cursor;
if (!have_addr) {
db_printf("show rangeset addr\n");
@@ -343,10 +364,9 @@
rs = (struct rangeset *)addr;
db_printf("rangeset %p\n", rs);
- for (cursor = 0;; cursor = r->re_start + 1) {
- r = RANGESET_PCTRIE_LOOKUP_GE(&rs->rs_trie, cursor);
- if (r == NULL)
- break;
+ pctrie_iter_init(&ranges, &rs->rs_trie);
+ for (r = RANGESET_PCTRIE_ITER_LOOKUP_GE(&ranges, 0);
+ r != NULL; r = RANGESET_PCTRIE_ITER_STEP_GE(&ranges)) {
db_printf(" el %p start %#jx end %#jx\n",
r, r->re_start, r->re_end);
}
Index: sys/sys/rangeset.h
===================================================================
--- sys/sys/rangeset.h
+++ sys/sys/rangeset.h
@@ -34,6 +34,7 @@
#ifdef _KERNEL
#include <sys/_rangeset.h>
+struct pctrie_iter;
typedef bool (*rs_pred_t)(void *ctx, void *r);
@@ -75,10 +76,23 @@
void *rangeset_lookup(struct rangeset *rs, uint64_t place);
/*
- * Finds the first range that begins at or after place.
+ * Returns the range that includes 'place', if any, and saves in iter the path
+ * to that place..
*/
-void *rangeset_next(struct rangeset *rs, uint64_t place);
+void *rangeset_lookup_iter(struct pctrie_iter *ranges, struct rangeset *rs,
+ uint64_t start);
+/*
+ * After lookup_iter fails, report whether the interval from start to end is
+ * empty.
+ */
+bool rangeset_empty_iter(struct pctrie_iter *ranges, uint64_t sva,
+ uint64_t eva);
+
+/*
+ * Finds the range that abuts the current one to the right, if any.
+ */
+void *rangeset_next_iter(struct pctrie_iter *ranges);
/*
* Copies src_rs entries into dst_rs. dst_rs must be empty.
* Leaves dst_rs empty on failure.
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, May 24, 10:40 AM (9 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33470077
Default Alt Text
D46314.id142133.diff (6 KB)
Attached To
Mode
D46314: rangeset: speed up range traveral
Attached
Detach File
Event Timeline
Log In to Comment