Re: [PATCH v3] mm: Allow calling vfree() from non-schedulable context.

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

 



On Wed 29-03-17 14:36:10, Andrey Ryabinin wrote:
[...]
> So I just get a better idea. How about just always deferring
> __purge_vmap_area_lazy()?

I didn't get to look closer but from the high level POV this makes a lot
of sense. __purge_vmap_area_lazy shouldn't be called all that often that
the deferred mode would matter.

> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index 68eb002..a02a250 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -701,7 +701,7 @@ static bool __purge_vmap_area_lazy(unsigned long start, unsigned long end)
>   * Kick off a purge of the outstanding lazy areas. Don't bother if somebody
>   * is already purging.
>   */
> -static void try_purge_vmap_area_lazy(void)
> +static void try_purge_vmap_area_lazy(struct work_struct *work)
>  {
>         if (mutex_trylock(&vmap_purge_lock)) {
>                 __purge_vmap_area_lazy(ULONG_MAX, 0);
> @@ -720,6 +720,8 @@ static void purge_vmap_area_lazy(void)
>         mutex_unlock(&vmap_purge_lock);
>  }
>  
> +static DECLARE_WORK(purge_vmap_work, try_purge_vmap_area_lazy);
> +
>  /*
>   * Free a vmap area, caller ensuring that the area has been unmapped
>   * and flush_cache_vunmap had been called for the correct range
> @@ -735,8 +737,9 @@ static void free_vmap_area_noflush(struct vmap_area *va)
>         /* After this point, we may free va at any time */
>         llist_add(&va->purge_list, &vmap_purge_list);
>  
> -       if (unlikely(nr_lazy > lazy_max_pages()))
> -               try_purge_vmap_area_lazy();
> +       if (unlikely(nr_lazy > lazy_max_pages())
> +           && !work_pending(&purge_vmap_work))
> +               schedule_work(&purge_vmap_work);
>  }
>  
>  /*
> @@ -1125,7 +1128,6 @@ void vm_unmap_ram(const void *mem, unsigned int count)
>         unsigned long addr = (unsigned long)mem;
>         struct vmap_area *va;
>  
> -       might_sleep();
>         BUG_ON(!addr);
>         BUG_ON(addr < VMALLOC_START);
>         BUG_ON(addr > VMALLOC_END);
> @@ -1477,8 +1479,6 @@ struct vm_struct *remove_vm_area(const void *addr)
>  {
>         struct vmap_area *va;
>  
> -       might_sleep();
> -
>         va = find_vmap_area((unsigned long)addr);
>         if (va && va->flags & VM_VM_AREA) {
>                 struct vm_struct *vm = va->vm;
> 
>  
> 
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majordomo@xxxxxxxxx.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: <a href=mailto:"dont@xxxxxxxxx";> email@xxxxxxxxx </a>

-- 
Michal Hocko
SUSE Labs

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@xxxxxxxxx.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@xxxxxxxxx";> email@xxxxxxxxx </a>



[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]
  Powered by Linux