|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [linux-2.6.18-xen] privcmd: sprinkle around cond_resched() calls in mmap ioctl handling
# HG changeset patch
# User Jan Beulich <jbeulich@xxxxxxxx>
# Date 1390913431 -3600
# Node ID a2107a5b5b79e2bd5097166d542780be7936343e
# Parent f2e452d986249c934ed1ab0c73d3c73b6cbc2b26
privcmd: sprinkle around cond_resched() calls in mmap ioctl handling
Many of these operations can be arbitrarily long, which can become a
problem irrespective of them being exposed to privileged users only.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
diff -r f2e452d98624 -r a2107a5b5b79 drivers/xen/privcmd/privcmd.c
--- a/drivers/xen/privcmd/privcmd.c Tue Jan 28 13:38:34 2014 +0100
+++ b/drivers/xen/privcmd/privcmd.c Tue Jan 28 13:50:31 2014 +0100
@@ -126,6 +126,9 @@ static long privcmd_ioctl(struct file *f
p = mmapcmd.entry;
for (i = 0; i < mmapcmd.num;) {
+ if (i)
+ cond_resched();
+
nr = min(mmapcmd.num - i, MMAP_NR_PER_PAGE);
ret = -ENOMEM;
@@ -158,6 +161,9 @@ static long privcmd_ioctl(struct file *f
i = 0;
list_for_each(l, &pagelist) {
+ if (i)
+ cond_resched();
+
nr = i + min(mmapcmd.num - i, MMAP_NR_PER_PAGE);
msg = (privcmd_mmap_entry_t*)(l + 1);
@@ -186,6 +192,9 @@ static long privcmd_ioctl(struct file *f
addr = vma->vm_start;
i = 0;
list_for_each(l, &pagelist) {
+ if (i)
+ cond_resched();
+
nr = i + min(mmapcmd.num - i, MMAP_NR_PER_PAGE);
msg = (privcmd_mmap_entry_t*)(l + 1);
@@ -209,8 +218,12 @@ static long privcmd_ioctl(struct file *f
mmap_out:
up_write(&mm->mmap_sem);
- list_for_each_safe(l,l2,&pagelist)
+ i = 0;
+ list_for_each_safe(l, l2, &pagelist) {
+ if (!(++i & 7))
+ cond_resched();
free_page((unsigned long)l);
+ }
}
#undef MMAP_NR_PER_PAGE
break;
@@ -236,6 +249,9 @@ static long privcmd_ioctl(struct file *f
p = m.arr;
for (i=0; i<nr_pages; ) {
+ if (i)
+ cond_resched();
+
nr = min(nr_pages - i, MMAPBATCH_NR_PER_PAGE);
ret = -ENOMEM;
@@ -270,6 +286,9 @@ static long privcmd_ioctl(struct file *f
ret = 0;
paged_out = 0;
list_for_each(l, &pagelist) {
+ if (i)
+ cond_resched();
+
nr = i + min(nr_pages - i, MMAPBATCH_NR_PER_PAGE);
mfn = (unsigned long *)(l + 1);
@@ -302,6 +321,9 @@ static long privcmd_ioctl(struct file *f
else
ret = 0;
list_for_each(l, &pagelist) {
+ if (i)
+ cond_resched();
+
nr = min(nr_pages - i, MMAPBATCH_NR_PER_PAGE);
mfn = (unsigned long *)(l + 1);
if (copy_to_user(p, mfn, nr*sizeof(*mfn)))
@@ -310,8 +332,12 @@ static long privcmd_ioctl(struct file *f
}
}
mmapbatch_out:
- list_for_each_safe(l,l2,&pagelist)
+ i = 0;
+ list_for_each_safe(l, l2, &pagelist) {
+ if (!(++i & 7))
+ cond_resched();
free_page((unsigned long)l);
+ }
}
break;
@@ -335,6 +361,9 @@ static long privcmd_ioctl(struct file *f
p = m.arr;
for (i = 0; i < nr_pages; i += nr, p += nr) {
+ if (i)
+ cond_resched();
+
nr = min(nr_pages - i, MMAPBATCH_NR_PER_PAGE);
ret = -ENOMEM;
@@ -367,6 +396,9 @@ static long privcmd_ioctl(struct file *f
ret = 0;
paged_out = 0;
list_for_each(l, &pagelist) {
+ if (i)
+ cond_resched();
+
nr = i + min(nr_pages - i, MMAPBATCH_NR_PER_PAGE);
mfn = (void *)(l + 1);
err = (void *)(l + 1);
@@ -397,6 +429,9 @@ static long privcmd_ioctl(struct file *f
ret = paged_out ? -ENOENT : 0;
i = 0;
list_for_each(l, &pagelist) {
+ if (i)
+ cond_resched();
+
nr = min(nr_pages - i, MMAPBATCH_NR_PER_PAGE);
err = (void *)(l + 1);
if (copy_to_user(p, err, nr * sizeof(*err)))
@@ -407,8 +442,12 @@ static long privcmd_ioctl(struct file *f
ret = -EFAULT;
mmapbatch_v2_out:
- list_for_each_safe(l, l2, &pagelist)
+ i = 0;
+ list_for_each_safe(l, l2, &pagelist) {
+ if (!(++i & 7))
+ cond_resched();
free_page((unsigned long)l);
+ }
#undef MMAPBATCH_NR_PER_PAGE
}
break;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |