aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mlock.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/mlock.c')
-rw-r--r--mm/mlock.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/mm/mlock.c b/mm/mlock.c
index 1ada366570cb..3035a56e7616 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -667,3 +667,48 @@ void user_shm_unlock(size_t size, struct user_struct *user)
667 spin_unlock(&shmlock_user_lock); 667 spin_unlock(&shmlock_user_lock);
668 free_uid(user); 668 free_uid(user);
669} 669}
670
671void *alloc_locked_buffer(size_t size)
672{
673 unsigned long rlim, vm, pgsz;
674 void *buffer = NULL;
675
676 pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT;
677
678 down_write(&current->mm->mmap_sem);
679
680 rlim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
681 vm = current->mm->total_vm + pgsz;
682 if (rlim < vm)
683 goto out;
684
685 rlim = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
686 vm = current->mm->locked_vm + pgsz;
687 if (rlim < vm)
688 goto out;
689
690 buffer = kzalloc(size, GFP_KERNEL);
691 if (!buffer)
692 goto out;
693
694 current->mm->total_vm += pgsz;
695 current->mm->locked_vm += pgsz;
696
697 out:
698 up_write(&current->mm->mmap_sem);
699 return buffer;
700}
701
702void free_locked_buffer(void *buffer, size_t size)
703{
704 unsigned long pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT;
705
706 down_write(&current->mm->mmap_sem);
707
708 current->mm->total_vm -= pgsz;
709 current->mm->locked_vm -= pgsz;
710
711 up_write(&current->mm->mmap_sem);
712
713 kfree(buffer);
714}