diff options
Diffstat (limited to 'mm/mlock.c')
-rw-r--r-- | mm/mlock.c | 51 |
1 files changed, 21 insertions, 30 deletions
diff --git a/mm/mlock.c b/mm/mlock.c index cbe9e0581b75..ac130433c7d3 100644 --- a/mm/mlock.c +++ b/mm/mlock.c | |||
@@ -629,52 +629,43 @@ void user_shm_unlock(size_t size, struct user_struct *user) | |||
629 | free_uid(user); | 629 | free_uid(user); |
630 | } | 630 | } |
631 | 631 | ||
632 | void *alloc_locked_buffer(size_t size) | 632 | int account_locked_memory(struct mm_struct *mm, struct rlimit *rlim, |
633 | size_t size) | ||
633 | { | 634 | { |
634 | unsigned long rlim, vm, pgsz; | 635 | unsigned long lim, vm, pgsz; |
635 | void *buffer = NULL; | 636 | int error = -ENOMEM; |
636 | 637 | ||
637 | pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT; | 638 | pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT; |
638 | 639 | ||
639 | down_write(¤t->mm->mmap_sem); | 640 | down_write(&mm->mmap_sem); |
640 | |||
641 | rlim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT; | ||
642 | vm = current->mm->total_vm + pgsz; | ||
643 | if (rlim < vm) | ||
644 | goto out; | ||
645 | 641 | ||
646 | rlim = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT; | 642 | lim = rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT; |
647 | vm = current->mm->locked_vm + pgsz; | 643 | vm = mm->total_vm + pgsz; |
648 | if (rlim < vm) | 644 | if (lim < vm) |
649 | goto out; | 645 | goto out; |
650 | 646 | ||
651 | buffer = kzalloc(size, GFP_KERNEL); | 647 | lim = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT; |
652 | if (!buffer) | 648 | vm = mm->locked_vm + pgsz; |
649 | if (lim < vm) | ||
653 | goto out; | 650 | goto out; |
654 | 651 | ||
655 | current->mm->total_vm += pgsz; | 652 | mm->total_vm += pgsz; |
656 | current->mm->locked_vm += pgsz; | 653 | mm->locked_vm += pgsz; |
657 | 654 | ||
655 | error = 0; | ||
658 | out: | 656 | out: |
659 | up_write(¤t->mm->mmap_sem); | 657 | up_write(&mm->mmap_sem); |
660 | return buffer; | 658 | return error; |
661 | } | 659 | } |
662 | 660 | ||
663 | void release_locked_buffer(void *buffer, size_t size) | 661 | void refund_locked_memory(struct mm_struct *mm, size_t size) |
664 | { | 662 | { |
665 | unsigned long pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT; | 663 | unsigned long pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT; |
666 | 664 | ||
667 | down_write(¤t->mm->mmap_sem); | 665 | down_write(&mm->mmap_sem); |
668 | |||
669 | current->mm->total_vm -= pgsz; | ||
670 | current->mm->locked_vm -= pgsz; | ||
671 | |||
672 | up_write(¤t->mm->mmap_sem); | ||
673 | } | ||
674 | 666 | ||
675 | void free_locked_buffer(void *buffer, size_t size) | 667 | mm->total_vm -= pgsz; |
676 | { | 668 | mm->locked_vm -= pgsz; |
677 | release_locked_buffer(buffer, size); | ||
678 | 669 | ||
679 | kfree(buffer); | 670 | up_write(&mm->mmap_sem); |
680 | } | 671 | } |