linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] Add free() function
@ 2018-03-22 19:58 Matthew Wilcox
  2018-03-22 19:58 ` [PATCH 1/4] decompression: Rename malloc and free Matthew Wilcox
                   ` (3 more replies)
  0 siblings, 4 replies; 17+ messages in thread
From: Matthew Wilcox @ 2018-03-22 19:58 UTC (permalink / raw)
  To: linux-mm; +Cc: Kirill Tkhai, Matthew Wilcox, linux-kernel, Paul E. McKenney

From: Matthew Wilcox <mawilcox@microsoft.com>

Today, kfree_rcu() can only free objects allocated using kmalloc().
There have been attempts to extend that to kvfree(), but I think we
should take it even further and allow freeing as many different objects
as possible.

It turns out many different kinds of memory allocations can be detected
from the address.  vmalloc() and percpu_alloc() can be detected by being
in a particular range.  kmalloc() and kmem_cache_alloc() can be detected
from the struct page.  __get_free_pages() and page_frag_alloc() are both
freeable just by decrementing the refcount on the page.

This allows us to delete many dozens of tiny rcu callbacks throughout
the kernel, much as was done when kfree_rcu was added.

Matthew Wilcox (4):
  decompression: Rename malloc and free
  Rename 'free' functions
  mm: Add free()
  rcu: Switch to using free() instead of kfree()

 crypto/lrw.c                  |  4 ++--
 crypto/xts.c                  |  4 ++--
 include/linux/decompress/mm.h | 10 ++++++----
 include/linux/kernel.h        |  2 ++
 include/linux/rcupdate.h      | 40 +++++++++++++++++++---------------------
 include/linux/rcutiny.h       |  2 +-
 include/linux/rcutree.h       |  2 +-
 include/trace/events/rcu.h    |  8 ++++----
 kernel/rcu/rcu.h              |  8 +++-----
 kernel/rcu/tree.c             | 11 +++++------
 mm/util.c                     | 39 +++++++++++++++++++++++++++++++++++++++
 11 files changed, 84 insertions(+), 46 deletions(-)

-- 
2.16.2

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 1/4] decompression: Rename malloc and free
  2018-03-22 19:58 [PATCH 0/4] Add free() function Matthew Wilcox
@ 2018-03-22 19:58 ` Matthew Wilcox
  2018-03-22 19:58 ` [PATCH 2/4] Rename 'free' functions Matthew Wilcox
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 17+ messages in thread
From: Matthew Wilcox @ 2018-03-22 19:58 UTC (permalink / raw)
  To: linux-mm; +Cc: Kirill Tkhai, Matthew Wilcox, linux-kernel, Paul E. McKenney

From: Matthew Wilcox <mawilcox@microsoft.com>

Rename the trivial malloc and free implementations to tmalloc and tfree
to avoid a namespace collision with an in-kernel free() function.

Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com>
---
 include/linux/decompress/mm.h | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/include/linux/decompress/mm.h b/include/linux/decompress/mm.h
index 868e9eacd69e..0ac62b025c1b 100644
--- a/include/linux/decompress/mm.h
+++ b/include/linux/decompress/mm.h
@@ -31,7 +31,7 @@
 STATIC_RW_DATA unsigned long malloc_ptr;
 STATIC_RW_DATA int malloc_count;
 
-static void *malloc(int size)
+static void *tmalloc(int size)
 {
 	void *p;
 
@@ -52,15 +52,17 @@ static void *malloc(int size)
 	return p;
 }
 
-static void free(void *where)
+static void tfree(void *where)
 {
 	malloc_count--;
 	if (!malloc_count)
 		malloc_ptr = free_mem_ptr;
 }
 
-#define large_malloc(a) malloc(a)
-#define large_free(a) free(a)
+#define malloc(a) tmalloc(a)
+#define free(a) tfree(a)
+#define large_malloc(a) tmalloc(a)
+#define large_free(a) tfree(a)
 
 #define INIT
 
-- 
2.16.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 2/4] Rename 'free' functions
  2018-03-22 19:58 [PATCH 0/4] Add free() function Matthew Wilcox
  2018-03-22 19:58 ` [PATCH 1/4] decompression: Rename malloc and free Matthew Wilcox
@ 2018-03-22 19:58 ` Matthew Wilcox
  2018-03-22 19:58 ` [PATCH 3/4] mm: Add free() Matthew Wilcox
  2018-03-22 19:58 ` [PATCH 4/4] rcu: Switch to using free() instead of kfree() Matthew Wilcox
  3 siblings, 0 replies; 17+ messages in thread
From: Matthew Wilcox @ 2018-03-22 19:58 UTC (permalink / raw)
  To: linux-mm; +Cc: Kirill Tkhai, Matthew Wilcox, linux-kernel, Paul E. McKenney

From: Matthew Wilcox <mawilcox@microsoft.com>

The names of these static functions collide with a kernel-wide 'free'
function.  Call them 'free_inst' instead.

Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com>
---
 crypto/lrw.c | 4 ++--
 crypto/xts.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/crypto/lrw.c b/crypto/lrw.c
index cbbd7c50ad19..2b93fc7f4e38 100644
--- a/crypto/lrw.c
+++ b/crypto/lrw.c
@@ -522,7 +522,7 @@ static void exit_tfm(struct crypto_skcipher *tfm)
 	crypto_free_skcipher(ctx->child);
 }
 
-static void free(struct skcipher_instance *inst)
+static void free_inst(struct skcipher_instance *inst)
 {
 	crypto_drop_skcipher(skcipher_instance_ctx(inst));
 	kfree(inst);
@@ -634,7 +634,7 @@ static int create(struct crypto_template *tmpl, struct rtattr **tb)
 	inst->alg.encrypt = encrypt;
 	inst->alg.decrypt = decrypt;
 
-	inst->free = free;
+	inst->free = free_inst;
 
 	err = skcipher_register_instance(tmpl, inst);
 	if (err)
diff --git a/crypto/xts.c b/crypto/xts.c
index f317c48b5e43..5a7ac3dc2fd7 100644
--- a/crypto/xts.c
+++ b/crypto/xts.c
@@ -465,7 +465,7 @@ static void exit_tfm(struct crypto_skcipher *tfm)
 	crypto_free_cipher(ctx->tweak);
 }
 
-static void free(struct skcipher_instance *inst)
+static void free_inst(struct skcipher_instance *inst)
 {
 	crypto_drop_skcipher(skcipher_instance_ctx(inst));
 	kfree(inst);
@@ -576,7 +576,7 @@ static int create(struct crypto_template *tmpl, struct rtattr **tb)
 	inst->alg.encrypt = encrypt;
 	inst->alg.decrypt = decrypt;
 
-	inst->free = free;
+	inst->free = free_inst;
 
 	err = skcipher_register_instance(tmpl, inst);
 	if (err)
-- 
2.16.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 3/4] mm: Add free()
  2018-03-22 19:58 [PATCH 0/4] Add free() function Matthew Wilcox
  2018-03-22 19:58 ` [PATCH 1/4] decompression: Rename malloc and free Matthew Wilcox
  2018-03-22 19:58 ` [PATCH 2/4] Rename 'free' functions Matthew Wilcox
@ 2018-03-22 19:58 ` Matthew Wilcox
  2018-03-23  8:04   ` Rasmus Villemoes
                     ` (2 more replies)
  2018-03-22 19:58 ` [PATCH 4/4] rcu: Switch to using free() instead of kfree() Matthew Wilcox
  3 siblings, 3 replies; 17+ messages in thread
From: Matthew Wilcox @ 2018-03-22 19:58 UTC (permalink / raw)
  To: linux-mm; +Cc: Kirill Tkhai, Matthew Wilcox, linux-kernel, Paul E. McKenney

From: Matthew Wilcox <mawilcox@microsoft.com>

free() can free many different kinds of memory.

Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com>
---
 include/linux/kernel.h |  2 ++
 mm/util.c              | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 3fd291503576..8bb578938e65 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -933,6 +933,8 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
 			 "pointer type mismatch in container_of()");	\
 	((type *)(__mptr - offsetof(type, member))); })
 
+void free(const void *);
+
 /* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */
 #ifdef CONFIG_FTRACE_MCOUNT_RECORD
 # define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD
diff --git a/mm/util.c b/mm/util.c
index dc4c7b551aaf..8aa2071059b0 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -26,6 +26,45 @@ static inline int is_kernel_rodata(unsigned long addr)
 		addr < (unsigned long)__end_rodata;
 }
 
+/**
+ * free() - Free memory
+ * @ptr: Pointer to memory
+ *
+ * This function can free almost any type of memory.  It can safely be
+ * called on:
+ * * NULL pointers.
+ * * Pointers to read-only data (will do nothing).
+ * * Pointers to memory allocated from kmalloc().
+ * * Pointers to memory allocated from kmem_cache_alloc().
+ * * Pointers to memory allocated from vmalloc().
+ * * Pointers to memory allocated from alloc_percpu().
+ * * Pointers to memory allocated from __get_free_pages().
+ * * Pointers to memory allocated from page_frag_alloc().
+ *
+ * It cannot free memory allocated by dma_pool_alloc() or dma_alloc_coherent().
+ */
+void free(const void *ptr)
+{
+	struct page *page;
+
+	if (unlikely(ZERO_OR_NULL_PTR(ptr)))
+		return;
+	if (is_kernel_rodata((unsigned long)ptr))
+		return;
+
+	page = virt_to_head_page(ptr);
+	if (likely(PageSlab(page)))
+		return kmem_cache_free(page->slab_cache, (void *)ptr);
+
+	if (is_vmalloc_addr(ptr))
+		return vfree(ptr);
+	if (is_kernel_percpu_address((unsigned long)ptr))
+		free_percpu((void __percpu *)ptr);
+	if (put_page_testzero(page))
+		__put_page(page);
+}
+EXPORT_SYMBOL(free);
+
 /**
  * kfree_const - conditionally free memory
  * @x: pointer to the memory
-- 
2.16.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 4/4] rcu: Switch to using free() instead of kfree()
  2018-03-22 19:58 [PATCH 0/4] Add free() function Matthew Wilcox
                   ` (2 preceding siblings ...)
  2018-03-22 19:58 ` [PATCH 3/4] mm: Add free() Matthew Wilcox
@ 2018-03-22 19:58 ` Matthew Wilcox
  2018-03-24  7:07   ` kbuild test robot
  2018-03-24  8:20   ` kbuild test robot
  3 siblings, 2 replies; 17+ messages in thread
From: Matthew Wilcox @ 2018-03-22 19:58 UTC (permalink / raw)
  To: linux-mm; +Cc: Kirill Tkhai, Matthew Wilcox, linux-kernel, Paul E. McKenney

From: Matthew Wilcox <mawilcox@microsoft.com>

Now we can free memory allocated with all kinds of functions that aren't
kmalloc().

Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com>
---
 include/linux/rcupdate.h   | 40 +++++++++++++++++++---------------------
 include/linux/rcutiny.h    |  2 +-
 include/linux/rcutree.h    |  2 +-
 include/trace/events/rcu.h |  8 ++++----
 kernel/rcu/rcu.h           |  8 +++-----
 kernel/rcu/tree.c          | 11 +++++------
 6 files changed, 33 insertions(+), 38 deletions(-)

diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 043d04784675..c450a3b78da8 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -832,48 +832,46 @@ static inline notrace void rcu_read_unlock_sched_notrace(void)
 
 /*
  * Does the specified offset indicate that the corresponding rcu_head
- * structure can be handled by kfree_rcu()?
+ * structure can be handled by free_rcu()?
  */
-#define __is_kfree_rcu_offset(offset) ((offset) < 4096)
+#define __is_free_rcu_offset(offset) ((offset) < 4096)
 
 /*
- * Helper macro for kfree_rcu() to prevent argument-expansion eyestrain.
+ * Helper macro for free_rcu() to prevent argument-expansion eyestrain.
  */
-#define __kfree_rcu(head, offset) \
+#define __free_rcu(head, offset) \
 	do { \
-		BUILD_BUG_ON(!__is_kfree_rcu_offset(offset)); \
-		kfree_call_rcu(head, (rcu_callback_t)(unsigned long)(offset)); \
+		BUILD_BUG_ON(!__is_free_rcu_offset(offset)); \
+		free_call_rcu(head, (rcu_callback_t)(unsigned long)(offset)); \
 	} while (0)
 
 /**
- * kfree_rcu() - kfree an object after a grace period.
- * @ptr:	pointer to kfree
+ * free_rcu() - Free an object after a grace period.
+ * @ptr:	pointer to be freed
  * @rcu_head:	the name of the struct rcu_head within the type of @ptr.
  *
- * Many rcu callbacks functions just call kfree() on the base structure.
- * These functions are trivial, but their size adds up, and furthermore
+ * Many rcu callback functions just free the base structure.  These
+ * functions are trivial, but their size adds up, and furthermore
  * when they are used in a kernel module, that module must invoke the
  * high-latency rcu_barrier() function at module-unload time.
  *
- * The kfree_rcu() function handles this issue.  Rather than encoding a
- * function address in the embedded rcu_head structure, kfree_rcu() instead
+ * The free_rcu() function handles both of these issues.  Rather than
+ * storing a function address in the rcu_head structure, free_rcu() instead
  * encodes the offset of the rcu_head structure within the base structure.
- * Because the functions are not allowed in the low-order 4096 bytes of
+ * Because functions are not allowed in the low-order 4096 bytes of
  * kernel virtual memory, offsets up to 4095 bytes can be accommodated.
  * If the offset is larger than 4095 bytes, a compile-time error will
- * be generated in __kfree_rcu().  If this error is triggered, you can
+ * be generated in __free_rcu().  If this error is triggered, you can
  * either fall back to use of call_rcu() or rearrange the structure to
- * position the rcu_head structure into the first 4096 bytes.
- *
- * Note that the allowable offset might decrease in the future, for example,
- * to allow something like kmem_cache_free_rcu().
+ * position the rcu_head structure in the first 4096 bytes.
  *
  * The BUILD_BUG_ON check must not involve any function calls, hence the
  * checks are done in macros here.
  */
-#define kfree_rcu(ptr, rcu_head)					\
-	__kfree_rcu(&((ptr)->rcu_head), offsetof(typeof(*(ptr)), rcu_head))
-
+#define free_rcu(ptr, rcu_head)					\
+	__free_rcu(&((ptr)->rcu_head), offsetof(typeof(*(ptr)), rcu_head))
+/* Legacy name */
+#define kfree_rcu(ptr, rcu_head)	free_rcu(ptr, rcu_head)
 
 /*
  * Place this after a lock-acquisition primitive to guarantee that
diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h
index ce9beec35e34..071b57c7cb90 100644
--- a/include/linux/rcutiny.h
+++ b/include/linux/rcutiny.h
@@ -84,7 +84,7 @@ static inline void synchronize_sched_expedited(void)
 	synchronize_sched();
 }
 
-static inline void kfree_call_rcu(struct rcu_head *head,
+static inline void free_call_rcu(struct rcu_head *head,
 				  rcu_callback_t func)
 {
 	call_rcu(head, func);
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h
index fd996cdf1833..d7498dda8c65 100644
--- a/include/linux/rcutree.h
+++ b/include/linux/rcutree.h
@@ -48,7 +48,7 @@ void synchronize_rcu_bh(void);
 void synchronize_sched_expedited(void);
 void synchronize_rcu_expedited(void);
 
-void kfree_call_rcu(struct rcu_head *head, rcu_callback_t func);
+void free_call_rcu(struct rcu_head *head, rcu_callback_t func);
 
 /**
  * synchronize_rcu_bh_expedited - Brute-force RCU-bh grace period
diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h
index 0b50fda80db0..d388a1dd2be7 100644
--- a/include/trace/events/rcu.h
+++ b/include/trace/events/rcu.h
@@ -502,7 +502,7 @@ TRACE_EVENT(rcu_callback,
  * the fourth argument is the number of lazy callbacks queued, and the
  * fifth argument is the total number of callbacks queued.
  */
-TRACE_EVENT(rcu_kfree_callback,
+TRACE_EVENT(rcu_free_callback,
 
 	TP_PROTO(const char *rcuname, struct rcu_head *rhp, unsigned long offset,
 		 long qlen_lazy, long qlen),
@@ -596,7 +596,7 @@ TRACE_EVENT(rcu_invoke_callback,
  * is the offset of the callback within the enclosing RCU-protected
  * data structure.
  */
-TRACE_EVENT(rcu_invoke_kfree_callback,
+TRACE_EVENT(rcu_invoke_free_callback,
 
 	TP_PROTO(const char *rcuname, struct rcu_head *rhp, unsigned long offset),
 
@@ -767,12 +767,12 @@ TRACE_EVENT(rcu_barrier,
 #define trace_rcu_fqs(rcuname, gpnum, cpu, qsevent) do { } while (0)
 #define trace_rcu_dyntick(polarity, oldnesting, newnesting, dyntick) do { } while (0)
 #define trace_rcu_callback(rcuname, rhp, qlen_lazy, qlen) do { } while (0)
-#define trace_rcu_kfree_callback(rcuname, rhp, offset, qlen_lazy, qlen) \
+#define trace_rcu_free_callback(rcuname, rhp, offset, qlen_lazy, qlen) \
 	do { } while (0)
 #define trace_rcu_batch_start(rcuname, qlen_lazy, qlen, blimit) \
 	do { } while (0)
 #define trace_rcu_invoke_callback(rcuname, rhp) do { } while (0)
-#define trace_rcu_invoke_kfree_callback(rcuname, rhp, offset) do { } while (0)
+#define trace_rcu_invoke_free_callback(rcuname, rhp, offset) do { } while (0)
 #define trace_rcu_batch_end(rcuname, callbacks_invoked, cb, nr, iit, risk) \
 	do { } while (0)
 #define trace_rcu_torture_read(rcutorturename, rhp, secs, c_old, c) \
diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h
index 6334f2c1abd0..26dc9ed054c5 100644
--- a/kernel/rcu/rcu.h
+++ b/kernel/rcu/rcu.h
@@ -151,8 +151,6 @@ static inline void debug_rcu_head_unqueue(struct rcu_head *head)
 }
 #endif	/* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
 
-void kfree(const void *);
-
 /*
  * Reclaim the specified callback, either by invoking it (non-lazy case)
  * or freeing it directly (lazy case).  Return true if lazy, false otherwise.
@@ -162,9 +160,9 @@ static inline bool __rcu_reclaim(const char *rn, struct rcu_head *head)
 	unsigned long offset = (unsigned long)head->func;
 
 	rcu_lock_acquire(&rcu_callback_map);
-	if (__is_kfree_rcu_offset(offset)) {
-		RCU_TRACE(trace_rcu_invoke_kfree_callback(rn, head, offset);)
-		kfree((void *)head - offset);
+	if (__is_free_rcu_offset(offset)) {
+		RCU_TRACE(trace_rcu_invoke_free_callback(rn, head, offset);)
+		free((void *)head - offset);
 		rcu_lock_release(&rcu_callback_map);
 		return true;
 	} else {
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 491bdf39f276..b662fa7497a0 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -3061,8 +3061,8 @@ __call_rcu(struct rcu_head *head, rcu_callback_t func,
 	if (!lazy)
 		rcu_idle_count_callbacks_posted();
 
-	if (__is_kfree_rcu_offset((unsigned long)func))
-		trace_rcu_kfree_callback(rsp->name, head, (unsigned long)func,
+	if (__is_free_rcu_offset((unsigned long)func))
+		trace_rcu_free_callback(rsp->name, head, (unsigned long)func,
 					 rcu_segcblist_n_lazy_cbs(&rdp->cblist),
 					 rcu_segcblist_n_cbs(&rdp->cblist));
 	else
@@ -3134,14 +3134,13 @@ EXPORT_SYMBOL_GPL(call_rcu_bh);
  * This will likely be later named something like "call_rcu_lazy()",
  * but this change will require some way of tagging the lazy RCU
  * callbacks in the list of pending callbacks. Until then, this
- * function may only be called from __kfree_rcu().
+ * function may only be called from __free_rcu().
  */
-void kfree_call_rcu(struct rcu_head *head,
-		    rcu_callback_t func)
+void free_call_rcu(struct rcu_head *head, rcu_callback_t func)
 {
 	__call_rcu(head, func, rcu_state_p, -1, 1);
 }
-EXPORT_SYMBOL_GPL(kfree_call_rcu);
+EXPORT_SYMBOL_GPL(free_call_rcu);
 
 /*
  * Because a context switch is a grace period for RCU-sched and RCU-bh,
-- 
2.16.2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/4] mm: Add free()
  2018-03-22 19:58 ` [PATCH 3/4] mm: Add free() Matthew Wilcox
@ 2018-03-23  8:04   ` Rasmus Villemoes
  2018-03-23 14:34     ` Matthew Wilcox
  2018-03-23 13:33   ` Kirill Tkhai
  2018-03-24  7:38   ` kbuild test robot
  2 siblings, 1 reply; 17+ messages in thread
From: Rasmus Villemoes @ 2018-03-23  8:04 UTC (permalink / raw)
  To: Matthew Wilcox, linux-mm
  Cc: Kirill Tkhai, Matthew Wilcox, linux-kernel, Paul E. McKenney

On 2018-03-22 20:58, Matthew Wilcox wrote:
> From: Matthew Wilcox <mawilcox@microsoft.com>
> 
> free() can free many different kinds of memory.

I'd be a bit worried about using that name. gcc very much knows about
the C standard's definition of that function, as can be seen on
godbolt.org by compiling

void free(const void *);
void f(void)
{
    free((void*)0);
}

with -O2 -Wall -Wextra -c. Anything from 4.6 onwards simply compiles this to

f:
 repz retq

And sure, your free() implementation obviously also has that property,
but I'm worried that they might one day decide to warn about the
prototype mismatch (actually, I'm surprised it doesn't warn now, given
that it obviously pretends to know what free() function I'm calling...),
or make some crazy optimization that will break stuff in very subtle ways.

Also, we probably don't want people starting to use free() (or whatever
name is chosen) if they do know the kind of memory they're freeing?
Maybe it should not be advertised that widely (i.e., in kernel.h).

Rasmus

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/4] mm: Add free()
  2018-03-22 19:58 ` [PATCH 3/4] mm: Add free() Matthew Wilcox
  2018-03-23  8:04   ` Rasmus Villemoes
@ 2018-03-23 13:33   ` Kirill Tkhai
  2018-03-23 15:14     ` Matthew Wilcox
  2018-03-24  7:38   ` kbuild test robot
  2 siblings, 1 reply; 17+ messages in thread
From: Kirill Tkhai @ 2018-03-23 13:33 UTC (permalink / raw)
  To: Matthew Wilcox, linux-mm; +Cc: Matthew Wilcox, linux-kernel, Paul E. McKenney

Hi, Matthew,

On 22.03.2018 22:58, Matthew Wilcox wrote:
> From: Matthew Wilcox <mawilcox@microsoft.com>
> 
> free() can free many different kinds of memory.
> 
> Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com>
> ---
>  include/linux/kernel.h |  2 ++
>  mm/util.c              | 39 +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 41 insertions(+)
> 
> diff --git a/include/linux/kernel.h b/include/linux/kernel.h
> index 3fd291503576..8bb578938e65 100644
> --- a/include/linux/kernel.h
> +++ b/include/linux/kernel.h
> @@ -933,6 +933,8 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
>  			 "pointer type mismatch in container_of()");	\
>  	((type *)(__mptr - offsetof(type, member))); })
>  
> +void free(const void *);
> +
>  /* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */
>  #ifdef CONFIG_FTRACE_MCOUNT_RECORD
>  # define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD
> diff --git a/mm/util.c b/mm/util.c
> index dc4c7b551aaf..8aa2071059b0 100644
> --- a/mm/util.c
> +++ b/mm/util.c
> @@ -26,6 +26,45 @@ static inline int is_kernel_rodata(unsigned long addr)
>  		addr < (unsigned long)__end_rodata;
>  }
>  
> +/**
> + * free() - Free memory
> + * @ptr: Pointer to memory
> + *
> + * This function can free almost any type of memory.  It can safely be
> + * called on:
> + * * NULL pointers.
> + * * Pointers to read-only data (will do nothing).
> + * * Pointers to memory allocated from kmalloc().
> + * * Pointers to memory allocated from kmem_cache_alloc().
> + * * Pointers to memory allocated from vmalloc().
> + * * Pointers to memory allocated from alloc_percpu().
> + * * Pointers to memory allocated from __get_free_pages().
> + * * Pointers to memory allocated from page_frag_alloc().
> + *
> + * It cannot free memory allocated by dma_pool_alloc() or dma_alloc_coherent().
> + */
> +void free(const void *ptr)
> +{
> +	struct page *page;
> +
> +	if (unlikely(ZERO_OR_NULL_PTR(ptr)))
> +		return;
> +	if (is_kernel_rodata((unsigned long)ptr))
> +		return;
> +
> +	page = virt_to_head_page(ptr);
> +	if (likely(PageSlab(page)))
> +		return kmem_cache_free(page->slab_cache, (void *)ptr);

It seems slab_cache is not generic for all types of slabs. SLOB does not care about it:

~/linux-next$ git grep -w slab_cache mm include | grep -v kasan
include/linux/mm.h:	 * slab code uses page->slab_cache, which share storage with page->ptl.
include/linux/mm_types.h:		struct kmem_cache *slab_cache;	/* SL[AU]B: Pointer to slab */
mm/slab.c:	return page->slab_cache;
mm/slab.c:	cachep = page->slab_cache;
mm/slab.c:	page->slab_cache = cache;
mm/slab.c:	cachep = page->slab_cache;
mm/slab.h:	cachep = page->slab_cache;
mm/slub.c:	if (unlikely(s != page->slab_cache)) {
mm/slub.c:		} else if (!page->slab_cache) {
mm/slub.c:	page->slab_cache = s;
mm/slub.c:	__free_slab(page->slab_cache, page);
mm/slub.c:		df->s = page->slab_cache;
mm/slub.c:	s = page->slab_cache;
mm/slub.c:	return slab_ksize(page->slab_cache);
mm/slub.c:	slab_free(page->slab_cache, page, object, NULL, 1, _RET_IP_);
mm/slub.c:			p->slab_cache = s;
mm/slub.c:			p->slab_cache = s;

Also, using kmem_cache_free() for kmalloc()'ed memory will connect them hardly,
and this may be difficult to maintain in the future. One more thing, there is
some kasan checks on the main way of kfree(), and there is no guarantee they
reflected in kmem_cache_free() identical.

Maybe, we will use kfree() for now, and skip kmemcache free() support? If there is
no different way to differ kmemcache memory from kmalloc()'ed memory, of course.

Kirill

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/4] mm: Add free()
  2018-03-23  8:04   ` Rasmus Villemoes
@ 2018-03-23 14:34     ` Matthew Wilcox
  2018-04-03  8:50       ` Pavel Machek
  0 siblings, 1 reply; 17+ messages in thread
From: Matthew Wilcox @ 2018-03-23 14:34 UTC (permalink / raw)
  To: Rasmus Villemoes
  Cc: linux-mm, Kirill Tkhai, Matthew Wilcox, linux-kernel, Paul E. McKenney

On Fri, Mar 23, 2018 at 09:04:10AM +0100, Rasmus Villemoes wrote:
> On 2018-03-22 20:58, Matthew Wilcox wrote:
> > From: Matthew Wilcox <mawilcox@microsoft.com>
> > 
> > free() can free many different kinds of memory.
> 
> I'd be a bit worried about using that name. gcc very much knows about
> the C standard's definition of that function, as can be seen on
> godbolt.org by compiling
> 
> void free(const void *);
> void f(void)
> {
>     free((void*)0);
> }
> 
> with -O2 -Wall -Wextra -c. Anything from 4.6 onwards simply compiles this to
> 
> f:
>  repz retq
> 
> And sure, your free() implementation obviously also has that property,
> but I'm worried that they might one day decide to warn about the
> prototype mismatch (actually, I'm surprised it doesn't warn now, given
> that it obviously pretends to know what free() function I'm calling...),
> or make some crazy optimization that will break stuff in very subtle ways.
> 
> Also, we probably don't want people starting to use free() (or whatever
> name is chosen) if they do know the kind of memory they're freeing?
> Maybe it should not be advertised that widely (i.e., in kernel.h).

All that you've said I see as an advantage, not a disadvantage.
Maybe I should change the prototype to match the userspace
free(), although gcc is deliberately lax about the constness of
function arguments when determining compatibility with builtins.
See match_builtin_function_types() if you're really curious.

gcc already does some nice optimisations around free().  For example, it
can eliminate dead stores:

#include <stdlib.h>

void f(char *foo)
{
	foo[1] = 3;
	free(foo);
}

becomes:

0000000000000000 <f>:
   0:	e9 00 00 00 00       	jmpq   5 <f+0x5>
			1: R_X86_64_PLT32	free-0x4

You can see more things it knows about free() by grepping for
BUILT_IN_FREE.  

I absolutely do want to see people using free() instead of kfree()
if it's not important that the memory was kmalloced.  I wouldn't go
through and change existing code, but I do want to see
#define malloc(x) kvmalloc((x), GFP_KERNEL)

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/4] mm: Add free()
  2018-03-23 13:33   ` Kirill Tkhai
@ 2018-03-23 15:14     ` Matthew Wilcox
  2018-03-23 15:49       ` Kirill Tkhai
                         ` (2 more replies)
  0 siblings, 3 replies; 17+ messages in thread
From: Matthew Wilcox @ 2018-03-23 15:14 UTC (permalink / raw)
  To: Kirill Tkhai; +Cc: linux-mm, Matthew Wilcox, linux-kernel, Paul E. McKenney

On Fri, Mar 23, 2018 at 04:33:24PM +0300, Kirill Tkhai wrote:
> > +	page = virt_to_head_page(ptr);
> > +	if (likely(PageSlab(page)))
> > +		return kmem_cache_free(page->slab_cache, (void *)ptr);
> 
> It seems slab_cache is not generic for all types of slabs. SLOB does not care about it:

Oof.  I was sure I checked that.  You're quite right that it doesn't ...
this should fix that problem:

diff --git a/mm/slob.c b/mm/slob.c
index 623e8a5c46ce..96339420c6fc 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -266,7 +266,7 @@ static void *slob_page_alloc(struct page *sp, size_t size, int align)
 /*
  * slob_alloc: entry point into the slob allocator.
  */
-static void *slob_alloc(size_t size, gfp_t gfp, int align, int node)
+static void *slob_alloc(size_t size, gfp_t gfp, int align, int node, void *c)
 {
 	struct page *sp;
 	struct list_head *prev;
@@ -324,6 +324,7 @@ static void *slob_alloc(size_t size, gfp_t gfp, int align, int node)
 		sp->units = SLOB_UNITS(PAGE_SIZE);
 		sp->freelist = b;
 		INIT_LIST_HEAD(&sp->lru);
+		sp->slab_cache = c;
 		set_slob(b, SLOB_UNITS(PAGE_SIZE), b + SLOB_UNITS(PAGE_SIZE));
 		set_slob_page_free(sp, slob_list);
 		b = slob_page_alloc(sp, size, align);
@@ -440,7 +441,7 @@ __do_kmalloc_node(size_t size, gfp_t gfp, int node, unsigned long caller)
 		if (!size)
 			return ZERO_SIZE_PTR;
 
-		m = slob_alloc(size + align, gfp, align, node);
+		m = slob_alloc(size + align, gfp, align, node, NULL);
 
 		if (!m)
 			return NULL;
@@ -544,7 +545,7 @@ static void *slob_alloc_node(struct kmem_cache *c, gfp_t flags, int node)
 	fs_reclaim_release(flags);
 
 	if (c->size < PAGE_SIZE) {
-		b = slob_alloc(c->size, flags, c->align, node);
+		b = slob_alloc(c->size, flags, c->align, node, c);
 		trace_kmem_cache_alloc_node(_RET_IP_, b, c->object_size,
 					    SLOB_UNITS(c->size) * SLOB_UNIT,
 					    flags, node);
@@ -600,6 +601,8 @@ static void kmem_rcu_free(struct rcu_head *head)
 
 void kmem_cache_free(struct kmem_cache *c, void *b)
 {
+	if (!c)
+		return kfree(b);
 	kmemleak_free_recursive(b, c->flags);
 	if (unlikely(c->flags & SLAB_TYPESAFE_BY_RCU)) {
 		struct slob_rcu *slob_rcu;

> Also, using kmem_cache_free() for kmalloc()'ed memory will connect them hardly,
> and this may be difficult to maintain in the future.

I think the win from being able to delete all the little RCU callbacks
that just do a kmem_cache_free() is big enough to outweigh the
disadvantage of forcing slab allocators to support kmem_cache_free()
working on kmalloced memory.

> One more thing, there is
> some kasan checks on the main way of kfree(), and there is no guarantee they
> reflected in kmem_cache_free() identical.

Which function are you talking about here?

slub calls slab_free() for both kfree() and kmem_cache_free().
slab calls __cache_free() for both kfree() and kmem_cache_free().
Each of them do their kasan handling in the called function.

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/4] mm: Add free()
  2018-03-23 15:14     ` Matthew Wilcox
@ 2018-03-23 15:49       ` Kirill Tkhai
  2018-03-23 16:15       ` Matthew Wilcox
  2018-03-25 23:56       ` Matthew Wilcox
  2 siblings, 0 replies; 17+ messages in thread
From: Kirill Tkhai @ 2018-03-23 15:49 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: linux-mm, Matthew Wilcox, linux-kernel, Paul E. McKenney

On 23.03.2018 18:14, Matthew Wilcox wrote:
> On Fri, Mar 23, 2018 at 04:33:24PM +0300, Kirill Tkhai wrote:
>>> +	page = virt_to_head_page(ptr);
>>> +	if (likely(PageSlab(page)))
>>> +		return kmem_cache_free(page->slab_cache, (void *)ptr);
>>
>> It seems slab_cache is not generic for all types of slabs. SLOB does not care about it:
> 
> Oof.  I was sure I checked that.  You're quite right that it doesn't ...
> this should fix that problem:
> 
> diff --git a/mm/slob.c b/mm/slob.c
> index 623e8a5c46ce..96339420c6fc 100644
> --- a/mm/slob.c
> +++ b/mm/slob.c
> @@ -266,7 +266,7 @@ static void *slob_page_alloc(struct page *sp, size_t size, int align)
>  /*
>   * slob_alloc: entry point into the slob allocator.
>   */
> -static void *slob_alloc(size_t size, gfp_t gfp, int align, int node)
> +static void *slob_alloc(size_t size, gfp_t gfp, int align, int node, void *c)
>  {
>  	struct page *sp;
>  	struct list_head *prev;
> @@ -324,6 +324,7 @@ static void *slob_alloc(size_t size, gfp_t gfp, int align, int node)
>  		sp->units = SLOB_UNITS(PAGE_SIZE);
>  		sp->freelist = b;
>  		INIT_LIST_HEAD(&sp->lru);
> +		sp->slab_cache = c;
>  		set_slob(b, SLOB_UNITS(PAGE_SIZE), b + SLOB_UNITS(PAGE_SIZE));
>  		set_slob_page_free(sp, slob_list);
>  		b = slob_page_alloc(sp, size, align);
> @@ -440,7 +441,7 @@ __do_kmalloc_node(size_t size, gfp_t gfp, int node, unsigned long caller)
>  		if (!size)
>  			return ZERO_SIZE_PTR;
>  
> -		m = slob_alloc(size + align, gfp, align, node);
> +		m = slob_alloc(size + align, gfp, align, node, NULL);
>  
>  		if (!m)
>  			return NULL;
> @@ -544,7 +545,7 @@ static void *slob_alloc_node(struct kmem_cache *c, gfp_t flags, int node)
>  	fs_reclaim_release(flags);
>  
>  	if (c->size < PAGE_SIZE) {
> -		b = slob_alloc(c->size, flags, c->align, node);
> +		b = slob_alloc(c->size, flags, c->align, node, c);
>  		trace_kmem_cache_alloc_node(_RET_IP_, b, c->object_size,
>  					    SLOB_UNITS(c->size) * SLOB_UNIT,
>  					    flags, node);
> @@ -600,6 +601,8 @@ static void kmem_rcu_free(struct rcu_head *head)
>  
>  void kmem_cache_free(struct kmem_cache *c, void *b)
>  {
> +	if (!c)
> +		return kfree(b);
>  	kmemleak_free_recursive(b, c->flags);
>  	if (unlikely(c->flags & SLAB_TYPESAFE_BY_RCU)) {
>  		struct slob_rcu *slob_rcu;
> 
>> Also, using kmem_cache_free() for kmalloc()'ed memory will connect them hardly,
>> and this may be difficult to maintain in the future.
> 
> I think the win from being able to delete all the little RCU callbacks
> that just do a kmem_cache_free() is big enough to outweigh the
> disadvantage of forcing slab allocators to support kmem_cache_free()
> working on kmalloced memory.
> 
>> One more thing, there is
>> some kasan checks on the main way of kfree(), and there is no guarantee they
>> reflected in kmem_cache_free() identical.
> 
> Which function are you talking about here?
> 
> slub calls slab_free() for both kfree() and kmem_cache_free().
> slab calls __cache_free() for both kfree() and kmem_cache_free().
> Each of them do their kasan handling in the called function.

Maybe not KASAN, I never dived deeply into sl[*]b. But they look like
just three different functions, doing different actions...

Kirill

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/4] mm: Add free()
  2018-03-23 15:14     ` Matthew Wilcox
  2018-03-23 15:49       ` Kirill Tkhai
@ 2018-03-23 16:15       ` Matthew Wilcox
  2018-03-25 23:56       ` Matthew Wilcox
  2 siblings, 0 replies; 17+ messages in thread
From: Matthew Wilcox @ 2018-03-23 16:15 UTC (permalink / raw)
  To: Kirill Tkhai; +Cc: linux-mm, Matthew Wilcox, linux-kernel, Paul E. McKenney

On Fri, Mar 23, 2018 at 08:14:21AM -0700, Matthew Wilcox wrote:
> > One more thing, there is
> > some kasan checks on the main way of kfree(), and there is no guarantee they
> > reflected in kmem_cache_free() identical.
> 
> Which function are you talking about here?
> 
> slub calls slab_free() for both kfree() and kmem_cache_free().
> slab calls __cache_free() for both kfree() and kmem_cache_free().
> Each of them do their kasan handling in the called function.

... except for where slub can free large objects without calling slab_free():

        if (unlikely(!PageSlab(page))) {
                BUG_ON(!PageCompound(page));
                kfree_hook(object);
                __free_pages(page, compound_order(page));
                return;
        }
        slab_free(page->slab_cache, page, object, NULL, 1, _RET_IP_);

If you call kmalloc(16384, GFP_KERNEL), slub will hand back an order-2
page without setting PageSlab on it.  So if that gets passed to free(),
it'll call __put_page() which calls free_compound_page() which calls
__free_pages_ok().  Looks like we want another compound_dtor to be sure
we call the kfree hook.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 4/4] rcu: Switch to using free() instead of kfree()
  2018-03-22 19:58 ` [PATCH 4/4] rcu: Switch to using free() instead of kfree() Matthew Wilcox
@ 2018-03-24  7:07   ` kbuild test robot
  2018-03-24  8:20   ` kbuild test robot
  1 sibling, 0 replies; 17+ messages in thread
From: kbuild test robot @ 2018-03-24  7:07 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: kbuild-all, linux-mm, Kirill Tkhai, Matthew Wilcox, linux-kernel,
	Paul E. McKenney

[-- Attachment #1: Type: text/plain, Size: 5078 bytes --]

Hi Matthew,

I love your patch! Perhaps something to improve:

[auto build test WARNING on rcu/rcu/next]
[also build test WARNING on v4.16-rc6 next-20180323]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Matthew-Wilcox/Add-free-function/20180324-140756
base:   https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git rcu/next
config: x86_64-randconfig-x016-201811 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All warnings (new ones prefixed by >>):

   In file included from include/linux/kernel.h:10:0,
                    from kernel/rcu/tree.c:31:
   kernel/rcu/tree_plugin.h: In function '__call_rcu_nocb':
   kernel/rcu/tree_plugin.h:2020:6: error: implicit declaration of function '__is_kfree_rcu_offset'; did you mean '__is_free_rcu_offset'? [-Werror=implicit-function-declaration]
     if (__is_kfree_rcu_offset((unsigned long)rhp->func))
         ^
   include/linux/compiler.h:58:30: note: in definition of macro '__trace_if'
     if (__builtin_constant_p(!!(cond)) ? !!(cond) :   \
                                 ^~~~
>> kernel/rcu/tree_plugin.h:2020:2: note: in expansion of macro 'if'
     if (__is_kfree_rcu_offset((unsigned long)rhp->func))
     ^~
   In file included from kernel/rcu/tree.c:4210:0:
   kernel/rcu/tree_plugin.h:2021:3: error: implicit declaration of function 'trace_rcu_kfree_callback'; did you mean 'trace_rcu_free_callback'? [-Werror=implicit-function-declaration]
      trace_rcu_kfree_callback(rdp->rsp->name, rhp,
      ^~~~~~~~~~~~~~~~~~~~~~~~
      trace_rcu_free_callback
   cc1: some warnings being treated as errors

vim +/if +2020 kernel/rcu/tree_plugin.h

3fbfbf7a3b kernel/rcutree_plugin.h  Paul E. McKenney    2012-08-19  2016  
d1e43fa5f8 kernel/rcutree_plugin.h  Frederic Weisbecker 2013-03-26  2017  	if (!rcu_is_nocb_cpu(rdp->cpu))
c271d3a957 kernel/rcu/tree_plugin.h Pranith Kumar       2014-07-08  2018  		return false;
96d3fd0d31 kernel/rcu/tree_plugin.h Paul E. McKenney    2013-10-04  2019  	__call_rcu_nocb_enqueue(rdp, rhp, &rhp->next, 1, lazy, flags);
21e7a60874 kernel/rcutree_plugin.h  Paul E. McKenney    2013-02-09 @2020  	if (__is_kfree_rcu_offset((unsigned long)rhp->func))
21e7a60874 kernel/rcutree_plugin.h  Paul E. McKenney    2013-02-09  2021  		trace_rcu_kfree_callback(rdp->rsp->name, rhp,
21e7a60874 kernel/rcutree_plugin.h  Paul E. McKenney    2013-02-09  2022  					 (unsigned long)rhp->func,
756cbf6bef kernel/rcutree_plugin.h  Paul E. McKenney    2013-08-15  2023  					 -atomic_long_read(&rdp->nocb_q_count_lazy),
756cbf6bef kernel/rcutree_plugin.h  Paul E. McKenney    2013-08-15  2024  					 -atomic_long_read(&rdp->nocb_q_count));
21e7a60874 kernel/rcutree_plugin.h  Paul E. McKenney    2013-02-09  2025  	else
21e7a60874 kernel/rcutree_plugin.h  Paul E. McKenney    2013-02-09  2026  		trace_rcu_callback(rdp->rsp->name, rhp,
756cbf6bef kernel/rcutree_plugin.h  Paul E. McKenney    2013-08-15  2027  				   -atomic_long_read(&rdp->nocb_q_count_lazy),
756cbf6bef kernel/rcutree_plugin.h  Paul E. McKenney    2013-08-15  2028  				   -atomic_long_read(&rdp->nocb_q_count));
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2029  
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2030  	/*
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2031  	 * If called from an extended quiescent state with interrupts
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2032  	 * disabled, invoke the RCU core in order to allow the idle-entry
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2033  	 * deferred-wakeup check to function.
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2034  	 */
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2035  	if (irqs_disabled_flags(flags) &&
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2036  	    !rcu_is_watching() &&
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2037  	    cpu_online(smp_processor_id()))
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2038  		invoke_rcu_core();
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2039  
c271d3a957 kernel/rcu/tree_plugin.h Pranith Kumar       2014-07-08  2040  	return true;
3fbfbf7a3b kernel/rcutree_plugin.h  Paul E. McKenney    2012-08-19  2041  }
3fbfbf7a3b kernel/rcutree_plugin.h  Paul E. McKenney    2012-08-19  2042  

:::::: The code at line 2020 was first introduced by commit
:::::: 21e7a6087480451804124cee27c0a7d0a7de1564 rcu: Add event tracing for no-CBs CPUs' callback registration

:::::: TO: Paul E. McKenney <paul.mckenney@linaro.org>
:::::: CC: Paul E. McKenney <paulmck@linux.vnet.ibm.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 27295 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/4] mm: Add free()
  2018-03-22 19:58 ` [PATCH 3/4] mm: Add free() Matthew Wilcox
  2018-03-23  8:04   ` Rasmus Villemoes
  2018-03-23 13:33   ` Kirill Tkhai
@ 2018-03-24  7:38   ` kbuild test robot
  2 siblings, 0 replies; 17+ messages in thread
From: kbuild test robot @ 2018-03-24  7:38 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: kbuild-all, linux-mm, Kirill Tkhai, Matthew Wilcox, linux-kernel,
	Paul E. McKenney

[-- Attachment #1: Type: text/plain, Size: 2869 bytes --]

Hi Matthew,

I love your patch! Yet something to improve:

[auto build test ERROR on rcu/rcu/next]
[also build test ERROR on v4.16-rc6 next-20180323]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Matthew-Wilcox/Add-free-function/20180324-140756
base:   https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git rcu/next
config: s390-default_defconfig (attached as .config)
compiler: s390x-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=s390 

All errors (new ones prefixed by >>):

>> drivers/s390/cio/blacklist.c:43:20: error: 'free' redeclared as different kind of symbol
    typedef enum {add, free} range_action;
                       ^~~~
   In file included from include/linux/list.h:9:0,
                    from include/linux/preempt.h:11,
                    from include/linux/spinlock.h:51,
                    from include/linux/vmalloc.h:5,
                    from drivers/s390/cio/blacklist.c:15:
   include/linux/kernel.h:935:6: note: previous declaration of 'free' was here
    void free(const void *);
         ^~~~

vim +/free +43 drivers/s390/cio/blacklist.c

^1da177e Linus Torvalds 2005-04-16  30  
^1da177e Linus Torvalds 2005-04-16  31  /*
^1da177e Linus Torvalds 2005-04-16  32   * "Blacklisting" of certain devices:
^1da177e Linus Torvalds 2005-04-16  33   * Device numbers given in the commandline as cio_ignore=... won't be known
^1da177e Linus Torvalds 2005-04-16  34   * to Linux.
^1da177e Linus Torvalds 2005-04-16  35   *
^1da177e Linus Torvalds 2005-04-16  36   * These can be single devices or ranges of devices
^1da177e Linus Torvalds 2005-04-16  37   */
^1da177e Linus Torvalds 2005-04-16  38  
fb6958a5 Cornelia Huck  2006-01-06  39  /* 65536 bits for each set to indicate if a devno is blacklisted or not */
a8237fc4 Cornelia Huck  2006-01-06  40  #define __BL_DEV_WORDS ((__MAX_SUBCHANNEL + (8*sizeof(long) - 1)) / \
^1da177e Linus Torvalds 2005-04-16  41  			 (8*sizeof(long)))
fb6958a5 Cornelia Huck  2006-01-06  42  static unsigned long bl_dev[__MAX_SSID + 1][__BL_DEV_WORDS];
^1da177e Linus Torvalds 2005-04-16 @43  typedef enum {add, free} range_action;
^1da177e Linus Torvalds 2005-04-16  44  

:::::: The code at line 43 was first introduced by commit
:::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2

:::::: TO: Linus Torvalds <torvalds@ppc970.osdl.org>
:::::: CC: Linus Torvalds <torvalds@ppc970.osdl.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 17664 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 4/4] rcu: Switch to using free() instead of kfree()
  2018-03-22 19:58 ` [PATCH 4/4] rcu: Switch to using free() instead of kfree() Matthew Wilcox
  2018-03-24  7:07   ` kbuild test robot
@ 2018-03-24  8:20   ` kbuild test robot
  1 sibling, 0 replies; 17+ messages in thread
From: kbuild test robot @ 2018-03-24  8:20 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: kbuild-all, linux-mm, Kirill Tkhai, Matthew Wilcox, linux-kernel,
	Paul E. McKenney

[-- Attachment #1: Type: text/plain, Size: 11364 bytes --]

Hi Matthew,

I love your patch! Yet something to improve:

[auto build test ERROR on rcu/rcu/next]
[also build test ERROR on v4.16-rc6 next-20180323]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Matthew-Wilcox/Add-free-function/20180324-140756
base:   https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git rcu/next
config: x86_64-randconfig-s0-03241416 (attached as .config)
compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   In file included from kernel/rcu/tree.c:4210:0:
   kernel/rcu/tree_plugin.h: In function '__call_rcu_nocb':
   kernel/rcu/tree_plugin.h:2020:6: error: implicit declaration of function '__is_kfree_rcu_offset' [-Werror=implicit-function-declaration]
     if (__is_kfree_rcu_offset((unsigned long)rhp->func))
         ^~~~~~~~~~~~~~~~~~~~~
>> kernel/rcu/tree_plugin.h:2021:3: error: implicit declaration of function 'trace_rcu_kfree_callback' [-Werror=implicit-function-declaration]
      trace_rcu_kfree_callback(rdp->rsp->name, rhp,
      ^~~~~~~~~~~~~~~~~~~~~~~~
   Cyclomatic Complexity 5 include/linux/compiler.h:__read_once_size
   Cyclomatic Complexity 5 include/linux/compiler.h:__write_once_size
   Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:constant_test_bit
   Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:variable_test_bit
   Cyclomatic Complexity 1 arch/x86/include/asm/arch_hweight.h:__arch_hweight64
   Cyclomatic Complexity 2 include/linux/bitops.h:hweight_long
   Cyclomatic Complexity 1 include/linux/kernel.h:tracing_off
   Cyclomatic Complexity 1 include/linux/kernel.h:ftrace_dump
   Cyclomatic Complexity 1 include/linux/list.h:INIT_LIST_HEAD
   Cyclomatic Complexity 2 include/linux/list.h:__list_add
   Cyclomatic Complexity 1 include/linux/list.h:list_add
   Cyclomatic Complexity 1 include/linux/list.h:list_add_tail
   Cyclomatic Complexity 1 include/linux/list.h:__list_del
   Cyclomatic Complexity 2 include/linux/list.h:__list_del_entry
   Cyclomatic Complexity 1 include/linux/list.h:list_del_init
   Cyclomatic Complexity 1 include/linux/list.h:list_empty
   Cyclomatic Complexity 1 include/linux/percpu-defs.h:__this_cpu_preempt_check
   Cyclomatic Complexity 1 arch/x86/include/asm/current.h:get_current
   Cyclomatic Complexity 3 include/linux/bitmap.h:bitmap_zero
   Cyclomatic Complexity 3 include/linux/bitmap.h:bitmap_and
   Cyclomatic Complexity 3 include/linux/bitmap.h:bitmap_subset
   Cyclomatic Complexity 3 include/linux/bitmap.h:bitmap_empty
   Cyclomatic Complexity 3 include/linux/bitmap.h:bitmap_weight
   Cyclomatic Complexity 1 include/linux/cpumask.h:cpumask_check
   Cyclomatic Complexity 1 include/linux/cpumask.h:cpumask_next
   Cyclomatic Complexity 1 include/linux/cpumask.h:cpumask_test_cpu
   Cyclomatic Complexity 1 include/linux/cpumask.h:cpumask_clear
   Cyclomatic Complexity 1 include/linux/cpumask.h:cpumask_and
   Cyclomatic Complexity 1 include/linux/cpumask.h:cpumask_subset
   Cyclomatic Complexity 1 include/linux/cpumask.h:cpumask_empty
   Cyclomatic Complexity 1 include/linux/cpumask.h:cpulist_parse
   Cyclomatic Complexity 1 include/linux/cpumask.h:zalloc_cpumask_var
   Cyclomatic Complexity 1 include/linux/cpumask.h:alloc_bootmem_cpumask_var
   Cyclomatic Complexity 1 include/linux/cpumask.h:cpumask_available
   Cyclomatic Complexity 1 include/linux/cpumask.h:get_cpu_mask
   Cyclomatic Complexity 1 arch/x86/include/asm/paravirt.h:arch_local_save_flags
   Cyclomatic Complexity 1 arch/x86/include/asm/paravirt.h:arch_local_irq_restore
   Cyclomatic Complexity 1 arch/x86/include/asm/paravirt.h:arch_local_irq_disable
   Cyclomatic Complexity 1 arch/x86/include/asm/paravirt.h:arch_local_irq_save
   Cyclomatic Complexity 1 include/linux/err.h:IS_ERR
   Cyclomatic Complexity 1 arch/x86/include/asm/irqflags.h:arch_irqs_disabled_flags
   Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_read
   Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_set
   Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_add
   Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_inc
   Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_dec_and_test
   Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_add_return
   Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_cmpxchg
   Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_xchg
   Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_and
   Cyclomatic Complexity 1 arch/x86/include/asm/atomic64_64.h:atomic64_read
   Cyclomatic Complexity 1 arch/x86/include/asm/atomic64_64.h:atomic64_set
   Cyclomatic Complexity 1 arch/x86/include/asm/atomic64_64.h:atomic64_add
   Cyclomatic Complexity 1 include/linux/atomic.h:atomic_andnot
   Cyclomatic Complexity 1 include/asm-generic/atomic-long.h:atomic_long_read
   Cyclomatic Complexity 1 include/asm-generic/atomic-long.h:atomic_long_set
   Cyclomatic Complexity 1 include/asm-generic/atomic-long.h:atomic_long_add
   Cyclomatic Complexity 2 include/linux/thread_info.h:test_ti_thread_flag
   Cyclomatic Complexity 1 arch/x86/include/asm/preempt.h:preempt_count
   Cyclomatic Complexity 5 arch/x86/include/asm/preempt.h:__preempt_count_add
   Cyclomatic Complexity 1 arch/x86/include/asm/preempt.h:__preempt_count_dec_and_test
   Cyclomatic Complexity 1 include/linux/bottom_half.h:__local_bh_disable_ip
   Cyclomatic Complexity 1 include/linux/bottom_half.h:local_bh_disable
   Cyclomatic Complexity 1 include/linux/bottom_half.h:local_bh_enable
   Cyclomatic Complexity 1 include/linux/lockdep.h:lock_is_held
   Cyclomatic Complexity 1 include/linux/spinlock.h:spinlock_check
   Cyclomatic Complexity 1 include/linux/spinlock.h:spin_lock
   Cyclomatic Complexity 1 include/linux/spinlock.h:spin_unlock
   Cyclomatic Complexity 1 include/linux/rcutree.h:synchronize_rcu_bh_expedited
   Cyclomatic Complexity 1 include/linux/rcupdate.h:rcu_lock_acquire
   Cyclomatic Complexity 1 include/linux/rcupdate.h:rcu_lock_release
   Cyclomatic Complexity 1 include/linux/completion.h:__init_completion
   Cyclomatic Complexity 1 include/linux/workqueue.h:__init_work
   Cyclomatic Complexity 1 include/linux/workqueue.h:queue_work
   Cyclomatic Complexity 1 include/linux/sched.h:is_idle_task
   Cyclomatic Complexity 1 include/linux/sched.h:task_thread_info
   Cyclomatic Complexity 1 include/linux/sched.h:test_tsk_thread_flag
   Cyclomatic Complexity 1 include/linux/sched.h:_cond_resched
   Cyclomatic Complexity 1 include/linux/sched.h:need_resched
   Cyclomatic Complexity 1 include/linux/sched.h:task_cpu
   Cyclomatic Complexity 1 include/linux/nmi.h:touch_softlockup_watchdog
   Cyclomatic Complexity 1 include/linux/nmi.h:arch_touch_nmi_watchdog
   Cyclomatic Complexity 1 include/linux/nmi.h:touch_nmi_watchdog
   Cyclomatic Complexity 1 include/linux/nmi.h:trigger_single_cpu_backtrace
   Cyclomatic Complexity 1 include/linux/irq_work.h:init_irq_work
   Cyclomatic Complexity 1 include/linux/cpu.h:cpus_read_lock
   Cyclomatic Complexity 1 include/linux/cpu.h:cpus_read_unlock
   Cyclomatic Complexity 1 include/linux/cpu.h:get_online_cpus
   Cyclomatic Complexity 1 include/linux/cpu.h:put_online_cpus
   Cyclomatic Complexity 1 include/linux/kernel_stat.h:kstat_softirqs_cpu
   Cyclomatic Complexity 1 include/linux/sched/signal.h:signal_pending
   Cyclomatic Complexity 1 kernel/rcu/rcu_segcblist.h:rcu_cblist_dequeued_lazy
   Cyclomatic Complexity 1 kernel/rcu/rcu_segcblist.h:rcu_segcblist_empty
   Cyclomatic Complexity 1 kernel/rcu/rcu_segcblist.h:rcu_segcblist_n_cbs
   Cyclomatic Complexity 1 kernel/rcu/rcu_segcblist.h:rcu_segcblist_n_lazy_cbs
   Cyclomatic Complexity 1 kernel/rcu/rcu_segcblist.h:rcu_segcblist_n_nonlazy_cbs
   Cyclomatic Complexity 1 kernel/rcu/rcu_segcblist.h:rcu_segcblist_is_enabled
   Cyclomatic Complexity 1 kernel/rcu/rcu_segcblist.h:rcu_segcblist_restempty

vim +/trace_rcu_kfree_callback +2021 kernel/rcu/tree_plugin.h

3fbfbf7a3b kernel/rcutree_plugin.h  Paul E. McKenney    2012-08-19  2016  
d1e43fa5f8 kernel/rcutree_plugin.h  Frederic Weisbecker 2013-03-26  2017  	if (!rcu_is_nocb_cpu(rdp->cpu))
c271d3a957 kernel/rcu/tree_plugin.h Pranith Kumar       2014-07-08  2018  		return false;
96d3fd0d31 kernel/rcu/tree_plugin.h Paul E. McKenney    2013-10-04  2019  	__call_rcu_nocb_enqueue(rdp, rhp, &rhp->next, 1, lazy, flags);
21e7a60874 kernel/rcutree_plugin.h  Paul E. McKenney    2013-02-09 @2020  	if (__is_kfree_rcu_offset((unsigned long)rhp->func))
21e7a60874 kernel/rcutree_plugin.h  Paul E. McKenney    2013-02-09 @2021  		trace_rcu_kfree_callback(rdp->rsp->name, rhp,
21e7a60874 kernel/rcutree_plugin.h  Paul E. McKenney    2013-02-09  2022  					 (unsigned long)rhp->func,
756cbf6bef kernel/rcutree_plugin.h  Paul E. McKenney    2013-08-15  2023  					 -atomic_long_read(&rdp->nocb_q_count_lazy),
756cbf6bef kernel/rcutree_plugin.h  Paul E. McKenney    2013-08-15  2024  					 -atomic_long_read(&rdp->nocb_q_count));
21e7a60874 kernel/rcutree_plugin.h  Paul E. McKenney    2013-02-09  2025  	else
21e7a60874 kernel/rcutree_plugin.h  Paul E. McKenney    2013-02-09  2026  		trace_rcu_callback(rdp->rsp->name, rhp,
756cbf6bef kernel/rcutree_plugin.h  Paul E. McKenney    2013-08-15  2027  				   -atomic_long_read(&rdp->nocb_q_count_lazy),
756cbf6bef kernel/rcutree_plugin.h  Paul E. McKenney    2013-08-15  2028  				   -atomic_long_read(&rdp->nocb_q_count));
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2029  
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2030  	/*
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2031  	 * If called from an extended quiescent state with interrupts
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2032  	 * disabled, invoke the RCU core in order to allow the idle-entry
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2033  	 * deferred-wakeup check to function.
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2034  	 */
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2035  	if (irqs_disabled_flags(flags) &&
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2036  	    !rcu_is_watching() &&
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2037  	    cpu_online(smp_processor_id()))
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2038  		invoke_rcu_core();
1772947bd0 kernel/rcu/tree_plugin.h Paul E. McKenney    2014-08-12  2039  
c271d3a957 kernel/rcu/tree_plugin.h Pranith Kumar       2014-07-08  2040  	return true;
3fbfbf7a3b kernel/rcutree_plugin.h  Paul E. McKenney    2012-08-19  2041  }
3fbfbf7a3b kernel/rcutree_plugin.h  Paul E. McKenney    2012-08-19  2042  

:::::: The code at line 2021 was first introduced by commit
:::::: 21e7a6087480451804124cee27c0a7d0a7de1564 rcu: Add event tracing for no-CBs CPUs' callback registration

:::::: TO: Paul E. McKenney <paul.mckenney@linaro.org>
:::::: CC: Paul E. McKenney <paulmck@linux.vnet.ibm.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 29086 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/4] mm: Add free()
  2018-03-23 15:14     ` Matthew Wilcox
  2018-03-23 15:49       ` Kirill Tkhai
  2018-03-23 16:15       ` Matthew Wilcox
@ 2018-03-25 23:56       ` Matthew Wilcox
  2 siblings, 0 replies; 17+ messages in thread
From: Matthew Wilcox @ 2018-03-25 23:56 UTC (permalink / raw)
  To: Kirill Tkhai; +Cc: linux-mm, Matthew Wilcox, linux-kernel, Paul E. McKenney

On Fri, Mar 23, 2018 at 08:14:21AM -0700, Matthew Wilcox wrote:
> On Fri, Mar 23, 2018 at 04:33:24PM +0300, Kirill Tkhai wrote:
> > > +	page = virt_to_head_page(ptr);
> > > +	if (likely(PageSlab(page)))
> > > +		return kmem_cache_free(page->slab_cache, (void *)ptr);
> > 
> > It seems slab_cache is not generic for all types of slabs. SLOB does not care about it:
> 
> Oof.  I was sure I checked that.  You're quite right that it doesn't ...
> this should fix that problem:

This patch was complete rubbish.  The point of SLOB is that it mixes
sizes within the same page, and doesn't store the size when allocating
from a slab.  So there is no way to tell.  I'm going to think about this
some more.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/4] mm: Add free()
  2018-03-23 14:34     ` Matthew Wilcox
@ 2018-04-03  8:50       ` Pavel Machek
  2018-04-03 11:41         ` Matthew Wilcox
  0 siblings, 1 reply; 17+ messages in thread
From: Pavel Machek @ 2018-04-03  8:50 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Rasmus Villemoes, linux-mm, Kirill Tkhai, Matthew Wilcox,
	linux-kernel, Paul E. McKenney

[-- Attachment #1: Type: text/plain, Size: 1545 bytes --]

Hi!

> > And sure, your free() implementation obviously also has that property,
> > but I'm worried that they might one day decide to warn about the
> > prototype mismatch (actually, I'm surprised it doesn't warn now, given
> > that it obviously pretends to know what free() function I'm calling...),
> > or make some crazy optimization that will break stuff in very subtle ways.
> > 
> > Also, we probably don't want people starting to use free() (or whatever
> > name is chosen) if they do know the kind of memory they're freeing?
> > Maybe it should not be advertised that widely (i.e., in kernel.h).
> 
> All that you've said I see as an advantage, not a disadvantage.
> Maybe I should change the prototype to match the userspace
> free(), although gcc is deliberately lax about the constness of
> function arguments when determining compatibility with builtins.
> See match_builtin_function_types() if you're really curious.
> 
> gcc already does some nice optimisations around free().  For example, it
> can eliminate dead stores:

Are we comfortable with that optimalization for kernel?

us: "Hey, let's remove those encryption keys before freeing memory."
gcc: :-).

us: "Hey, we want to erase lock magic values not to cause confusion
later."
gcc: "I like confusion!"

Yes, these probably can be fixed by strategic "volatile" and/or
barriers, but...
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/4] mm: Add free()
  2018-04-03  8:50       ` Pavel Machek
@ 2018-04-03 11:41         ` Matthew Wilcox
  0 siblings, 0 replies; 17+ messages in thread
From: Matthew Wilcox @ 2018-04-03 11:41 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Rasmus Villemoes, linux-mm, Kirill Tkhai, Matthew Wilcox,
	linux-kernel, Paul E. McKenney

On Tue, Apr 03, 2018 at 10:50:59AM +0200, Pavel Machek wrote:
> > gcc already does some nice optimisations around free().  For example, it
> > can eliminate dead stores:
> 
> Are we comfortable with that optimalization for kernel?
> 
> us: "Hey, let's remove those encryption keys before freeing memory."
> gcc: :-).
> 
> us: "Hey, we want to erase lock magic values not to cause confusion
> later."
> gcc: "I like confusion!"
> 
> Yes, these probably can be fixed by strategic "volatile" and/or
> barriers, but...

Exactly, we should mark those sites explicitly with volatile so that 
they aren't dead stores.

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2018-04-03 11:41 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-22 19:58 [PATCH 0/4] Add free() function Matthew Wilcox
2018-03-22 19:58 ` [PATCH 1/4] decompression: Rename malloc and free Matthew Wilcox
2018-03-22 19:58 ` [PATCH 2/4] Rename 'free' functions Matthew Wilcox
2018-03-22 19:58 ` [PATCH 3/4] mm: Add free() Matthew Wilcox
2018-03-23  8:04   ` Rasmus Villemoes
2018-03-23 14:34     ` Matthew Wilcox
2018-04-03  8:50       ` Pavel Machek
2018-04-03 11:41         ` Matthew Wilcox
2018-03-23 13:33   ` Kirill Tkhai
2018-03-23 15:14     ` Matthew Wilcox
2018-03-23 15:49       ` Kirill Tkhai
2018-03-23 16:15       ` Matthew Wilcox
2018-03-25 23:56       ` Matthew Wilcox
2018-03-24  7:38   ` kbuild test robot
2018-03-22 19:58 ` [PATCH 4/4] rcu: Switch to using free() instead of kfree() Matthew Wilcox
2018-03-24  7:07   ` kbuild test robot
2018-03-24  8:20   ` kbuild test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).