[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] linux-2.6.18/privcmd: sprinkle around cond_resched() calls in mmap ioctl handling


  • To: "xen-devel" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: "Jan Beulich" <JBeulich@xxxxxxxx>
  • Date: Tue, 28 Jan 2014 12:52:18 +0000
  • Delivery-date: Tue, 28 Jan 2014 12:52:21 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xen.org>

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>

--- sle11sp3.orig/drivers/xen/privcmd/privcmd.c 2012-12-12 12:05:51.000000000 
+0100
+++ sle11sp3/drivers/xen/privcmd/privcmd.c      2014-01-16 10:01:23.000000000 
+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;



Attachment: xen-privcmd-mmap-cond-resched.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.