|
|
unsigned long grow; | unsigned long grow; |
| |
/* | /* |
* vma->vm_start/vm_end cannot change under us because the caller is required |
* vma->vm_start/vm_end cannot change under us because the caller |
* to hold the mmap_sem in write mode. We need to get the spinlock only |
* is required to hold the mmap_sem in read mode. We need the |
* before relocating the vma range ourself. |
* page_table_lock lock to serialize against concurrent expand_stacks. |
*/ | */ |
address &= PAGE_MASK; | address &= PAGE_MASK; |
spin_lock(&vma->vm_mm->page_table_lock); | spin_lock(&vma->vm_mm->page_table_lock); |
|
|
|
/* already expanded while we were spinning? */ |
|
if (vma->vm_start <= address) { |
|
spin_unlock(&vma->vm_mm->page_table_lock); |
|
return 0; |
|
} |
|
|
grow = (vma->vm_start - address) >> PAGE_SHIFT; | grow = (vma->vm_start - address) >> PAGE_SHIFT; |
if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur || | if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur || |
((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur) { | ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur) { |