From: "Matthew Wilcox (Oracle)" <willy@xxxxxxxxxxxxx> Since vfree() can sleep, calling kvfree() from contexts where sleeping is not permitted (eg holding a spinlock) is a bit of a lottery whether it'll work. Introduce kvfree_safe() for situations where we know we can sleep, but make kvfree() safe by default. Reported-by: Jeff Layton <jlayton@xxxxxxxxxx> Cc: Alexander Viro <viro@xxxxxxxxxxxxxxxxxx> Cc: Luis Henriques <lhenriques@xxxxxxxx> Cc: Christoph Hellwig <hch@xxxxxx> Cc: Carlos Maiolino <cmaiolino@xxxxxxxxxx> Signed-off-by: Matthew Wilcox (Oracle) <willy@xxxxxxxxxxxxx> --- mm/util.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/mm/util.c b/mm/util.c index bab284d69c8c..992f0332dced 100644 --- a/mm/util.c +++ b/mm/util.c @@ -470,6 +470,28 @@ void *kvmalloc_node(size_t size, gfp_t flags, int node) } EXPORT_SYMBOL(kvmalloc_node); +/** + * kvfree_fast() - Free memory. + * @addr: Pointer to allocated memory. + * + * kvfree_fast frees memory allocated by any of vmalloc(), kmalloc() or + * kvmalloc(). It is slightly more efficient to use kfree() or vfree() if + * you are certain that you know which one to use. + * + * Context: Either preemptible task context or not-NMI interrupt. Must not + * hold a spinlock as it can sleep. + */ +void kvfree_fast(const void *addr) +{ + might_sleep(); + + if (is_vmalloc_addr(addr)) + vfree(addr); + else + kfree(addr); +} +EXPORT_SYMBOL(kvfree_fast); + /** * kvfree() - Free memory. * @addr: Pointer to allocated memory. @@ -478,12 +500,12 @@ EXPORT_SYMBOL(kvmalloc_node); * It is slightly more efficient to use kfree() or vfree() if you are certain * that you know which one to use. * - * Context: Either preemptible task context or not-NMI interrupt. + * Context: Any context except NMI. */ void kvfree(const void *addr) { if (is_vmalloc_addr(addr)) - vfree(addr); + vfree_atomic(addr); else kfree(addr); } -- 2.20.1