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

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



On Tue, Jan 28, 2014 at 12:52:18PM +0000, Jan Beulich wrote:
> Many of these operations can be arbitrarily long, which can become a
> problem irrespective of them being exposed to privileged users only.

You probably also want to sprinkle that in the balloon driver as well.

Any thoughts of upstreaming this as well?

Thanks.
> 
> 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;
> 
> 
> 

> 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;

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


_______________________________________________
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®.