vfree: don't schedule free_work() if llist_add() returns false
vfree() only needs schedule_work(&p->wq) if p->list was empty, otherwise vfree_deferred->wq is already pending or it is running and didn't do llist_del_all() yet. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Родитель
345606d429
Коммит
59d3132f8a
|
@ -1477,7 +1477,6 @@ static void __vunmap(const void *addr, int deallocate_pages)
|
||||||
* conventions for vfree() arch-depenedent would be a really bad idea)
|
* conventions for vfree() arch-depenedent would be a really bad idea)
|
||||||
*
|
*
|
||||||
* NOTE: assumes that the object at *addr has a size >= sizeof(llist_node)
|
* NOTE: assumes that the object at *addr has a size >= sizeof(llist_node)
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
void vfree(const void *addr)
|
void vfree(const void *addr)
|
||||||
{
|
{
|
||||||
|
@ -1489,8 +1488,8 @@ void vfree(const void *addr)
|
||||||
return;
|
return;
|
||||||
if (unlikely(in_interrupt())) {
|
if (unlikely(in_interrupt())) {
|
||||||
struct vfree_deferred *p = &__get_cpu_var(vfree_deferred);
|
struct vfree_deferred *p = &__get_cpu_var(vfree_deferred);
|
||||||
llist_add((struct llist_node *)addr, &p->list);
|
if (llist_add((struct llist_node *)addr, &p->list))
|
||||||
schedule_work(&p->wq);
|
schedule_work(&p->wq);
|
||||||
} else
|
} else
|
||||||
__vunmap(addr, 1);
|
__vunmap(addr, 1);
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче