From 61751a896bbba472c0bfa671cef6c9420e30028d Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Fri, 7 Nov 2008 20:13:28 +0200 Subject: [PATCH] vma_intersect() was erroneous, replaced by a nice and simple set_intersection() routine. Still testing sys_munmap(). It now correctly spots and unmaps the overlapping vma. The issue now is that if a split occurs, we forgot to add same objects to new vma. --- include/l4/lib/math.h | 15 +++++++++++++++ tasks/mm0/include/vm_area.h | 2 -- tasks/mm0/src/mmap.c | 23 ++++++----------------- tasks/mm0/src/munmap.c | 4 +++- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/include/l4/lib/math.h b/include/l4/lib/math.h index fd12c08..d5ce96e 100644 --- a/include/l4/lib/math.h +++ b/include/l4/lib/math.h @@ -4,4 +4,19 @@ #define min(x, y) (((x) < (y)) ? x : y) #define max(x, y) (((x) > (y)) ? x : y) +/* Tests if ranges a-b intersect with range c-d */ +static inline int set_intersection(unsigned long a, unsigned long b, + unsigned long c, unsigned long d) +{ + /* + * Below is the complement (') of the intersection + * of 2 ranges, much simpler ;-) + */ + if (b <= c || a >= d) + return 0; + + /* The rest is always intersecting */ + return 1; +} + #endif /* __LIB_MATH_H__ */ diff --git a/tasks/mm0/include/vm_area.h b/tasks/mm0/include/vm_area.h index 47f6dc2..afdb753 100644 --- a/tasks/mm0/include/vm_area.h +++ b/tasks/mm0/include/vm_area.h @@ -183,8 +183,6 @@ struct vm_area { unsigned long file_offset; /* File offset in pfns */ }; -int vma_intersect(unsigned long pfn_start, unsigned long pfn_end, - struct vm_area *vma); /* * Finds the vma that has the given address. * TODO: In the future a lot of use cases may need to traverse each vma diff --git a/tasks/mm0/src/mmap.c b/tasks/mm0/src/mmap.c index 3cece38..6cdbea9 100644 --- a/tasks/mm0/src/mmap.c +++ b/tasks/mm0/src/mmap.c @@ -3,6 +3,7 @@ * * Copyright (C) 2007, 2008 Bahadir Balban */ +#include #include #include #include INC_API(errno.h) @@ -37,20 +38,6 @@ struct vm_area *vma_new(unsigned long pfn_start, unsigned long npages, return vma; } -int vma_intersect(unsigned long pfn_start, unsigned long pfn_end, - struct vm_area *vma) -{ - if ((pfn_start <= vma->pfn_start) && (pfn_end > vma->pfn_start)) { - printf("%s: VMAs overlap.\n", __FUNCTION__); - return 1; - } - if ((pfn_end >= vma->pfn_end) && (pfn_start < vma->pfn_end)) { - printf("%s: VMAs overlap.\n", __FUNCTION__); - return 1; - } - return 0; -} - /* Search an empty space in the task's mmapable address region. */ unsigned long find_unmapped_area(unsigned long npages, struct tcb *task) { @@ -72,7 +59,8 @@ unsigned long find_unmapped_area(unsigned long npages, struct tcb *task) while (pfn_end <= __pfn(task->end)) { /* If intersection, skip the vma and fast-forward to next */ - if (vma_intersect(pfn_start, pfn_end, vma)) { + if (set_intersection(pfn_start, pfn_end, + vma->pfn_start, vma->pfn_end)) { /* Update interval to next available space */ pfn_start = vma->pfn_end; @@ -204,8 +192,9 @@ void *do_mmap(struct vm_file *mapfile, unsigned long file_offset, * splitting, shrink/grow etc. */ list_for_each_entry(mapped, &task->vm_area_head->list, list) - BUG_ON(vma_intersect(map_pfn, map_pfn + npages, - mapped)); + BUG_ON(set_intersection(map_pfn, map_pfn + npages, + mapped->pfn_start, + mapped->pfn_end)); } /* For valid regions that aren't allocated by us, create the vma. */ diff --git a/tasks/mm0/src/munmap.c b/tasks/mm0/src/munmap.c index 780289d..da2dfdd 100644 --- a/tasks/mm0/src/munmap.c +++ b/tasks/mm0/src/munmap.c @@ -6,6 +6,7 @@ #include #include #include +#include #include @@ -134,7 +135,8 @@ int do_munmap(struct tcb *task, void *vaddr, unsigned long npages) list_for_each_entry_safe(vma, n, &task->vm_area_head->list, list) { /* Check for intersection */ - if (vma_intersect(munmap_start, munmap_end, vma)) { + if (set_intersection(munmap_start, munmap_end, + vma->pfn_start, vma->pfn_end)) { /* * Flush pages if vma is writable, * dirty and file-backed.