Merge branch 'drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
[linux-2.6.git] / mm / mlock.c
index 3446b7e..01fbe93 100644 (file)
 #include <linux/mm.h>
 #include <linux/mempolicy.h>
 #include <linux/syscalls.h>
+#include <linux/sched.h>
+#include <linux/module.h>
 
+int can_do_mlock(void)
+{
+       if (capable(CAP_IPC_LOCK))
+               return 1;
+       if (current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur != 0)
+               return 1;
+       return 0;
+}
+EXPORT_SYMBOL(can_do_mlock);
 
 static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
        unsigned long start, unsigned long end, unsigned int newflags)
@@ -67,8 +78,6 @@ success:
 
        mm->locked_vm -= pages;
 out:
-       if (ret == -ENOMEM)
-               ret = -EAGAIN;
        return ret;
 }
 
@@ -233,9 +242,12 @@ int user_shm_lock(size_t size, struct user_struct *user)
 
        locked = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
        lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+       if (lock_limit == RLIM_INFINITY)
+               allowed = 1;
        lock_limit >>= PAGE_SHIFT;
        spin_lock(&shmlock_user_lock);
-       if (locked + user->locked_shm > lock_limit && !capable(CAP_IPC_LOCK))
+       if (!allowed &&
+           locked + user->locked_shm > lock_limit && !capable(CAP_IPC_LOCK))
                goto out;
        get_uid(user);
        user->locked_shm += locked;