vm_radix.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*-
  2. * SPDX-License-Identifier: BSD-2-Clause
  3. *
  4. * Copyright (c) 2013 EMC Corp.
  5. * Copyright (c) 2011 Jeffrey Roberson <jeff@freebsd.org>
  6. * Copyright (c) 2008 Mayur Shardul <mayur.shardul@gmail.com>
  7. * All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  22. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  24. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  25. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  26. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  27. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. */
  30. #ifndef _VM_RADIX_H_
  31. #define _VM_RADIX_H_
  32. #include <vm/_vm_radix.h>
  33. #ifdef _KERNEL
  34. #include <sys/pctrie.h>
  35. #include <vm/vm_page.h>
  36. #include <vm/vm.h>
  37. void vm_radix_wait(void);
  38. void vm_radix_zinit(void);
  39. void *vm_radix_node_alloc(struct pctrie *ptree);
  40. void vm_radix_node_free(struct pctrie *ptree, void *node);
  41. extern smr_t vm_radix_smr;
  42. static __inline void
  43. vm_radix_init(struct vm_radix *rtree)
  44. {
  45. pctrie_init(&rtree->rt_trie);
  46. }
  47. static __inline bool
  48. vm_radix_is_empty(struct vm_radix *rtree)
  49. {
  50. return (pctrie_is_empty(&rtree->rt_trie));
  51. }
  52. PCTRIE_DEFINE_SMR(VM_RADIX, vm_page, pindex, vm_radix_node_alloc, vm_radix_node_free,
  53. vm_radix_smr);
  54. /*
  55. * Inserts the key-value pair into the trie.
  56. * Panics if the key already exists.
  57. */
  58. static __inline int
  59. vm_radix_insert(struct vm_radix *rtree, vm_page_t page)
  60. {
  61. return (VM_RADIX_PCTRIE_INSERT(&rtree->rt_trie, page));
  62. }
  63. /*
  64. * Insert the page into the vm_radix tree with its pindex as the key. Panic if
  65. * the pindex already exists. Return zero on success or a non-zero error on
  66. * memory allocation failure. Set the out parameter mpred to the previous page
  67. * in the tree as if found by a previous call to vm_radix_lookup_le with the
  68. * new page pindex.
  69. */
  70. static __inline int
  71. vm_radix_insert_lookup_lt(struct vm_radix *rtree, vm_page_t page,
  72. vm_page_t *mpred)
  73. {
  74. int error;
  75. error = VM_RADIX_PCTRIE_INSERT_LOOKUP_LE(&rtree->rt_trie, page, mpred);
  76. if (__predict_false(error == EEXIST))
  77. panic("vm_radix_insert_lookup_lt: page already present, %p",
  78. *mpred);
  79. return (error);
  80. }
  81. /*
  82. * Returns the value stored at the index assuming there is an external lock.
  83. *
  84. * If the index is not present, NULL is returned.
  85. */
  86. static __inline vm_page_t
  87. vm_radix_lookup(struct vm_radix *rtree, vm_pindex_t index)
  88. {
  89. return (VM_RADIX_PCTRIE_LOOKUP(&rtree->rt_trie, index));
  90. }
  91. /*
  92. * Returns the value stored at the index without requiring an external lock.
  93. *
  94. * If the index is not present, NULL is returned.
  95. */
  96. static __inline vm_page_t
  97. vm_radix_lookup_unlocked(struct vm_radix *rtree, vm_pindex_t index)
  98. {
  99. return (VM_RADIX_PCTRIE_LOOKUP_UNLOCKED(&rtree->rt_trie, index));
  100. }
  101. /*
  102. * Returns the page with the least pindex that is greater than or equal to the
  103. * specified pindex, or NULL if there are no such pages.
  104. *
  105. * Requires that access be externally synchronized by a lock.
  106. */
  107. static __inline vm_page_t
  108. vm_radix_lookup_ge(struct vm_radix *rtree, vm_pindex_t index)
  109. {
  110. return (VM_RADIX_PCTRIE_LOOKUP_GE(&rtree->rt_trie, index));
  111. }
  112. /*
  113. * Returns the page with the greatest pindex that is less than or equal to the
  114. * specified pindex, or NULL if there are no such pages.
  115. *
  116. * Requires that access be externally synchronized by a lock.
  117. */
  118. static __inline vm_page_t
  119. vm_radix_lookup_le(struct vm_radix *rtree, vm_pindex_t index)
  120. {
  121. return (VM_RADIX_PCTRIE_LOOKUP_LE(&rtree->rt_trie, index));
  122. }
  123. /*
  124. * Remove the specified index from the trie, and return the value stored at
  125. * that index. If the index is not present, return NULL.
  126. */
  127. static __inline vm_page_t
  128. vm_radix_remove(struct vm_radix *rtree, vm_pindex_t index)
  129. {
  130. return (VM_RADIX_PCTRIE_REMOVE_LOOKUP(&rtree->rt_trie, index));
  131. }
  132. /*
  133. * Remove and free all the nodes from the radix tree.
  134. */
  135. static __inline void
  136. vm_radix_reclaim_allnodes(struct vm_radix *rtree)
  137. {
  138. VM_RADIX_PCTRIE_RECLAIM(&rtree->rt_trie);
  139. }
  140. /*
  141. * Replace an existing page in the trie with another one.
  142. * Panics if there is not an old page in the trie at the new page's index.
  143. */
  144. static __inline vm_page_t
  145. vm_radix_replace(struct vm_radix *rtree, vm_page_t newpage)
  146. {
  147. return (VM_RADIX_PCTRIE_REPLACE(&rtree->rt_trie, newpage));
  148. }
  149. #endif /* _KERNEL */
  150. #endif /* !_VM_RADIX_H_ */