+
+int account_locked_memory(struct mm_struct *mm, struct rlimit *rlim,
+ size_t size)
+{
+ unsigned long lim, vm, pgsz;
+ int error = -ENOMEM;
+
+ pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT;
+
+ down_write(&mm->mmap_sem);
+
+ lim = rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
+ vm = mm->total_vm + pgsz;
+ if (lim < vm)
+ goto out;
+
+ lim = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
+ vm = mm->locked_vm + pgsz;
+ if (lim < vm)
+ goto out;
+
+ mm->total_vm += pgsz;
+ mm->locked_vm += pgsz;
+
+ error = 0;
+ out:
+ up_write(&mm->mmap_sem);
+ return error;
+}
+
+void refund_locked_memory(struct mm_struct *mm, size_t size)
+{
+ unsigned long pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT;
+
+ down_write(&mm->mmap_sem);
+
+ mm->total_vm -= pgsz;
+ mm->locked_vm -= pgsz;
+
+ up_write(&mm->mmap_sem);
+}