Deleted Added
full compact
vm_radix.c (245254) vm_radix.c (246430)
1/*
2 * Copyright (c) 2011 Jeffrey Roberson <jeff@freebsd.org>
3 * Copyright (c) 2008 Mayur Shardul <mayur.shardul@gmail.com>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 278 unchanged lines hidden (view full) ---

287 int height)
288{
289 uintptr_t root;
290
291 root = (uintptr_t)rnode | height;
292 rtree->rt_root = root;
293}
294
1/*
2 * Copyright (c) 2011 Jeffrey Roberson <jeff@freebsd.org>
3 * Copyright (c) 2008 Mayur Shardul <mayur.shardul@gmail.com>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 278 unchanged lines hidden (view full) ---

287 int height)
288{
289 uintptr_t root;
290
291 root = (uintptr_t)rnode | height;
292 rtree->rt_root = root;
293}
294
295static inline void *
295static inline vm_page_t
296vm_radix_match(void *child)
297{
298 uintptr_t c;
299
300 c = (uintptr_t)child;
301
296vm_radix_match(void *child)
297{
298 uintptr_t c;
299
300 c = (uintptr_t)child;
301
302 return ((void *)(c & ~VM_RADIX_FLAGS));
302 return ((vm_page_t)(c & ~VM_RADIX_FLAGS));
303}
304
305static void
306vm_radix_reclaim_allnodes_internal(struct vm_radix_node *rnode, int level)
307{
308 int slot;
309
310 MPASS(rnode != NULL && level >= 0);

--- 22 unchanged lines hidden (view full) ---

333 CTR2(KTR_VM, "reclaiming: node %p, level %d", rnode, level);
334 vm_radix_node_put(rnode);
335}
336
337/*
338 * Inserts the key-value pair in to the radix tree. Returns errno.
339 * Panics if the key already exists.
340 */
303}
304
305static void
306vm_radix_reclaim_allnodes_internal(struct vm_radix_node *rnode, int level)
307{
308 int slot;
309
310 MPASS(rnode != NULL && level >= 0);

--- 22 unchanged lines hidden (view full) ---

333 CTR2(KTR_VM, "reclaiming: node %p, level %d", rnode, level);
334 vm_radix_node_put(rnode);
335}
336
337/*
338 * Inserts the key-value pair in to the radix tree. Returns errno.
339 * Panics if the key already exists.
340 */
341int
342vm_radix_insert(struct vm_radix *rtree, vm_pindex_t index, void *val)
341void
342vm_radix_insert(struct vm_radix *rtree, vm_pindex_t index, vm_page_t page)
343{
344 struct vm_radix_node *rnode;
345 struct vm_radix_node *root;
346 int level;
347 int slot;
348
349 CTR4(KTR_VM,
343{
344 struct vm_radix_node *rnode;
345 struct vm_radix_node *root;
346 int level;
347 int slot;
348
349 CTR4(KTR_VM,
350 "insert: tree %p, " KFRMT64(index) ", val %p", rtree,
351 KSPLT64L(index), KSPLT64H(index), val);
350 "insert: tree %p, " KFRMT64(index) ", page %p", rtree,
351 KSPLT64L(index), KSPLT64H(index), page);
352 if (index == -1)
353 panic("vm_radix_insert: -1 is not a valid index.\n");
354 level = vm_radix_height(rtree, &root);
355 /*
356 * Increase the height by adding nodes at the root until
357 * there is sufficient space.
358 */
359 while (level == 0 || index > VM_RADIX_MAX(level)) {

--- 11 unchanged lines hidden (view full) ---

371 */
372 if (root == NULL || root->rn_count != 0) {
373 rnode = vm_radix_node_get();
374 if (rnode == NULL) {
375 CTR5(KTR_VM,
376 "insert: tree %p, root %p, " KFRMT64(index) ", level %d ENOMEM",
377 rtree, root, KSPLT64L(index),
378 KSPLT64H(index), level);
352 if (index == -1)
353 panic("vm_radix_insert: -1 is not a valid index.\n");
354 level = vm_radix_height(rtree, &root);
355 /*
356 * Increase the height by adding nodes at the root until
357 * there is sufficient space.
358 */
359 while (level == 0 || index > VM_RADIX_MAX(level)) {

--- 11 unchanged lines hidden (view full) ---

371 */
372 if (root == NULL || root->rn_count != 0) {
373 rnode = vm_radix_node_get();
374 if (rnode == NULL) {
375 CTR5(KTR_VM,
376 "insert: tree %p, root %p, " KFRMT64(index) ", level %d ENOMEM",
377 rtree, root, KSPLT64L(index),
378 KSPLT64H(index), level);
379 return (ENOMEM);
379 panic("vm_radix_insert: failed allocation");
380 }
381 /*
382 * Store the new pointer with a memory barrier so
383 * that it is visible before the new root.
384 */
385 if (root) {
386 atomic_store_rel_ptr((volatile uintptr_t *)
387 &rnode->rn_child[0], (uintptr_t)root);

--- 15 unchanged lines hidden (view full) ---

403 CTR6(KTR_VM,
404 "insert: tree %p, " KFRMT64(index) ", level %d, slot %d, rnode %p ENOMEM",
405 rtree, KSPLT64L(index), KSPLT64H(index),
406 level, slot, rnode);
407 CTR4(KTR_VM,
408 "insert: tree %p, rnode %p, child %p, count %u ENOMEM",
409 rtree, rnode, rnode->rn_child[slot],
410 rnode->rn_count);
380 }
381 /*
382 * Store the new pointer with a memory barrier so
383 * that it is visible before the new root.
384 */
385 if (root) {
386 atomic_store_rel_ptr((volatile uintptr_t *)
387 &rnode->rn_child[0], (uintptr_t)root);

--- 15 unchanged lines hidden (view full) ---

403 CTR6(KTR_VM,
404 "insert: tree %p, " KFRMT64(index) ", level %d, slot %d, rnode %p ENOMEM",
405 rtree, KSPLT64L(index), KSPLT64H(index),
406 level, slot, rnode);
407 CTR4(KTR_VM,
408 "insert: tree %p, rnode %p, child %p, count %u ENOMEM",
409 rtree, rnode, rnode->rn_child[slot],
410 rnode->rn_count);
411 return (ENOMEM);
411 panic("vm_radix_insert: failed allocation");
412 }
413 rnode->rn_count++;
414 }
415 CTR6(KTR_VM,
416 "insert: tree %p, " KFRMT64(index) ", level %d, slot %d, rnode %p",
417 rtree, KSPLT64L(index), KSPLT64H(index), level, slot,
418 rnode);
419 CTR4(KTR_VM,
420 "insert: tree %p, rnode %p, child %p, count %u",
421 rtree, rnode, rnode->rn_child[slot], rnode->rn_count);
422 rnode = rnode->rn_child[slot];
423 }
424
425 slot = vm_radix_slot(index, 0);
426 MPASS(rnode != NULL);
427 KASSERT(rnode->rn_child[slot] == NULL,
428 ("vm_radix_insert: Duplicate value %p at index: %lu\n",
429 rnode->rn_child[slot], (u_long)index));
412 }
413 rnode->rn_count++;
414 }
415 CTR6(KTR_VM,
416 "insert: tree %p, " KFRMT64(index) ", level %d, slot %d, rnode %p",
417 rtree, KSPLT64L(index), KSPLT64H(index), level, slot,
418 rnode);
419 CTR4(KTR_VM,
420 "insert: tree %p, rnode %p, child %p, count %u",
421 rtree, rnode, rnode->rn_child[slot], rnode->rn_count);
422 rnode = rnode->rn_child[slot];
423 }
424
425 slot = vm_radix_slot(index, 0);
426 MPASS(rnode != NULL);
427 KASSERT(rnode->rn_child[slot] == NULL,
428 ("vm_radix_insert: Duplicate value %p at index: %lu\n",
429 rnode->rn_child[slot], (u_long)index));
430 rnode->rn_child[slot] = val;
430 rnode->rn_child[slot] = page;
431 rnode->rn_count++;
432 CTR5(KTR_VM,
433 "insert: tree %p, " KFRMT64(index) ", level %d, slot %d",
434 rtree, KSPLT64L(index), KSPLT64H(index), level, slot);
435 CTR3(KTR_VM, "insert: slot %d, rnode %p, count %u", slot, rnode,
436 rnode->rn_count);
431 rnode->rn_count++;
432 CTR5(KTR_VM,
433 "insert: tree %p, " KFRMT64(index) ", level %d, slot %d",
434 rtree, KSPLT64L(index), KSPLT64H(index), level, slot);
435 CTR3(KTR_VM, "insert: slot %d, rnode %p, count %u", slot, rnode,
436 rnode->rn_count);
437
438 return 0;
439}
440
441/*
442 * Returns the value stored at the index. If the index is not present
443 * NULL is returned.
444 */
437}
438
439/*
440 * Returns the value stored at the index. If the index is not present
441 * NULL is returned.
442 */
445void *
443vm_page_t
446vm_radix_lookup(struct vm_radix *rtree, vm_pindex_t index)
447{
448 struct vm_radix_node *rnode;
449 int slot;
450 int level;
451
452 level = vm_radix_height(rtree, &rnode);
453 if (index > VM_RADIX_MAX(level))

--- 92 unchanged lines hidden (view full) ---

546out:
547 *startp = start;
548 return (rnode);
549}
550
551/*
552 * Look up any entry at a position bigger than or equal to index.
553 */
444vm_radix_lookup(struct vm_radix *rtree, vm_pindex_t index)
445{
446 struct vm_radix_node *rnode;
447 int slot;
448 int level;
449
450 level = vm_radix_height(rtree, &rnode);
451 if (index > VM_RADIX_MAX(level))

--- 92 unchanged lines hidden (view full) ---

544out:
545 *startp = start;
546 return (rnode);
547}
548
549/*
550 * Look up any entry at a position bigger than or equal to index.
551 */
554void *
555vm_radix_lookup_ge(struct vm_radix *rtree, vm_pindex_t start)
552vm_page_t
553vm_radix_lookup_ge(struct vm_radix *rtree, vm_pindex_t index)
556{
554{
555 vm_page_t page;
557 struct vm_radix_node *rnode;
556 struct vm_radix_node *rnode;
558 void *val;
559 int slot;
560
557 int slot;
558
561 CTR3(KTR_VM, "lookupn: tree %p, " KFRMT64(start), rtree,
562 KSPLT64L(start), KSPLT64H(start));
559 CTR3(KTR_VM, "lookupn: tree %p, " KFRMT64(index), rtree,
560 KSPLT64L(index), KSPLT64H(index));
563 if (rtree->rt_root == 0)
564 return (NULL);
561 if (rtree->rt_root == 0)
562 return (NULL);
565 while ((rnode = vm_radix_leaf(rtree, &start)) != NULL) {
566 slot = vm_radix_slot(start, 0);
567 for (; slot < VM_RADIX_COUNT; slot++, start++) {
568 val = vm_radix_match(rnode->rn_child[slot]);
569 if (val == NULL) {
563 while ((rnode = vm_radix_leaf(rtree, &index)) != NULL) {
564 slot = vm_radix_slot(index, 0);
565 for (; slot < VM_RADIX_COUNT; slot++, index++) {
566 page = vm_radix_match(rnode->rn_child[slot]);
567 if (page == NULL) {
570
571 /*
568
569 /*
572 * The start address can wrap at the
570 * The index address can wrap at the
573 * VM_RADIX_MAXVAL value.
571 * VM_RADIX_MAXVAL value.
574 * We need to make sure that start address
572 * We need to make sure that index address
575 * point to the next chunk (even if wrapping)
576 * to stay consistent with default scanning
577 * behaviour. Also, because of the nature
578 * of the wrapping, the wrap up checks must
579 * be done after all the necessary controls
573 * point to the next chunk (even if wrapping)
574 * to stay consistent with default scanning
575 * behaviour. Also, because of the nature
576 * of the wrapping, the wrap up checks must
577 * be done after all the necessary controls
580 * on start are completed.
578 * on index are completed.
581 */
579 */
582 if ((VM_RADIX_MAXVAL - start) == 0)
580 if ((VM_RADIX_MAXVAL - index) == 0)
583 return (NULL);
584 continue;
585 }
586 CTR5(KTR_VM,
587 "lookupn: tree %p " KFRMT64(index) " slot %d found child %p",
581 return (NULL);
582 continue;
583 }
584 CTR5(KTR_VM,
585 "lookupn: tree %p " KFRMT64(index) " slot %d found child %p",
588 rtree, KSPLT64L(start), KSPLT64H(start), slot, val);
589 return (val);
586 rtree, KSPLT64L(index), KSPLT64H(index), slot,
587 page);
588 return (page);
590 }
589 }
591 MPASS((VM_RADIX_MAXVAL - start) != 0);
590 MPASS((VM_RADIX_MAXVAL - index) != 0);
592 }
593 return (NULL);
594}
595
596/*
597 * Look up any entry at a position less than or equal to index.
598 */
591 }
592 return (NULL);
593}
594
595/*
596 * Look up any entry at a position less than or equal to index.
597 */
599void *
598vm_page_t
600vm_radix_lookup_le(struct vm_radix *rtree, vm_pindex_t index)
601{
602 struct vm_radix_node *rnode;
603 struct vm_radix_node *child;
604 vm_pindex_t max;
605 vm_pindex_t inc;
599vm_radix_lookup_le(struct vm_radix *rtree, vm_pindex_t index)
600{
601 struct vm_radix_node *rnode;
602 struct vm_radix_node *child;
603 vm_pindex_t max;
604 vm_pindex_t inc;
606 void *val;
605 vm_page_t page;
607 int slot;
608 int level;
609
610 CTR3(KTR_VM, "lookup_le: tree %p, " KFRMT64(index), rtree,
611 KSPLT64L(index), KSPLT64H(index));
612restart:
613 level = vm_radix_height(rtree, &rnode);
614 if (rnode == NULL)

--- 41 unchanged lines hidden (view full) ---

656 break;
657 }
658 }
659 rnode = child;
660 level--;
661 }
662 if (rnode) {
663 for (; slot >= 0; slot--, index--) {
606 int slot;
607 int level;
608
609 CTR3(KTR_VM, "lookup_le: tree %p, " KFRMT64(index), rtree,
610 KSPLT64L(index), KSPLT64H(index));
611restart:
612 level = vm_radix_height(rtree, &rnode);
613 if (rnode == NULL)

--- 41 unchanged lines hidden (view full) ---

655 break;
656 }
657 }
658 rnode = child;
659 level--;
660 }
661 if (rnode) {
662 for (; slot >= 0; slot--, index--) {
664 val = vm_radix_match(rnode->rn_child[slot]);
665 if (val)
666 return (val);
663 page = vm_radix_match(rnode->rn_child[slot]);
664 if (page)
665 return (page);
667 }
668 }
669 if (index != -1)
670 goto restart;
671 return (NULL);
672}
673
674/*

--- 88 unchanged lines hidden ---
666 }
667 }
668 if (index != -1)
669 goto restart;
670 return (NULL);
671}
672
673/*

--- 88 unchanged lines hidden ---