The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/mm/interval_tree.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * mm/interval_tree.c - interval tree for mapping->i_mmap
    3  *
    4  * Copyright (C) 2012, Michel Lespinasse <walken@google.com>
    5  *
    6  * This file is released under the GPL v2.
    7  */
    8 
    9 #include <linux/mm.h>
   10 #include <linux/fs.h>
   11 #include <linux/rmap.h>
   12 #include <linux/interval_tree_generic.h>
   13 
   14 static inline unsigned long vma_start_pgoff(struct vm_area_struct *v)
   15 {
   16         return v->vm_pgoff;
   17 }
   18 
   19 static inline unsigned long vma_last_pgoff(struct vm_area_struct *v)
   20 {
   21         return v->vm_pgoff + ((v->vm_end - v->vm_start) >> PAGE_SHIFT) - 1;
   22 }
   23 
   24 INTERVAL_TREE_DEFINE(struct vm_area_struct, shared.linear.rb,
   25                      unsigned long, shared.linear.rb_subtree_last,
   26                      vma_start_pgoff, vma_last_pgoff,, vma_interval_tree)
   27 
   28 /* Insert node immediately after prev in the interval tree */
   29 void vma_interval_tree_insert_after(struct vm_area_struct *node,
   30                                     struct vm_area_struct *prev,
   31                                     struct rb_root *root)
   32 {
   33         struct rb_node **link;
   34         struct vm_area_struct *parent;
   35         unsigned long last = vma_last_pgoff(node);
   36 
   37         VM_BUG_ON(vma_start_pgoff(node) != vma_start_pgoff(prev));
   38 
   39         if (!prev->shared.linear.rb.rb_right) {
   40                 parent = prev;
   41                 link = &prev->shared.linear.rb.rb_right;
   42         } else {
   43                 parent = rb_entry(prev->shared.linear.rb.rb_right,
   44                                   struct vm_area_struct, shared.linear.rb);
   45                 if (parent->shared.linear.rb_subtree_last < last)
   46                         parent->shared.linear.rb_subtree_last = last;
   47                 while (parent->shared.linear.rb.rb_left) {
   48                         parent = rb_entry(parent->shared.linear.rb.rb_left,
   49                                 struct vm_area_struct, shared.linear.rb);
   50                         if (parent->shared.linear.rb_subtree_last < last)
   51                                 parent->shared.linear.rb_subtree_last = last;
   52                 }
   53                 link = &parent->shared.linear.rb.rb_left;
   54         }
   55 
   56         node->shared.linear.rb_subtree_last = last;
   57         rb_link_node(&node->shared.linear.rb, &parent->shared.linear.rb, link);
   58         rb_insert_augmented(&node->shared.linear.rb, root,
   59                             &vma_interval_tree_augment);
   60 }
   61 
   62 static inline unsigned long avc_start_pgoff(struct anon_vma_chain *avc)
   63 {
   64         return vma_start_pgoff(avc->vma);
   65 }
   66 
   67 static inline unsigned long avc_last_pgoff(struct anon_vma_chain *avc)
   68 {
   69         return vma_last_pgoff(avc->vma);
   70 }
   71 
   72 INTERVAL_TREE_DEFINE(struct anon_vma_chain, rb, unsigned long, rb_subtree_last,
   73                      avc_start_pgoff, avc_last_pgoff,
   74                      static inline, __anon_vma_interval_tree)
   75 
   76 void anon_vma_interval_tree_insert(struct anon_vma_chain *node,
   77                                    struct rb_root *root)
   78 {
   79 #ifdef CONFIG_DEBUG_VM_RB
   80         node->cached_vma_start = avc_start_pgoff(node);
   81         node->cached_vma_last = avc_last_pgoff(node);
   82 #endif
   83         __anon_vma_interval_tree_insert(node, root);
   84 }
   85 
   86 void anon_vma_interval_tree_remove(struct anon_vma_chain *node,
   87                                    struct rb_root *root)
   88 {
   89         __anon_vma_interval_tree_remove(node, root);
   90 }
   91 
   92 struct anon_vma_chain *
   93 anon_vma_interval_tree_iter_first(struct rb_root *root,
   94                                   unsigned long first, unsigned long last)
   95 {
   96         return __anon_vma_interval_tree_iter_first(root, first, last);
   97 }
   98 
   99 struct anon_vma_chain *
  100 anon_vma_interval_tree_iter_next(struct anon_vma_chain *node,
  101                                  unsigned long first, unsigned long last)
  102 {
  103         return __anon_vma_interval_tree_iter_next(node, first, last);
  104 }
  105 
  106 #ifdef CONFIG_DEBUG_VM_RB
  107 void anon_vma_interval_tree_verify(struct anon_vma_chain *node)
  108 {
  109         WARN_ON_ONCE(node->cached_vma_start != avc_start_pgoff(node));
  110         WARN_ON_ONCE(node->cached_vma_last != avc_last_pgoff(node));
  111 }
  112 #endif

Cache object: 5ff5d22ab5f3e6221e4e14085d4be0b5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.