Deleted Added
full compact
vm_radix.c (238245) vm_radix.c (245254)
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:

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

472 return NULL;
473}
474
475/*
476 * Find the first leaf with a valid node between *startp and end. Return
477 * the index of the first valid item in the leaf in *startp.
478 */
479static struct vm_radix_node *
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:

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

472 return NULL;
473}
474
475/*
476 * Find the first leaf with a valid node between *startp and end. Return
477 * the index of the first valid item in the leaf in *startp.
478 */
479static struct vm_radix_node *
480vm_radix_leaf(struct vm_radix *rtree, vm_pindex_t *startp, vm_pindex_t end)
480vm_radix_leaf(struct vm_radix *rtree, vm_pindex_t *startp)
481{
482 struct vm_radix_node *rnode;
483 vm_pindex_t start;
484 vm_pindex_t inc;
485 int slot;
486 int level;
487
488 start = *startp;
489restart:
490 level = vm_radix_height(rtree, &rnode);
481{
482 struct vm_radix_node *rnode;
483 vm_pindex_t start;
484 vm_pindex_t inc;
485 int slot;
486 int level;
487
488 start = *startp;
489restart:
490 level = vm_radix_height(rtree, &rnode);
491 if (start > VM_RADIX_MAX(level) || (end && start >= end)) {
491 if (start > VM_RADIX_MAX(level)) {
492 rnode = NULL;
493 goto out;
494 }
495 /*
496 * Search the tree from the top for any leaf node holding an index
492 rnode = NULL;
493 goto out;
494 }
495 /*
496 * Search the tree from the top for any leaf node holding an index
497 * between start and end.
497 * between start and maxval.
498 */
499 for (level--; level; level--) {
500 slot = vm_radix_slot(start, level);
501 CTR6(KTR_VM,
502 "leaf: tree %p, " KFRMT64(start) ", level %d, slot %d, rnode %p",
503 rtree, KSPLT64L(start), KSPLT64H(start), level, slot,
504 rnode);
505 CTR2(KTR_VM, "leaf: rnode %p, child %p", rnode,

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

519
520 /* Avoid start address wrapping up. */
521 if ((VM_RADIX_MAXVAL - start) < inc) {
522 rnode = NULL;
523 goto out;
524 }
525 start += inc;
526 slot++;
498 */
499 for (level--; level; level--) {
500 slot = vm_radix_slot(start, level);
501 CTR6(KTR_VM,
502 "leaf: tree %p, " KFRMT64(start) ", level %d, slot %d, rnode %p",
503 rtree, KSPLT64L(start), KSPLT64H(start), level, slot,
504 rnode);
505 CTR2(KTR_VM, "leaf: rnode %p, child %p", rnode,

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

519
520 /* Avoid start address wrapping up. */
521 if ((VM_RADIX_MAXVAL - start) < inc) {
522 rnode = NULL;
523 goto out;
524 }
525 start += inc;
526 slot++;
527 CTR6(KTR_VM,
528 "leaf: " KFRMT64(start) ", " KFRMT64(end) ", " KFRMT64(inc),
529 KSPLT64L(start), KSPLT64H(start), KSPLT64L(end),
530 KSPLT64H(end), KSPLT64L(inc), KSPLT64H(inc));
527 CTR4(KTR_VM,
528 "leaf: " KFRMT64(start) ", " KFRMT64(inc),
529 KSPLT64L(start), KSPLT64H(start), KSPLT64L(inc),
530 KSPLT64H(inc));
531 CTR2(KTR_VM, "leaf: level %d, slot %d", level, slot);
532 for (; slot < VM_RADIX_COUNT; slot++, start += inc) {
531 CTR2(KTR_VM, "leaf: level %d, slot %d", level, slot);
532 for (; slot < VM_RADIX_COUNT; slot++, start += inc) {
533 if (end != 0 && start >= end) {
534 rnode = NULL;
535 goto out;
536 }
537 if (rnode->rn_child[slot]) {
538 rnode = rnode->rn_child[slot];
539 break;
540 }
541 if ((VM_RADIX_MAXVAL - start) < inc) {
542 rnode = NULL;
543 goto out;
544 }
545 }
546 if (slot == VM_RADIX_COUNT)
547 goto restart;
548 }
549
550out:
551 *startp = start;
552 return (rnode);
553}
554
533 if (rnode->rn_child[slot]) {
534 rnode = rnode->rn_child[slot];
535 break;
536 }
537 if ((VM_RADIX_MAXVAL - start) < inc) {
538 rnode = NULL;
539 goto out;
540 }
541 }
542 if (slot == VM_RADIX_COUNT)
543 goto restart;
544 }
545
546out:
547 *startp = start;
548 return (rnode);
549}
550
555
556
557/*
551/*
558 * Looks up as many as cnt values between start and end, and stores
559 * them in the caller allocated array out. The next index can be used
560 * to restart the scan. This optimizes forward scans in the tree.
552 * Look up any entry at a position bigger than or equal to index.
561 */
553 */
562int
563vm_radix_lookupn(struct vm_radix *rtree, vm_pindex_t start,
564 vm_pindex_t end, void **out, int cnt, vm_pindex_t *next, u_int *exhausted)
554void *
555vm_radix_lookup_ge(struct vm_radix *rtree, vm_pindex_t start)
565{
566 struct vm_radix_node *rnode;
567 void *val;
568 int slot;
556{
557 struct vm_radix_node *rnode;
558 void *val;
559 int slot;
569 int outidx;
570
560
571 CTR5(KTR_VM, "lookupn: tree %p, " KFRMT64(start) ", " KFRMT64(end),
572 rtree, KSPLT64L(start), KSPLT64H(start), KSPLT64L(end),
573 KSPLT64H(end));
574 if (end == 0)
575 *exhausted = 0;
561 CTR3(KTR_VM, "lookupn: tree %p, " KFRMT64(start), rtree,
562 KSPLT64L(start), KSPLT64H(start));
576 if (rtree->rt_root == 0)
563 if (rtree->rt_root == 0)
577 return (0);
578 outidx = 0;
579 while ((rnode = vm_radix_leaf(rtree, &start, end)) != NULL) {
564 return (NULL);
565 while ((rnode = vm_radix_leaf(rtree, &start)) != NULL) {
580 slot = vm_radix_slot(start, 0);
581 for (; slot < VM_RADIX_COUNT; slot++, start++) {
566 slot = vm_radix_slot(start, 0);
567 for (; slot < VM_RADIX_COUNT; slot++, start++) {
582 if (end != 0 && start >= end)
583 goto out;
584 val = vm_radix_match(rnode->rn_child[slot]);
585 if (val == NULL) {
586
587 /*
588 * The start address can wrap at the
589 * VM_RADIX_MAXVAL value.
590 * We need to make sure that start address
591 * point to the next chunk (even if wrapping)
592 * to stay consistent with default scanning
593 * behaviour. Also, because of the nature
594 * of the wrapping, the wrap up checks must
595 * be done after all the necessary controls
596 * on start are completed.
597 */
568 val = vm_radix_match(rnode->rn_child[slot]);
569 if (val == NULL) {
570
571 /*
572 * The start address can wrap at the
573 * VM_RADIX_MAXVAL value.
574 * We need to make sure that start 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
580 * on start are completed.
581 */
598 if ((VM_RADIX_MAXVAL - start) == 0) {
599 start++;
600 if (end == 0)
601 *exhausted = 1;
602 goto out;
603 }
582 if ((VM_RADIX_MAXVAL - start) == 0)
583 return (NULL);
604 continue;
605 }
606 CTR5(KTR_VM,
607 "lookupn: tree %p " KFRMT64(index) " slot %d found child %p",
608 rtree, KSPLT64L(start), KSPLT64H(start), slot, val);
584 continue;
585 }
586 CTR5(KTR_VM,
587 "lookupn: tree %p " KFRMT64(index) " slot %d found child %p",
588 rtree, KSPLT64L(start), KSPLT64H(start), slot, val);
609 out[outidx] = val;
610 if (++outidx == cnt ||
611 (VM_RADIX_MAXVAL - start) == 0) {
612 start++;
613 if ((VM_RADIX_MAXVAL - start) == 0 && end == 0)
614 *exhausted = 1;
615 goto out;
616 }
589 return (val);
617 }
618 MPASS((VM_RADIX_MAXVAL - start) != 0);
590 }
591 MPASS((VM_RADIX_MAXVAL - start) != 0);
619 if (end != 0 && start >= end)
620 break;
621 }
592 }
622out:
623 *next = start;
624 return (outidx);
593 return (NULL);
625}
626
627/*
628 * Look up any entry at a position less than or equal to index.
629 */
630void *
631vm_radix_lookup_le(struct vm_radix *rtree, vm_pindex_t index)
632{

--- 161 unchanged lines hidden ---
594}
595
596/*
597 * Look up any entry at a position less than or equal to index.
598 */
599void *
600vm_radix_lookup_le(struct vm_radix *rtree, vm_pindex_t index)
601{

--- 161 unchanged lines hidden ---