projects
/
deliverable
/
linux.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
mm, hotplug: fix error handling in mem_online_node()
[deliverable/linux.git]
/
mm
/
nommu.c
diff --git
a/mm/nommu.c
b/mm/nommu.c
index c4c542c736a962774f0770eef0d50c419b19a2cb..1fd0c51b10a63db69181fc6ba2f42127aaad6ef7 100644
(file)
--- a/
mm/nommu.c
+++ b/
mm/nommu.c
@@
-680,9
+680,9
@@
static void protect_vma(struct vm_area_struct *vma, unsigned long flags)
*/
static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
{
*/
static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
{
- struct vm_area_struct *pvma, *
*pp, *next
;
+ struct vm_area_struct *pvma, *
prev
;
struct address_space *mapping;
struct address_space *mapping;
- struct rb_node **p, *parent;
+ struct rb_node **p, *parent
, *rb_prev
;
kenter(",%p", vma);
kenter(",%p", vma);
@@
-703,7
+703,7
@@
static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
}
/* add the VMA to the tree */
}
/* add the VMA to the tree */
- parent = NULL;
+ parent =
rb_prev =
NULL;
p = &mm->mm_rb.rb_node;
while (*p) {
parent = *p;
p = &mm->mm_rb.rb_node;
while (*p) {
parent = *p;
@@
-713,17
+713,20
@@
static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
* (the latter is necessary as we may get identical VMAs) */
if (vma->vm_start < pvma->vm_start)
p = &(*p)->rb_left;
* (the latter is necessary as we may get identical VMAs) */
if (vma->vm_start < pvma->vm_start)
p = &(*p)->rb_left;
- else if (vma->vm_start > pvma->vm_start)
+ else if (vma->vm_start > pvma->vm_start) {
+ rb_prev = parent;
p = &(*p)->rb_right;
p = &(*p)->rb_right;
- else if (vma->vm_end < pvma->vm_end)
+
}
else if (vma->vm_end < pvma->vm_end)
p = &(*p)->rb_left;
p = &(*p)->rb_left;
- else if (vma->vm_end > pvma->vm_end)
+ else if (vma->vm_end > pvma->vm_end) {
+ rb_prev = parent;
p = &(*p)->rb_right;
p = &(*p)->rb_right;
- else if (vma < pvma)
+
}
else if (vma < pvma)
p = &(*p)->rb_left;
p = &(*p)->rb_left;
- else if (vma > pvma)
+ else if (vma > pvma) {
+ rb_prev = parent;
p = &(*p)->rb_right;
p = &(*p)->rb_right;
- else
+
}
else
BUG();
}
BUG();
}
@@
-731,20
+734,11
@@
static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
rb_insert_color(&vma->vm_rb, &mm->mm_rb);
/* add VMA to the VMA list also */
rb_insert_color(&vma->vm_rb, &mm->mm_rb);
/* add VMA to the VMA list also */
- for (pp = &mm->mmap; (pvma = *pp); pp = &(*pp)->vm_next) {
- if (pvma->vm_start > vma->vm_start)
- break;
- if (pvma->vm_start < vma->vm_start)
- continue;
- if (pvma->vm_end < vma->vm_end)
- break;
- }
+ prev = NULL;
+ if (rb_prev)
+ prev = rb_entry(rb_prev, struct vm_area_struct, vm_rb);
- next = *pp;
- *pp = vma;
- vma->vm_next = next;
- if (next)
- next->vm_prev = vma;
+ __vma_link_list(mm, vma, prev, parent);
}
/*
}
/*
@@
-752,7
+746,6
@@
static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
*/
static void delete_vma_from_mm(struct vm_area_struct *vma)
{
*/
static void delete_vma_from_mm(struct vm_area_struct *vma)
{
- struct vm_area_struct **pp;
struct address_space *mapping;
struct mm_struct *mm = vma->vm_mm;
struct address_space *mapping;
struct mm_struct *mm = vma->vm_mm;
@@
-775,12
+768,14
@@
static void delete_vma_from_mm(struct vm_area_struct *vma)
/* remove from the MM's tree and list */
rb_erase(&vma->vm_rb, &mm->mm_rb);
/* remove from the MM's tree and list */
rb_erase(&vma->vm_rb, &mm->mm_rb);
- for (pp = &mm->mmap; *pp; pp = &(*pp)->vm_next) {
- if (*pp == vma) {
- *pp = vma->vm_next;
- break;
- }
- }
+
+ if (vma->vm_prev)
+ vma->vm_prev->vm_next = vma->vm_next;
+ else
+ mm->mmap = vma->vm_next;
+
+ if (vma->vm_next)
+ vma->vm_next->vm_prev = vma->vm_prev;
vma->vm_mm = NULL;
}
vma->vm_mm = NULL;
}
@@
-809,17
+804,15
@@
static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
{
struct vm_area_struct *vma;
struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
{
struct vm_area_struct *vma;
- struct rb_node *n = mm->mm_rb.rb_node;
/* check the cache first */
vma = mm->mmap_cache;
if (vma && vma->vm_start <= addr && vma->vm_end > addr)
return vma;
/* check the cache first */
vma = mm->mmap_cache;
if (vma && vma->vm_start <= addr && vma->vm_end > addr)
return vma;
- /* trawl the
tree
(there may be multiple mappings in which addr
+ /* trawl the
list
(there may be multiple mappings in which addr
* resides) */
* resides) */
- for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) {
- vma = rb_entry(n, struct vm_area_struct, vm_rb);
+ for (vma = mm->mmap; vma; vma = vma->vm_next) {
if (vma->vm_start > addr)
return NULL;
if (vma->vm_end > addr) {
if (vma->vm_start > addr)
return NULL;
if (vma->vm_end > addr) {
@@
-859,7
+852,6
@@
static struct vm_area_struct *find_vma_exact(struct mm_struct *mm,
unsigned long len)
{
struct vm_area_struct *vma;
unsigned long len)
{
struct vm_area_struct *vma;
- struct rb_node *n = mm->mm_rb.rb_node;
unsigned long end = addr + len;
/* check the cache first */
unsigned long end = addr + len;
/* check the cache first */
@@
-867,10
+859,9
@@
static struct vm_area_struct *find_vma_exact(struct mm_struct *mm,
if (vma && vma->vm_start == addr && vma->vm_end == end)
return vma;
if (vma && vma->vm_start == addr && vma->vm_end == end)
return vma;
- /* trawl the
tree
(there may be multiple mappings in which addr
+ /* trawl the
list
(there may be multiple mappings in which addr
* resides) */
* resides) */
- for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) {
- vma = rb_entry(n, struct vm_area_struct, vm_rb);
+ for (vma = mm->mmap; vma; vma = vma->vm_next) {
if (vma->vm_start < addr)
continue;
if (vma->vm_start > addr)
if (vma->vm_start < addr)
continue;
if (vma->vm_start > addr)
@@
-1133,7
+1124,7
@@
static int do_mmap_private(struct vm_area_struct *vma,
unsigned long capabilities)
{
struct page *pages;
unsigned long capabilities)
{
struct page *pages;
- unsigned long total, point, n
, rlen
;
+ unsigned long total, point, n;
void *base;
int ret, order;
void *base;
int ret, order;
@@
-1157,13
+1148,12
@@
static int do_mmap_private(struct vm_area_struct *vma,
* make a private copy of the data and map that instead */
}
* make a private copy of the data and map that instead */
}
- rlen = PAGE_ALIGN(len);
/* allocate some memory to hold the mapping
* - note that this may not return a page-aligned address if the object
* we're allocating is smaller than a page
*/
/* allocate some memory to hold the mapping
* - note that this may not return a page-aligned address if the object
* we're allocating is smaller than a page
*/
- order = get_order(
r
len);
+ order = get_order(len);
kdebug("alloc order %d for %lx", order, len);
pages = alloc_pages(GFP_KERNEL, order);
kdebug("alloc order %d for %lx", order, len);
pages = alloc_pages(GFP_KERNEL, order);
@@
-1173,7
+1163,7
@@
static int do_mmap_private(struct vm_area_struct *vma,
total = 1 << order;
atomic_long_add(total, &mmap_pages_allocated);
total = 1 << order;
atomic_long_add(total, &mmap_pages_allocated);
- point =
r
len >> PAGE_SHIFT;
+ point = len >> PAGE_SHIFT;
/* we allocated a power-of-2 sized page set, so we may want to trim off
* the excess */
/* we allocated a power-of-2 sized page set, so we may want to trim off
* the excess */
@@
-1195,7
+1185,7
@@
static int do_mmap_private(struct vm_area_struct *vma,
base = page_address(pages);
region->vm_flags = vma->vm_flags |= VM_MAPPED_COPY;
region->vm_start = (unsigned long) base;
base = page_address(pages);
region->vm_flags = vma->vm_flags |= VM_MAPPED_COPY;
region->vm_start = (unsigned long) base;
- region->vm_end = region->vm_start +
r
len;
+ region->vm_end = region->vm_start + len;
region->vm_top = region->vm_start + (total << PAGE_SHIFT);
vma->vm_start = region->vm_start;
region->vm_top = region->vm_start + (total << PAGE_SHIFT);
vma->vm_start = region->vm_start;
@@
-1211,22
+1201,22
@@
static int do_mmap_private(struct vm_area_struct *vma,
old_fs = get_fs();
set_fs(KERNEL_DS);
old_fs = get_fs();
set_fs(KERNEL_DS);
- ret = vma->vm_file->f_op->read(vma->vm_file, base,
r
len, &fpos);
+ ret = vma->vm_file->f_op->read(vma->vm_file, base, len, &fpos);
set_fs(old_fs);
if (ret < 0)
goto error_free;
/* clear the last little bit */
set_fs(old_fs);
if (ret < 0)
goto error_free;
/* clear the last little bit */
- if (ret <
r
len)
- memset(base + ret, 0,
r
len - ret);
+ if (ret < len)
+ memset(base + ret, 0, len - ret);
}
return 0;
error_free:
}
return 0;
error_free:
- free_page_series(region->vm_start, region->vm_
end
);
+ free_page_series(region->vm_start, region->vm_
top
);
region->vm_start = vma->vm_start = 0;
region->vm_end = vma->vm_end = 0;
region->vm_top = 0;
region->vm_start = vma->vm_start = 0;
region->vm_end = vma->vm_end = 0;
region->vm_top = 0;
@@
-1235,7
+1225,7
@@
error_free:
enomem:
printk("Allocation of length %lu from process %d (%s) failed\n",
len, current->pid, current->comm);
enomem:
printk("Allocation of length %lu from process %d (%s) failed\n",
len, current->pid, current->comm);
- show_free_areas();
+ show_free_areas(
0
);
return -ENOMEM;
}
return -ENOMEM;
}
@@
-1268,6
+1258,7
@@
unsigned long do_mmap_pgoff(struct file *file,
/* we ignore the address hint */
addr = 0;
/* we ignore the address hint */
addr = 0;
+ len = PAGE_ALIGN(len);
/* we've determined that we can make the mapping, now translate what we
* now know into VMA flags */
/* we've determined that we can make the mapping, now translate what we
* now know into VMA flags */
@@
-1385,15
+1376,15
@@
unsigned long do_mmap_pgoff(struct file *file,
if (capabilities & BDI_CAP_MAP_DIRECT) {
addr = file->f_op->get_unmapped_area(file, addr, len,
pgoff, flags);
if (capabilities & BDI_CAP_MAP_DIRECT) {
addr = file->f_op->get_unmapped_area(file, addr, len,
pgoff, flags);
- if (IS_ERR
((void *)
addr)) {
+ if (IS_ERR
_VALUE(
addr)) {
ret = addr;
ret = addr;
- if (ret !=
(unsigned long)
-ENOSYS)
+ if (ret != -ENOSYS)
goto error_just_free;
/* the driver refused to tell us where to site
* the mapping so we'll have to attempt to copy
* it */
goto error_just_free;
/* the driver refused to tell us where to site
* the mapping so we'll have to attempt to copy
* it */
- ret =
(unsigned long)
-ENODEV;
+ ret = -ENODEV;
if (!(capabilities & BDI_CAP_MAP_COPY))
goto error_just_free;
if (!(capabilities & BDI_CAP_MAP_COPY))
goto error_just_free;
@@
-1468,14
+1459,14
@@
error_getting_vma:
printk(KERN_WARNING "Allocation of vma for %lu byte allocation"
" from process %d failed\n",
len, current->pid);
printk(KERN_WARNING "Allocation of vma for %lu byte allocation"
" from process %d failed\n",
len, current->pid);
- show_free_areas();
+ show_free_areas(
0
);
return -ENOMEM;
error_getting_region:
printk(KERN_WARNING "Allocation of vm region for %lu byte allocation"
" from process %d failed\n",
len, current->pid);
return -ENOMEM;
error_getting_region:
printk(KERN_WARNING "Allocation of vm region for %lu byte allocation"
" from process %d failed\n",
len, current->pid);
- show_free_areas();
+ show_free_areas(
0
);
return -ENOMEM;
}
EXPORT_SYMBOL(do_mmap_pgoff);
return -ENOMEM;
}
EXPORT_SYMBOL(do_mmap_pgoff);
@@
-1644,15
+1635,17
@@
static int shrink_vma(struct mm_struct *mm,
int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
{
struct vm_area_struct *vma;
int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
{
struct vm_area_struct *vma;
- struct rb_node *rb;
- unsigned long end = start + len;
+ unsigned long end;
int ret;
kenter(",%lx,%zx", start, len);
int ret;
kenter(",%lx,%zx", start, len);
+ len = PAGE_ALIGN(len);
if (len == 0)
return -EINVAL;
if (len == 0)
return -EINVAL;
+ end = start + len;
+
/* find the first potentially overlapping VMA */
vma = find_vma(mm, start);
if (!vma) {
/* find the first potentially overlapping VMA */
vma = find_vma(mm, start);
if (!vma) {
@@
-1677,9
+1670,8
@@
int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
}
if (end == vma->vm_end)
goto erase_whole_vma;
}
if (end == vma->vm_end)
goto erase_whole_vma;
- rb = rb_next(&vma->vm_rb);
- vma = rb_entry(rb, struct vm_area_struct, vm_rb);
- } while (rb);
+ vma = vma->vm_next;
+ } while (vma);
kleave(" = -EINVAL [split file]");
return -EINVAL;
} else {
kleave(" = -EINVAL [split file]");
return -EINVAL;
} else {
@@
-1773,6
+1765,8
@@
unsigned long do_mremap(unsigned long addr,
struct vm_area_struct *vma;
/* insanity checks first */
struct vm_area_struct *vma;
/* insanity checks first */
+ old_len = PAGE_ALIGN(old_len);
+ new_len = PAGE_ALIGN(new_len);
if (old_len == 0 || new_len == 0)
return (unsigned long) -EINVAL;
if (old_len == 0 || new_len == 0)
return (unsigned long) -EINVAL;
This page took
0.07584 seconds
and
5
git commands to generate.