augmented rbtree: add new RB_DECLARE_CALLBACKS_MAX macro
Add RB_DECLARE_CALLBACKS_MAX, which generates augmented rbtree callbacks for the case where the augmented value is a scalar whose definition follows a max(f(node)) pattern. This actually covers all present uses of RB_DECLARE_CALLBACKS, and saves some (source) code duplication in the various RBCOMPUTE function definitions. [walken@google.com: fix mm/vmalloc.c] Link: http://lkml.kernel.org/r/CANN689FXgK13wDYNh1zKxdipeTuALG4eKvKpsdZqKFJ-rvtGiQ@mail.gmail.com [walken@google.com: re-add check to check_augmented()] Link: http://lkml.kernel.org/r/20190727022027.GA86863@google.com Link: http://lkml.kernel.org/r/20190703040156.56953-3-walken@google.com Signed-off-by: Michel Lespinasse <walken@google.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: David Howells <dhowells@redhat.com> Cc: Davidlohr Bueso <dbueso@suse.de> Cc: Uladzislau Rezki <urezki@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
这个提交包含在:
29
mm/mmap.c
29
mm/mmap.c
@@ -289,9 +289,9 @@ out:
|
||||
return retval;
|
||||
}
|
||||
|
||||
static long vma_compute_subtree_gap(struct vm_area_struct *vma)
|
||||
static inline unsigned long vma_compute_gap(struct vm_area_struct *vma)
|
||||
{
|
||||
unsigned long max, prev_end, subtree_gap;
|
||||
unsigned long gap, prev_end;
|
||||
|
||||
/*
|
||||
* Note: in the rare case of a VM_GROWSDOWN above a VM_GROWSUP, we
|
||||
@@ -299,14 +299,21 @@ static long vma_compute_subtree_gap(struct vm_area_struct *vma)
|
||||
* an unmapped area; whereas when expanding we only require one.
|
||||
* That's a little inconsistent, but keeps the code here simpler.
|
||||
*/
|
||||
max = vm_start_gap(vma);
|
||||
gap = vm_start_gap(vma);
|
||||
if (vma->vm_prev) {
|
||||
prev_end = vm_end_gap(vma->vm_prev);
|
||||
if (max > prev_end)
|
||||
max -= prev_end;
|
||||
if (gap > prev_end)
|
||||
gap -= prev_end;
|
||||
else
|
||||
max = 0;
|
||||
gap = 0;
|
||||
}
|
||||
return gap;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_VM_RB
|
||||
static unsigned long vma_compute_subtree_gap(struct vm_area_struct *vma)
|
||||
{
|
||||
unsigned long max = vma_compute_gap(vma), subtree_gap;
|
||||
if (vma->vm_rb.rb_left) {
|
||||
subtree_gap = rb_entry(vma->vm_rb.rb_left,
|
||||
struct vm_area_struct, vm_rb)->rb_subtree_gap;
|
||||
@@ -322,7 +329,6 @@ static long vma_compute_subtree_gap(struct vm_area_struct *vma)
|
||||
return max;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_VM_RB
|
||||
static int browse_rb(struct mm_struct *mm)
|
||||
{
|
||||
struct rb_root *root = &mm->mm_rb;
|
||||
@@ -428,8 +434,9 @@ static void validate_mm(struct mm_struct *mm)
|
||||
#define validate_mm(mm) do { } while (0)
|
||||
#endif
|
||||
|
||||
RB_DECLARE_CALLBACKS(static, vma_gap_callbacks, struct vm_area_struct, vm_rb,
|
||||
unsigned long, rb_subtree_gap, vma_compute_subtree_gap)
|
||||
RB_DECLARE_CALLBACKS_MAX(static, vma_gap_callbacks,
|
||||
struct vm_area_struct, vm_rb,
|
||||
unsigned long, rb_subtree_gap, vma_compute_gap)
|
||||
|
||||
/*
|
||||
* Update augmented rbtree rb_subtree_gap values after vma->vm_start or
|
||||
@@ -439,8 +446,8 @@ RB_DECLARE_CALLBACKS(static, vma_gap_callbacks, struct vm_area_struct, vm_rb,
|
||||
static void vma_gap_update(struct vm_area_struct *vma)
|
||||
{
|
||||
/*
|
||||
* As it turns out, RB_DECLARE_CALLBACKS() already created a callback
|
||||
* function that does exactly what we want.
|
||||
* As it turns out, RB_DECLARE_CALLBACKS_MAX() already created
|
||||
* a callback function that does exactly what we want.
|
||||
*/
|
||||
vma_gap_callbacks_propagate(&vma->vm_rb, NULL);
|
||||
}
|
||||
|
@@ -396,9 +396,8 @@ compute_subtree_max_size(struct vmap_area *va)
|
||||
get_subtree_max_size(va->rb_node.rb_right));
|
||||
}
|
||||
|
||||
RB_DECLARE_CALLBACKS(static, free_vmap_area_rb_augment_cb,
|
||||
struct vmap_area, rb_node, unsigned long, subtree_max_size,
|
||||
compute_subtree_max_size)
|
||||
RB_DECLARE_CALLBACKS_MAX(static, free_vmap_area_rb_augment_cb,
|
||||
struct vmap_area, rb_node, unsigned long, subtree_max_size, va_size)
|
||||
|
||||
static void purge_vmap_area_lazy(void);
|
||||
static BLOCKING_NOTIFIER_HEAD(vmap_notify_list);
|
||||
|
在新工单中引用
屏蔽一个用户