[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
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 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |