linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] Move kfree_rcu out of rcu code and use kfree_bulk
@ 2018-04-02  5:31 rao.shoaib
  2018-04-02  5:31 ` [PATCH 1/2] Move kfree_call_rcu() to slab_common.c rao.shoaib
  2018-04-02  5:31 ` [PATCH 2/2] kfree_rcu() should use kfree_bulk() interface rao.shoaib
  0 siblings, 2 replies; 10+ messages in thread
From: rao.shoaib @ 2018-04-02  5:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: paulmck, joe, willy, brouer, linux-mm, Rao Shoaib

From: Rao Shoaib <rao.shoaib@oracle.com>

This patch moves kfree_call_rcu() out of rcu related code to
mm/slab_common and updates kfree_rcu() to use new bulk memory free
functions as they are more efficient.

This is a resubmission of the previous patch.

Changes:

1) checkpatch.pl has been fixed, so kfree_rcu macro is much simpler

2) To handle preemption, preempt_enable()/preempt_disable() statements
   have been added to __rcu_bulk_free().


Rao Shoaib (2):
  Move kfree_call_rcu() to slab_common.c
  kfree_rcu() should use kfree_bulk() interface

 include/linux/mm.h       |   5 ++
 include/linux/rcupdate.h |  43 +-----------
 include/linux/rcutiny.h  |   8 ++-
 include/linux/rcutree.h  |   2 -
 include/linux/slab.h     |  42 ++++++++++++
 kernel/rcu/tree.c        |  24 +++----
 kernel/sysctl.c          |  40 +++++++++++
 mm/slab.h                |  23 +++++++
 mm/slab_common.c         | 172 +++++++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 302 insertions(+), 57 deletions(-)

-- 
2.7.4

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

* [PATCH 1/2] Move kfree_call_rcu() to slab_common.c
  2018-04-02  5:31 [PATCH 0/2] Move kfree_rcu out of rcu code and use kfree_bulk rao.shoaib
@ 2018-04-02  5:31 ` rao.shoaib
  2018-04-02  7:59   ` kbuild test robot
  2018-04-02  9:45   ` kbuild test robot
  2018-04-02  5:31 ` [PATCH 2/2] kfree_rcu() should use kfree_bulk() interface rao.shoaib
  1 sibling, 2 replies; 10+ messages in thread
From: rao.shoaib @ 2018-04-02  5:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: paulmck, joe, willy, brouer, linux-mm, Rao Shoaib

From: Rao Shoaib <rao.shoaib@oracle.com>

kfree_call_rcu does not belong in linux/rcupdate.h and should be moved to
slab_common.c

Signed-off-by: Rao Shoaib <rao.shoaib@oracle.com>
---
 include/linux/rcupdate.h | 43 +++----------------------------------------
 include/linux/rcutree.h  |  2 --
 include/linux/slab.h     | 42 ++++++++++++++++++++++++++++++++++++++++++
 kernel/rcu/tree.c        | 24 ++++++++++--------------
 mm/slab_common.c         | 10 ++++++++++
 5 files changed, 65 insertions(+), 56 deletions(-)

diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 043d047..6338fb6 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -55,6 +55,9 @@ void call_rcu(struct rcu_head *head, rcu_callback_t func);
 #define	call_rcu	call_rcu_sched
 #endif /* #else #ifdef CONFIG_PREEMPT_RCU */
 
+/* only for use by kfree_call_rcu() */
+void call_rcu_lazy(struct rcu_head *head, rcu_callback_t func);
+
 void call_rcu_bh(struct rcu_head *head, rcu_callback_t func);
 void call_rcu_sched(struct rcu_head *head, rcu_callback_t func);
 void synchronize_sched(void);
@@ -837,45 +840,6 @@ static inline notrace void rcu_read_unlock_sched_notrace(void)
 #define __is_kfree_rcu_offset(offset) ((offset) < 4096)
 
 /*
- * Helper macro for kfree_rcu() to prevent argument-expansion eyestrain.
- */
-#define __kfree_rcu(head, offset) \
-	do { \
-		BUILD_BUG_ON(!__is_kfree_rcu_offset(offset)); \
-		kfree_call_rcu(head, (rcu_callback_t)(unsigned long)(offset)); \
-	} while (0)
-
-/**
- * kfree_rcu() - kfree an object after a grace period.
- * @ptr:	pointer to kfree
- * @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
- * 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
- * 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
- * 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
- * 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().
- *
- * 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))
-
-
-/*
  * Place this after a lock-acquisition primitive to guarantee that
  * an UNLOCK+LOCK pair acts as a full barrier.  This guarantee applies
  * if the UNLOCK and LOCK are executed by the same CPU or if the
@@ -887,5 +851,4 @@ static inline notrace void rcu_read_unlock_sched_notrace(void)
 #define smp_mb__after_unlock_lock()	do { } while (0)
 #endif /* #else #ifdef CONFIG_ARCH_WEAK_RELEASE_ACQUIRE */
 
-
 #endif /* __LINUX_RCUPDATE_H */
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h
index fd996cd..567ef58 100644
--- a/include/linux/rcutree.h
+++ b/include/linux/rcutree.h
@@ -48,8 +48,6 @@ 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);
-
 /**
  * synchronize_rcu_bh_expedited - Brute-force RCU-bh grace period
  *
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 231abc8..116e870 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -355,6 +355,48 @@ void *__kmalloc(size_t size, gfp_t flags) __assume_kmalloc_alignment __malloc;
 void *kmem_cache_alloc(struct kmem_cache *, gfp_t flags) __assume_slab_alignment __malloc;
 void kmem_cache_free(struct kmem_cache *, void *);
 
+void kfree_call_rcu(struct rcu_head *head, rcu_callback_t func);
+
+/* Helper macro for kfree_rcu() to prevent argument-expansion eyestrain. */
+#define __kfree_rcu(head, offset) \
+	do { \
+		unsigned long __of = (unsigned long)offset;	\
+		BUILD_BUG_ON(!__is_kfree_rcu_offset(__of)); \
+		kfree_call_rcu(head, (rcu_callback_t)(__of));	\
+	} while (0)
+
+/**
+ * kfree_rcu() - kfree an object after a grace period.
+ * @ptr:	pointer to kfree
+ * @rcu_name:	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
+ * 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
+ * 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
+ * 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
+ * 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().
+ *
+ * The BUILD_BUG_ON check must not involve any function calls, hence the
+ * checks are done in macros here.
+ */
+#define kfree_rcu(ptr, rcu_name)	\
+	do {				\
+		unsigned long __off = offsetof(typeof(*(ptr)), rcu_name); \
+		struct rcu_head *__rptr = (void *)ptr + __off; \
+		__kfree_rcu(__rptr, __off); \
+	} while (0)
 /*
  * Bulk allocation and freeing operations. These are accelerated in an
  * allocator specific way to avoid taking locks repeatedly or building
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 491bdf3..e40f014 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -3101,6 +3101,16 @@ void call_rcu_sched(struct rcu_head *head, rcu_callback_t func)
 }
 EXPORT_SYMBOL_GPL(call_rcu_sched);
 
+/* Queue an RCU callback for lazy invocation after a grace period.
+ * Currently there is no way of tagging the lazy RCU callbacks in the
+ * list of pending callbacks. Until then, this function may only be
+ * called from kfree_call_rcu().
+ */
+void call_rcu_lazy(struct rcu_head *head, rcu_callback_t func)
+{
+	__call_rcu(head, func, rcu_state_p, -1, 1);
+}
+
 /**
  * call_rcu_bh() - Queue an RCU for invocation after a quicker grace period.
  * @head: structure to be used for queueing the RCU updates.
@@ -3130,20 +3140,6 @@ void call_rcu_bh(struct rcu_head *head, rcu_callback_t func)
 EXPORT_SYMBOL_GPL(call_rcu_bh);
 
 /*
- * Queue an RCU callback for lazy invocation after a grace period.
- * 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().
- */
-void kfree_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);
-
-/*
  * Because a context switch is a grace period for RCU-sched and RCU-bh,
  * any blocking grace-period wait automatically implies a grace period
  * if there is only one CPU online at any point time during execution
diff --git a/mm/slab_common.c b/mm/slab_common.c
index 10f127b..2ea9866 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -1525,6 +1525,16 @@ void kzfree(const void *p)
 }
 EXPORT_SYMBOL(kzfree);
 
+/*
+ * Queue Memory to be freed by RCU after a grace period.
+ */
+void kfree_call_rcu(struct rcu_head *head,
+		    rcu_callback_t func)
+{
+	call_rcu_lazy(head, func);
+}
+EXPORT_SYMBOL_GPL(kfree_call_rcu);
+
 /* Tracepoints definitions. */
 EXPORT_TRACEPOINT_SYMBOL(kmalloc);
 EXPORT_TRACEPOINT_SYMBOL(kmem_cache_alloc);
-- 
2.7.4

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

* [PATCH 2/2] kfree_rcu() should use kfree_bulk() interface
  2018-04-02  5:31 [PATCH 0/2] Move kfree_rcu out of rcu code and use kfree_bulk rao.shoaib
  2018-04-02  5:31 ` [PATCH 1/2] Move kfree_call_rcu() to slab_common.c rao.shoaib
@ 2018-04-02  5:31 ` rao.shoaib
  2018-04-02  7:13   ` kbuild test robot
  2018-04-02 17:20   ` Christopher Lameter
  1 sibling, 2 replies; 10+ messages in thread
From: rao.shoaib @ 2018-04-02  5:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: paulmck, joe, willy, brouer, linux-mm, Rao Shoaib

From: Rao Shoaib <rao.shoaib@oracle.com>

kfree_rcu() should use the new kfree_bulk() interface for freeing
rcu structures as it is more efficient.

Signed-off-by: Rao Shoaib <rao.shoaib@oracle.com>
---
 include/linux/mm.h      |   5 ++
 include/linux/rcutiny.h |   8 ++-
 kernel/sysctl.c         |  40 ++++++++++++
 mm/slab.h               |  23 +++++++
 mm/slab_common.c        | 164 +++++++++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 238 insertions(+), 2 deletions(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index ad06d42..fb1e54c 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2673,5 +2673,10 @@ void __init setup_nr_node_ids(void);
 static inline void setup_nr_node_ids(void) {}
 #endif
 
+extern int sysctl_kfree_rcu_drain_limit;
+extern int sysctl_kfree_rcu_poll_limit;
+extern int sysctl_kfree_rcu_empty_limit;
+extern int sysctl_kfree_rcu_caching_allowed;
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_MM_H */
diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h
index ce9beec..b9e9025 100644
--- a/include/linux/rcutiny.h
+++ b/include/linux/rcutiny.h
@@ -84,10 +84,16 @@ static inline void synchronize_sched_expedited(void)
 	synchronize_sched();
 }
 
+static inline void call_rcu_lazy(struct rcu_head *head,
+				 rcu_callback_t func)
+{
+	call_rcu(head, func);
+}
+
 static inline void kfree_call_rcu(struct rcu_head *head,
 				  rcu_callback_t func)
 {
-	call_rcu(head, func);
+	call_rcu_lazy(head, func);
 }
 
 #define rcu_note_context_switch(preempt) \
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index f98f28c..ab70c99 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1650,6 +1650,46 @@ static struct ctl_table vm_table[] = {
 		.extra2		= (void *)&mmap_rnd_compat_bits_max,
 	},
 #endif
+	{
+		.procname	= "kfree_rcu_drain_limit",
+		.data		= &sysctl_kfree_rcu_drain_limit,
+		.maxlen		= sizeof(sysctl_kfree_rcu_drain_limit),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &one,
+		.extra2		= &one_hundred,
+	},
+
+	{
+		.procname	= "kfree_rcu_poll_limit",
+		.data		= &sysctl_kfree_rcu_poll_limit,
+		.maxlen		= sizeof(sysctl_kfree_rcu_poll_limit),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &one,
+		.extra2		= &one_hundred,
+	},
+
+	{
+		.procname	= "kfree_rcu_empty_limit",
+		.data		= &sysctl_kfree_rcu_empty_limit,
+		.maxlen		= sizeof(sysctl_kfree_rcu_empty_limit),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &zero,
+		.extra2		= &four,
+	},
+
+	{
+		.procname	= "kfree_rcu_caching_allowed",
+		.data		= &sysctl_kfree_rcu_caching_allowed,
+		.maxlen		= sizeof(sysctl_kfree_rcu_caching_allowed),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &zero,
+		.extra2		= &one,
+	},
+
 	{ }
 };
 
diff --git a/mm/slab.h b/mm/slab.h
index 5181323..a332ea6 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -80,6 +80,29 @@ extern const struct kmalloc_info_struct {
 	unsigned long size;
 } kmalloc_info[];
 
+#define	RCU_MAX_ACCUMULATE_SIZE	25
+
+struct rcu_bulk_free_container {
+	struct	rcu_head rbfc_rcu;
+	int	rbfc_entries;
+	void	*rbfc_data[RCU_MAX_ACCUMULATE_SIZE];
+	struct	rcu_bulk_free *rbfc_rbf;
+};
+
+struct rcu_bulk_free {
+	struct	rcu_head rbf_rcu; /* used to schedule monitor process */
+	spinlock_t	rbf_lock;
+	struct		rcu_bulk_free_container *rbf_container;
+	struct		rcu_bulk_free_container *rbf_cached_container;
+	struct		rcu_head *rbf_list_head;
+	int		rbf_list_size;
+	int		rbf_cpu;
+	int		rbf_empty;
+	int		rbf_polled;
+	bool		rbf_init;
+	bool		rbf_monitor;
+};
+
 #ifndef CONFIG_SLOB
 /* Kmalloc array related functions */
 void setup_kmalloc_cache_index_table(void);
diff --git a/mm/slab_common.c b/mm/slab_common.c
index 2ea9866..6e8afff 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -20,6 +20,7 @@
 #include <asm/tlbflush.h>
 #include <asm/page.h>
 #include <linux/memcontrol.h>
+#include <linux/types.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/kmem.h>
@@ -1525,13 +1526,174 @@ void kzfree(const void *p)
 }
 EXPORT_SYMBOL(kzfree);
 
+static DEFINE_PER_CPU(struct rcu_bulk_free, cpu_rbf);
+
+/* drain if atleast these many objects */
+int sysctl_kfree_rcu_drain_limit __read_mostly = 10;
+
+/* time to poll if fewer than drain_limit */
+int sysctl_kfree_rcu_poll_limit __read_mostly = 5;
+
+/* num of times to check bfr exit */
+int sysctl_kfree_rcu_empty_limit __read_mostly = 2;
+
+int sysctl_kfree_rcu_caching_allowed __read_mostly = 1;
+
+/* RCU call back function. Frees the memory */
+static void __rcu_bulk_free_impl(struct rcu_head *rbfc_rcu)
+{
+	struct rcu_bulk_free *rbf = NULL;
+	struct rcu_bulk_free_container *rbfc = container_of(rbfc_rcu,
+	    struct rcu_bulk_free_container, rbfc_rcu);
+
+	kfree_bulk(rbfc->rbfc_entries, rbfc->rbfc_data);
+
+	rbf = rbfc->rbfc_rbf;
+	if (!sysctl_kfree_rcu_caching_allowed ||
+	    cmpxchg(&rbf->rbf_cached_container, NULL, rbfc)) {
+		kfree(rbfc);
+	}
+}
+
+/* processes list of rcu structures
+ * used when conatiner can not be allocated
+ */
+static void __rcu_bulk_schedule_list(struct rcu_bulk_free *rbf)
+{
+	int i;
+
+	for (i = 0; i < rbf->rbf_list_size; i++) {
+		struct rcu_head *free_head;
+
+		free_head = rbf->rbf_list_head;
+		rbf->rbf_list_head = free_head->next;
+		free_head->next = NULL;
+		call_rcu(free_head, free_head->func);
+	}
+	rbf->rbf_list_size = 0;
+}
+
+/* RCU monitoring function -- submits elements for RCU reclaim */
+static void __rcu_bulk_free_monitor(struct rcu_head *rbf_rcu)
+{
+	struct rcu_bulk_free *rbf = NULL;
+	struct rcu_bulk_free_container *rbfc = NULL;
+
+	rbf = container_of(rbf_rcu, struct rcu_bulk_free, rbf_rcu);
+
+	spin_lock(&rbf->rbf_lock);
+
+	rbfc = rbf->rbf_container;
+
+	rbf->rbf_polled++;
+	if (rbf->rbf_list_size > 0) {
+		if (rbf->rbf_list_size >= sysctl_kfree_rcu_drain_limit ||
+		    rbf->rbf_polled >= sysctl_kfree_rcu_poll_limit) {
+			rbf->rbf_polled = 0;
+			__rcu_bulk_schedule_list(rbf);
+		}
+	} else if (rbfc) {
+		if (rbfc->rbfc_entries >= sysctl_kfree_rcu_drain_limit ||
+		    rbf->rbf_polled >= sysctl_kfree_rcu_poll_limit) {
+			rbf->rbf_polled = 0;
+			call_rcu(&rbfc->rbfc_rcu, __rcu_bulk_free_impl);
+			rbf->rbf_container = NULL;
+		}
+	} else if (rbf->rbf_polled >= sysctl_kfree_rcu_empty_limit) {
+		rbf->rbf_monitor = false;
+		rbf->rbf_polled = 0;
+	}
+
+	spin_unlock(&rbf->rbf_lock);
+
+	if (rbf->rbf_monitor)
+		call_rcu(&rbf->rbf_rcu, __rcu_bulk_free_monitor);
+}
+
+/* Main RCU function that is called to free RCU structures */
+static void __rcu_bulk_free(struct rcu_head *head, rcu_callback_t func)
+{
+	unsigned long offset;
+	void *ptr;
+	struct rcu_bulk_free *rbf;
+	struct rcu_bulk_free_container *rbfc = NULL;
+
+	preempt_disable();
+	rbf = this_cpu_ptr(&cpu_rbf);
+
+	if (unlikely(!rbf->rbf_init)) {
+		spin_lock_init(&rbf->rbf_lock);
+		rbf->rbf_cpu = smp_processor_id();
+		rbf->rbf_init = true;
+	}
+
+	/* hold lock to protect against other cpu's */
+	spin_lock_bh(&rbf->rbf_lock);
+
+	rbfc = rbf->rbf_container;
+
+	if (!rbfc) {
+		if (!rbf->rbf_cached_container) {
+			rbf->rbf_container =
+			    kmalloc(sizeof(struct rcu_bulk_free_container),
+				    GFP_ATOMIC);
+		} else {
+			rbf->rbf_container =
+			    READ_ONCE(rbf->rbf_cached_container);
+			cmpxchg(&rbf->rbf_cached_container,
+				rbf->rbf_container, NULL);
+		}
+
+		if (unlikely(!rbf->rbf_container)) {
+			/* Memory allocation failed maintain a list */
+
+			head->func = (void *)func;
+			head->next = rbf->rbf_list_head;
+			rbf->rbf_list_head = head;
+			rbf->rbf_list_size++;
+			if (rbf->rbf_list_size == RCU_MAX_ACCUMULATE_SIZE)
+				__rcu_bulk_schedule_list(rbf);
+
+			goto done;
+		}
+
+		rbfc = rbf->rbf_container;
+		rbfc->rbfc_rbf = rbf;
+		rbfc->rbfc_entries = 0;
+
+		if (!rbf->rbf_list_head)
+			__rcu_bulk_schedule_list(rbf);
+	}
+
+	offset = (unsigned long)func;
+	ptr = (void *)head - offset;
+
+	rbfc->rbfc_data[rbfc->rbfc_entries++] = ptr;
+	if (rbfc->rbfc_entries == RCU_MAX_ACCUMULATE_SIZE) {
+		rbf->rbf_container = NULL;
+		spin_unlock_bh(&rbf->rbf_lock);
+		call_rcu_lazy(&rbfc->rbfc_rcu, __rcu_bulk_free_impl);
+		preempt_enable();
+		return;
+	}
+
+done:
+	if (!rbf->rbf_monitor) {
+		call_rcu_lazy(&rbf->rbf_rcu, __rcu_bulk_free_monitor);
+		rbf->rbf_monitor = true;
+	}
+
+	spin_unlock_bh(&rbf->rbf_lock);
+	preempt_enable();
+}
+
 /*
  * Queue Memory to be freed by RCU after a grace period.
  */
 void kfree_call_rcu(struct rcu_head *head,
 		    rcu_callback_t func)
 {
-	call_rcu_lazy(head, func);
+	__rcu_bulk_free(head, func);
 }
 EXPORT_SYMBOL_GPL(kfree_call_rcu);
 
-- 
2.7.4

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

* Re: [PATCH 2/2] kfree_rcu() should use kfree_bulk() interface
  2018-04-02  5:31 ` [PATCH 2/2] kfree_rcu() should use kfree_bulk() interface rao.shoaib
@ 2018-04-02  7:13   ` kbuild test robot
  2018-04-02 17:20   ` Christopher Lameter
  1 sibling, 0 replies; 10+ messages in thread
From: kbuild test robot @ 2018-04-02  7:13 UTC (permalink / raw)
  To: rao.shoaib
  Cc: kbuild-all, linux-kernel, paulmck, joe, willy, brouer, linux-mm

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

Hi Rao,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on rcu/rcu/next]
[also build test ERROR on v4.16 next-20180329]
[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/rao-shoaib-oracle-com/Move-kfree_rcu-out-of-rcu-code-and-use-kfree_bulk/20180402-135939
base:   https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git rcu/next
config: x86_64-randconfig-x010-201813 (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 errors (new ones prefixed by >>):

   In file included from include/linux/rcupdate.h:214:0,
                    from include/linux/srcu.h:33,
                    from include/linux/notifier.h:16,
                    from include/linux/memory_hotplug.h:7,
                    from include/linux/mmzone.h:775,
                    from include/linux/gfp.h:6,
                    from include/linux/slab.h:15,
                    from include/linux/crypto.h:24,
                    from arch/x86/kernel/asm-offsets.c:9:
>> include/linux/rcutiny.h:87:20: error: static declaration of 'call_rcu_lazy' follows non-static declaration
    static inline void call_rcu_lazy(struct rcu_head *head,
                       ^~~~~~~~~~~~~
   In file included from include/linux/srcu.h:33:0,
                    from include/linux/notifier.h:16,
                    from include/linux/memory_hotplug.h:7,
                    from include/linux/mmzone.h:775,
                    from include/linux/gfp.h:6,
                    from include/linux/slab.h:15,
                    from include/linux/crypto.h:24,
                    from arch/x86/kernel/asm-offsets.c:9:
   include/linux/rcupdate.h:59:6: note: previous declaration of 'call_rcu_lazy' was here
    void call_rcu_lazy(struct rcu_head *head, rcu_callback_t func);
         ^~~~~~~~~~~~~
   make[2]: *** [arch/x86/kernel/asm-offsets.s] Error 1
   make[2]: Target '__build' not remade because of errors.
   make[1]: *** [prepare0] Error 2
   make[1]: Target 'prepare' not remade because of errors.
   make: *** [sub-make] Error 2

vim +/call_rcu_lazy +87 include/linux/rcutiny.h

    86	
  > 87	static inline void call_rcu_lazy(struct rcu_head *head,
    88					 rcu_callback_t func)
    89	{
    90		call_rcu(head, func);
    91	}
    92	

---
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: 32909 bytes --]

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

* Re: [PATCH 1/2] Move kfree_call_rcu() to slab_common.c
  2018-04-02  5:31 ` [PATCH 1/2] Move kfree_call_rcu() to slab_common.c rao.shoaib
@ 2018-04-02  7:59   ` kbuild test robot
  2018-04-02  9:45   ` kbuild test robot
  1 sibling, 0 replies; 10+ messages in thread
From: kbuild test robot @ 2018-04-02  7:59 UTC (permalink / raw)
  To: rao.shoaib
  Cc: kbuild-all, linux-kernel, paulmck, joe, willy, brouer, linux-mm

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

Hi Rao,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on rcu/rcu/next]
[also build test ERROR on v4.16 next-20180329]
[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/rao-shoaib-oracle-com/Move-kfree_rcu-out-of-rcu-code-and-use-kfree_bulk/20180402-135939
base:   https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git rcu/next
config: i386-tinyconfig (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=i386 

All errors (new ones prefixed by >>):

>> mm/slab_common.c:1531:6: error: redefinition of 'kfree_call_rcu'
    void kfree_call_rcu(struct rcu_head *head,
         ^~~~~~~~~~~~~~
   In file included from include/linux/rcupdate.h:214:0,
                    from include/linux/srcu.h:33,
                    from include/linux/notifier.h:16,
                    from include/linux/memory_hotplug.h:7,
                    from include/linux/mmzone.h:775,
                    from include/linux/gfp.h:6,
                    from include/linux/slab.h:15,
                    from mm/slab_common.c:7:
   include/linux/rcutiny.h:87:20: note: previous definition of 'kfree_call_rcu' was here
    static inline void kfree_call_rcu(struct rcu_head *head,
                       ^~~~~~~~~~~~~~

vim +/kfree_call_rcu +1531 mm/slab_common.c

  1527	
  1528	/*
  1529	 * Queue Memory to be freed by RCU after a grace period.
  1530	 */
> 1531	void kfree_call_rcu(struct rcu_head *head,
  1532			    rcu_callback_t func)
  1533	{
  1534		call_rcu_lazy(head, func);
  1535	}
  1536	EXPORT_SYMBOL_GPL(kfree_call_rcu);
  1537	

---
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: 6743 bytes --]

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

* Re: [PATCH 1/2] Move kfree_call_rcu() to slab_common.c
  2018-04-02  5:31 ` [PATCH 1/2] Move kfree_call_rcu() to slab_common.c rao.shoaib
  2018-04-02  7:59   ` kbuild test robot
@ 2018-04-02  9:45   ` kbuild test robot
  2018-04-02 15:43     ` Paul E. McKenney
  1 sibling, 1 reply; 10+ messages in thread
From: kbuild test robot @ 2018-04-02  9:45 UTC (permalink / raw)
  To: rao.shoaib
  Cc: kbuild-all, linux-kernel, paulmck, joe, willy, brouer, linux-mm

Hi Rao,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on rcu/rcu/next]
[also build test WARNING on v4.16 next-20180329]
[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/rao-shoaib-oracle-com/Move-kfree_rcu-out-of-rcu-code-and-use-kfree_bulk/20180402-135939
base:   https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git rcu/next
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

   include/linux/init.h:134:6: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/init.h:135:5: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/init.h:268:6: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/init.h:269:6: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/printk.h:200:6: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/mem_encrypt.h:32:6: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/mem_encrypt.h:34:6: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/mem_encrypt.h:37:6: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/mem_encrypt.h:38:6: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/mem_encrypt.h:40:6: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/mem_encrypt.h:42:6: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/mem_encrypt.h:43:6: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/mem_encrypt.h:45:5: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/mem_encrypt.h:46:5: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/mem_encrypt.h:49:6: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/qspinlock.h:53:32: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/workqueue.h:646:5: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/workqueue.h:647:5: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/wait_bit.h:41:13: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/numa.h:34:12: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/numa.h:35:13: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/numa.h:62:13: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/vmalloc.h:64:13: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/vmalloc.h:173:8: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/vmalloc.h:174:8: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/fixmap.h:174:6: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/fixmap.h:176:6: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/fixmap.h:178:6: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/fixmap.h:180:6: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/apic.h:254:13: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/apic.h:430:13: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/io_apic.h:184:13: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/smp.h:113:6: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/smp.h:125:13: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/smp.h:126:13: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/percpu.h:110:33: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/percpu.h:112:13: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/percpu.h:114:12: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/percpu.h:118:12: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/percpu.h:126:12: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/fs.h:63:13: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/fs.h:64:13: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/fs.h:65:13: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/fs.h:66:13: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/memory_hotplug.h:221:13: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/mmzone.h:1292:15: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/fs.h:2421:13: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/fs.h:2422:13: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/fs.h:3329:5: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/hrtimer.h:497:13: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/kmemleak.h:29:33: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/kasan.h:29:6: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/kasan.h:30:6: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/pgtable.h:28:5: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/slab.h:135:6: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/slab.h:758:6: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/mm.h:1753:6: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/mm.h:1941:13: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/mm.h:2083:13: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/mm.h:2671:6: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/swiotlb.h:39:13: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/swiotlb.h:124:13: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/swiotlb.h:9:12: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/swiotlb.h:10:12: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/swiotlb.h:11:13: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/swiotlb.h:12:13: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/dma-contiguous.h:85:5: sparse: attribute 'indirect_branch': unknown attribute
   arch/x86/include/asm/vdso.h:44:13: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/cred.h:167:13: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/nsproxy.h:74:5: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/io.h:47:6: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/netdevice.h:302:5: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/netdevice.h:4056:5: sparse: attribute 'indirect_branch': unknown attribute
   include/linux/ftrace.h:462:6: sparse: attribute 'indirect_branch': unknown attribute
   include/trace/events/bpf.h:59:1: sparse: attribute 'indirect_branch': unknown attribute
   include/trace/events/bpf.h:95:1: sparse: attribute 'indirect_branch': unknown attribute
   include/trace/events/bpf.h:120:1: sparse: attribute 'indirect_branch': unknown attribute
   include/trace/events/bpf.h:150:1: sparse: attribute 'indirect_branch': unknown attribute
   include/trace/events/bpf.h:191:1: sparse: attribute 'indirect_branch': unknown attribute
   include/trace/events/bpf.h:231:1: sparse: attribute 'indirect_branch': unknown attribute
   include/trace/events/bpf.h:285:1: sparse: attribute 'indirect_branch': unknown attribute
   include/trace/events/bpf.h:315:1: sparse: attribute 'indirect_branch': unknown attribute
   include/trace/events/xdp.h:28:1: sparse: attribute 'indirect_branch': unknown attribute
   include/trace/events/xdp.h:53:1: sparse: attribute 'indirect_branch': unknown attribute
   include/trace/events/xdp.h:155:1: sparse: attribute 'indirect_branch': unknown attribute
   include/trace/events/xdp.h:190:1: sparse: attribute 'indirect_branch': unknown attribute
   kernel/bpf/core.c:1546:31: sparse: incorrect type in return expression (different address spaces) @@    expected struct bpf_prog_array [noderef] <asn:4>* @@    got sn:4>* @@
   kernel/bpf/core.c:1546:31:    expected struct bpf_prog_array [noderef] <asn:4>*
   kernel/bpf/core.c:1546:31:    got void *
   kernel/bpf/core.c:1550:17: sparse: incorrect type in return expression (different address spaces) @@    expected struct bpf_prog_array [noderef] <asn:4>* @@    got rray [noderef] <asn:4>* @@
   kernel/bpf/core.c:1550:17:    expected struct bpf_prog_array [noderef] <asn:4>*
   kernel/bpf/core.c:1550:17:    got struct bpf_prog_array *<noident>
>> kernel/bpf/core.c:1558:9: sparse: cast removes address space of expression
   kernel/bpf/core.c:1621:34: sparse: incorrect type in initializer (different address spaces) @@    expected struct bpf_prog **prog @@    got struct bpf_prog *struct bpf_prog **prog @@
   kernel/bpf/core.c:1621:34:    expected struct bpf_prog **prog
   kernel/bpf/core.c:1621:34:    got struct bpf_prog *[noderef] <asn:4>*<noident>
   kernel/bpf/core.c:1644:31: sparse: incorrect type in assignment (different address spaces) @@    expected struct bpf_prog **existing_prog @@    got struct bpf_prog *struct bpf_prog **existing_prog @@
   kernel/bpf/core.c:1644:31:    expected struct bpf_prog **existing_prog
   kernel/bpf/core.c:1644:31:    got struct bpf_prog *[noderef] <asn:4>*<noident>
   kernel/bpf/core.c:1666:15: sparse: incorrect type in assignment (different address spaces) @@    expected struct bpf_prog_array *array @@    got struct bpf_prog_astruct bpf_prog_array *array @@
   kernel/bpf/core.c:1666:15:    expected struct bpf_prog_array *array
   kernel/bpf/core.c:1666:15:    got struct bpf_prog_array [noderef] <asn:4>*
   kernel/bpf/core.c:1672:31: sparse: incorrect type in assignment (different address spaces) @@    expected struct bpf_prog **[assigned] existing_prog @@    got structstruct bpf_prog **[assigned] existing_prog @@
   kernel/bpf/core.c:1672:31:    expected struct bpf_prog **[assigned] existing_prog
   kernel/bpf/core.c:1672:31:    got struct bpf_prog *[noderef] <asn:4>*<noident>
   include/trace/events/bpf.h:59:1: sparse: Using plain integer as NULL pointer
   include/trace/events/bpf.h:95:1: sparse: Using plain integer as NULL pointer
   include/trace/events/bpf.h:120:1: sparse: Using plain integer as NULL pointer
   include/trace/events/bpf.h:191:1: sparse: Using plain integer as NULL pointer
   include/trace/events/bpf.h:231:1: sparse: Using plain integer as NULL pointer
   include/trace/events/bpf.h:285:1: sparse: Using plain integer as NULL pointer
   include/trace/events/bpf.h:315:1: sparse: too many warnings

vim +1558 kernel/bpf/core.c

324bda9e6c Alexei Starovoitov 2017-10-02  1542  
324bda9e6c Alexei Starovoitov 2017-10-02  1543  struct bpf_prog_array __rcu *bpf_prog_array_alloc(u32 prog_cnt, gfp_t flags)
324bda9e6c Alexei Starovoitov 2017-10-02  1544  {
324bda9e6c Alexei Starovoitov 2017-10-02  1545  	if (prog_cnt)
324bda9e6c Alexei Starovoitov 2017-10-02 @1546  		return kzalloc(sizeof(struct bpf_prog_array) +
324bda9e6c Alexei Starovoitov 2017-10-02  1547  			       sizeof(struct bpf_prog *) * (prog_cnt + 1),
324bda9e6c Alexei Starovoitov 2017-10-02  1548  			       flags);
324bda9e6c Alexei Starovoitov 2017-10-02  1549  
324bda9e6c Alexei Starovoitov 2017-10-02  1550  	return &empty_prog_array.hdr;
324bda9e6c Alexei Starovoitov 2017-10-02  1551  }
324bda9e6c Alexei Starovoitov 2017-10-02  1552  
324bda9e6c Alexei Starovoitov 2017-10-02  1553  void bpf_prog_array_free(struct bpf_prog_array __rcu *progs)
324bda9e6c Alexei Starovoitov 2017-10-02  1554  {
324bda9e6c Alexei Starovoitov 2017-10-02  1555  	if (!progs ||
324bda9e6c Alexei Starovoitov 2017-10-02  1556  	    progs == (struct bpf_prog_array __rcu *)&empty_prog_array.hdr)
324bda9e6c Alexei Starovoitov 2017-10-02  1557  		return;
324bda9e6c Alexei Starovoitov 2017-10-02 @1558  	kfree_rcu(progs, rcu);
324bda9e6c Alexei Starovoitov 2017-10-02  1559  }
324bda9e6c Alexei Starovoitov 2017-10-02  1560  

:::::: The code at line 1558 was first introduced by commit
:::::: 324bda9e6c5add86ba2e1066476481c48132aca0 bpf: multi program support for cgroup+bpf

:::::: TO: Alexei Starovoitov <ast@fb.com>
:::::: CC: David S. Miller <davem@davemloft.net>

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

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

* Re: [PATCH 1/2] Move kfree_call_rcu() to slab_common.c
  2018-04-02  9:45   ` kbuild test robot
@ 2018-04-02 15:43     ` Paul E. McKenney
  0 siblings, 0 replies; 10+ messages in thread
From: Paul E. McKenney @ 2018-04-02 15:43 UTC (permalink / raw)
  To: kbuild test robot
  Cc: rao.shoaib, kbuild-all, linux-kernel, joe, willy, brouer, linux-mm

On Mon, Apr 02, 2018 at 05:45:48PM +0800, kbuild test robot wrote:
> Hi Rao,
> 
> Thank you for the patch! Perhaps something to improve:
> 
> [auto build test WARNING on rcu/rcu/next]
> [also build test WARNING on v4.16 next-20180329]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

I have no idea what is going on with this one, but the other two are due
to not having Tiny RCU support for new-age kfree_rcu().

							Thanx, Paul

> url:    https://github.com/0day-ci/linux/commits/rao-shoaib-oracle-com/Move-kfree_rcu-out-of-rcu-code-and-use-kfree_bulk/20180402-135939
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git rcu/next
> reproduce:
>         # apt-get install sparse
>         make ARCH=x86_64 allmodconfig
>         make C=1 CF=-D__CHECK_ENDIAN__
> 
> 
> sparse warnings: (new ones prefixed by >>)
> 
>    include/linux/init.h:134:6: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/init.h:135:5: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/init.h:268:6: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/init.h:269:6: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/printk.h:200:6: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/mem_encrypt.h:32:6: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/mem_encrypt.h:34:6: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/mem_encrypt.h:37:6: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/mem_encrypt.h:38:6: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/mem_encrypt.h:40:6: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/mem_encrypt.h:42:6: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/mem_encrypt.h:43:6: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/mem_encrypt.h:45:5: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/mem_encrypt.h:46:5: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/mem_encrypt.h:49:6: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/qspinlock.h:53:32: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/workqueue.h:646:5: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/workqueue.h:647:5: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/wait_bit.h:41:13: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/numa.h:34:12: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/numa.h:35:13: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/numa.h:62:13: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/vmalloc.h:64:13: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/vmalloc.h:173:8: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/vmalloc.h:174:8: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/fixmap.h:174:6: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/fixmap.h:176:6: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/fixmap.h:178:6: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/fixmap.h:180:6: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/apic.h:254:13: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/apic.h:430:13: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/io_apic.h:184:13: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/smp.h:113:6: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/smp.h:125:13: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/smp.h:126:13: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/percpu.h:110:33: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/percpu.h:112:13: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/percpu.h:114:12: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/percpu.h:118:12: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/percpu.h:126:12: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/fs.h:63:13: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/fs.h:64:13: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/fs.h:65:13: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/fs.h:66:13: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/memory_hotplug.h:221:13: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/mmzone.h:1292:15: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/fs.h:2421:13: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/fs.h:2422:13: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/fs.h:3329:5: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/hrtimer.h:497:13: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/kmemleak.h:29:33: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/kasan.h:29:6: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/kasan.h:30:6: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/pgtable.h:28:5: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/slab.h:135:6: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/slab.h:758:6: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/mm.h:1753:6: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/mm.h:1941:13: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/mm.h:2083:13: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/mm.h:2671:6: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/swiotlb.h:39:13: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/swiotlb.h:124:13: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/swiotlb.h:9:12: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/swiotlb.h:10:12: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/swiotlb.h:11:13: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/swiotlb.h:12:13: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/dma-contiguous.h:85:5: sparse: attribute 'indirect_branch': unknown attribute
>    arch/x86/include/asm/vdso.h:44:13: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/cred.h:167:13: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/nsproxy.h:74:5: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/io.h:47:6: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/netdevice.h:302:5: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/netdevice.h:4056:5: sparse: attribute 'indirect_branch': unknown attribute
>    include/linux/ftrace.h:462:6: sparse: attribute 'indirect_branch': unknown attribute
>    include/trace/events/bpf.h:59:1: sparse: attribute 'indirect_branch': unknown attribute
>    include/trace/events/bpf.h:95:1: sparse: attribute 'indirect_branch': unknown attribute
>    include/trace/events/bpf.h:120:1: sparse: attribute 'indirect_branch': unknown attribute
>    include/trace/events/bpf.h:150:1: sparse: attribute 'indirect_branch': unknown attribute
>    include/trace/events/bpf.h:191:1: sparse: attribute 'indirect_branch': unknown attribute
>    include/trace/events/bpf.h:231:1: sparse: attribute 'indirect_branch': unknown attribute
>    include/trace/events/bpf.h:285:1: sparse: attribute 'indirect_branch': unknown attribute
>    include/trace/events/bpf.h:315:1: sparse: attribute 'indirect_branch': unknown attribute
>    include/trace/events/xdp.h:28:1: sparse: attribute 'indirect_branch': unknown attribute
>    include/trace/events/xdp.h:53:1: sparse: attribute 'indirect_branch': unknown attribute
>    include/trace/events/xdp.h:155:1: sparse: attribute 'indirect_branch': unknown attribute
>    include/trace/events/xdp.h:190:1: sparse: attribute 'indirect_branch': unknown attribute
>    kernel/bpf/core.c:1546:31: sparse: incorrect type in return expression (different address spaces) @@    expected struct bpf_prog_array [noderef] <asn:4>* @@    got sn:4>* @@
>    kernel/bpf/core.c:1546:31:    expected struct bpf_prog_array [noderef] <asn:4>*
>    kernel/bpf/core.c:1546:31:    got void *
>    kernel/bpf/core.c:1550:17: sparse: incorrect type in return expression (different address spaces) @@    expected struct bpf_prog_array [noderef] <asn:4>* @@    got rray [noderef] <asn:4>* @@
>    kernel/bpf/core.c:1550:17:    expected struct bpf_prog_array [noderef] <asn:4>*
>    kernel/bpf/core.c:1550:17:    got struct bpf_prog_array *<noident>
> >> kernel/bpf/core.c:1558:9: sparse: cast removes address space of expression
>    kernel/bpf/core.c:1621:34: sparse: incorrect type in initializer (different address spaces) @@    expected struct bpf_prog **prog @@    got struct bpf_prog *struct bpf_prog **prog @@
>    kernel/bpf/core.c:1621:34:    expected struct bpf_prog **prog
>    kernel/bpf/core.c:1621:34:    got struct bpf_prog *[noderef] <asn:4>*<noident>
>    kernel/bpf/core.c:1644:31: sparse: incorrect type in assignment (different address spaces) @@    expected struct bpf_prog **existing_prog @@    got struct bpf_prog *struct bpf_prog **existing_prog @@
>    kernel/bpf/core.c:1644:31:    expected struct bpf_prog **existing_prog
>    kernel/bpf/core.c:1644:31:    got struct bpf_prog *[noderef] <asn:4>*<noident>
>    kernel/bpf/core.c:1666:15: sparse: incorrect type in assignment (different address spaces) @@    expected struct bpf_prog_array *array @@    got struct bpf_prog_astruct bpf_prog_array *array @@
>    kernel/bpf/core.c:1666:15:    expected struct bpf_prog_array *array
>    kernel/bpf/core.c:1666:15:    got struct bpf_prog_array [noderef] <asn:4>*
>    kernel/bpf/core.c:1672:31: sparse: incorrect type in assignment (different address spaces) @@    expected struct bpf_prog **[assigned] existing_prog @@    got structstruct bpf_prog **[assigned] existing_prog @@
>    kernel/bpf/core.c:1672:31:    expected struct bpf_prog **[assigned] existing_prog
>    kernel/bpf/core.c:1672:31:    got struct bpf_prog *[noderef] <asn:4>*<noident>
>    include/trace/events/bpf.h:59:1: sparse: Using plain integer as NULL pointer
>    include/trace/events/bpf.h:95:1: sparse: Using plain integer as NULL pointer
>    include/trace/events/bpf.h:120:1: sparse: Using plain integer as NULL pointer
>    include/trace/events/bpf.h:191:1: sparse: Using plain integer as NULL pointer
>    include/trace/events/bpf.h:231:1: sparse: Using plain integer as NULL pointer
>    include/trace/events/bpf.h:285:1: sparse: Using plain integer as NULL pointer
>    include/trace/events/bpf.h:315:1: sparse: too many warnings
> 
> vim +1558 kernel/bpf/core.c
> 
> 324bda9e6c Alexei Starovoitov 2017-10-02  1542  
> 324bda9e6c Alexei Starovoitov 2017-10-02  1543  struct bpf_prog_array __rcu *bpf_prog_array_alloc(u32 prog_cnt, gfp_t flags)
> 324bda9e6c Alexei Starovoitov 2017-10-02  1544  {
> 324bda9e6c Alexei Starovoitov 2017-10-02  1545  	if (prog_cnt)
> 324bda9e6c Alexei Starovoitov 2017-10-02 @1546  		return kzalloc(sizeof(struct bpf_prog_array) +
> 324bda9e6c Alexei Starovoitov 2017-10-02  1547  			       sizeof(struct bpf_prog *) * (prog_cnt + 1),
> 324bda9e6c Alexei Starovoitov 2017-10-02  1548  			       flags);
> 324bda9e6c Alexei Starovoitov 2017-10-02  1549  
> 324bda9e6c Alexei Starovoitov 2017-10-02  1550  	return &empty_prog_array.hdr;
> 324bda9e6c Alexei Starovoitov 2017-10-02  1551  }
> 324bda9e6c Alexei Starovoitov 2017-10-02  1552  
> 324bda9e6c Alexei Starovoitov 2017-10-02  1553  void bpf_prog_array_free(struct bpf_prog_array __rcu *progs)
> 324bda9e6c Alexei Starovoitov 2017-10-02  1554  {
> 324bda9e6c Alexei Starovoitov 2017-10-02  1555  	if (!progs ||
> 324bda9e6c Alexei Starovoitov 2017-10-02  1556  	    progs == (struct bpf_prog_array __rcu *)&empty_prog_array.hdr)
> 324bda9e6c Alexei Starovoitov 2017-10-02  1557  		return;
> 324bda9e6c Alexei Starovoitov 2017-10-02 @1558  	kfree_rcu(progs, rcu);
> 324bda9e6c Alexei Starovoitov 2017-10-02  1559  }
> 324bda9e6c Alexei Starovoitov 2017-10-02  1560  
> 
> :::::: The code at line 1558 was first introduced by commit
> :::::: 324bda9e6c5add86ba2e1066476481c48132aca0 bpf: multi program support for cgroup+bpf
> 
> :::::: TO: Alexei Starovoitov <ast@fb.com>
> :::::: CC: David S. Miller <davem@davemloft.net>
> 
> ---
> 0-DAY kernel test infrastructure                Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
> 

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

* Re: [PATCH 2/2] kfree_rcu() should use kfree_bulk() interface
  2018-04-02  5:31 ` [PATCH 2/2] kfree_rcu() should use kfree_bulk() interface rao.shoaib
  2018-04-02  7:13   ` kbuild test robot
@ 2018-04-02 17:20   ` Christopher Lameter
  2018-04-04  7:28     ` Rao Shoaib
  1 sibling, 1 reply; 10+ messages in thread
From: Christopher Lameter @ 2018-04-02 17:20 UTC (permalink / raw)
  To: Rao Shoaib; +Cc: linux-kernel, paulmck, joe, willy, brouer, linux-mm

On Sun, 1 Apr 2018, rao.shoaib@oracle.com wrote:

> kfree_rcu() should use the new kfree_bulk() interface for freeing
> rcu structures as it is more efficient.

It would be even better if this approach could also use

	kmem_cache_free_bulk()

or

	kfree_bulk()

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

* Re: [PATCH 2/2] kfree_rcu() should use kfree_bulk() interface
  2018-04-02 17:20   ` Christopher Lameter
@ 2018-04-04  7:28     ` Rao Shoaib
  0 siblings, 0 replies; 10+ messages in thread
From: Rao Shoaib @ 2018-04-04  7:28 UTC (permalink / raw)
  To: Christopher Lameter; +Cc: linux-kernel, paulmck, joe, willy, brouer, linux-mm



On 04/02/2018 10:20 AM, Christopher Lameter wrote:
> On Sun, 1 Apr 2018, rao.shoaib@oracle.com wrote:
>
>> kfree_rcu() should use the new kfree_bulk() interface for freeing
>> rcu structures as it is more efficient.
> It would be even better if this approach could also use
>
> 	kmem_cache_free_bulk()
>
> or
>
> 	kfree_bulk()
Sorry I do not understand your comment. The patch is using kfree_bulk() 
which is an inline function.

Shoaib

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

* [PATCH 0/2] Move kfree_rcu out of rcu code and use kfree_bulk
@ 2018-04-03 17:22 rao.shoaib
  0 siblings, 0 replies; 10+ messages in thread
From: rao.shoaib @ 2018-04-03 17:22 UTC (permalink / raw)
  To: linux-kernel; +Cc: paulmck, joe, willy, brouer, linux-mm, Rao Shoaib

From: Rao Shoaib <rao.shoaib@oracle.com>

This patch moves kfree_call_rcu() out of rcu related code to
mm/slab_common and updates kfree_rcu() to use new bulk memory free
functions as they are more efficient.

This is a resubmission of the previous patch.

Changes since last submission
	Surrounded code with 'CONFIG_TREE_RCU || CONFIG_PREEMPT_RCU'
	to separate tinyurl definitions.

Diff of the changes:

diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 6338fb6..102a93f 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -55,8 +55,6 @@ void call_rcu(struct rcu_head *head, rcu_callback_t func);
 #define        call_rcu        call_rcu_sched
 #endif /* #else #ifdef CONFIG_PREEMPT_RCU */
 
-/* only for use by kfree_call_rcu() */
-void call_rcu_lazy(struct rcu_head *head, rcu_callback_t func);
 
 void call_rcu_bh(struct rcu_head *head, rcu_callback_t func);
 void call_rcu_sched(struct rcu_head *head, rcu_callback_t func);
@@ -210,6 +208,8 @@ do { \
 
 #if defined(CONFIG_TREE_RCU) || defined(CONFIG_PREEMPT_RCU)
 #include <linux/rcutree.h>
+/* only for use by kfree_call_rcu() */
+void call_rcu_lazy(struct rcu_head *head, rcu_callback_t func);
 #elif defined(CONFIG_TINY_RCU)
 #include <linux/rcutiny.h>
 #else
diff --git a/mm/slab_common.c b/mm/slab_common.c
index 6e8afff..f126d08 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -1526,6 +1526,7 @@ void kzfree(const void *p)
 }
 EXPORT_SYMBOL(kzfree);
 
+#if defined(CONFIG_TREE_RCU) || defined(CONFIG_PREEMPT_RCU)
 static DEFINE_PER_CPU(struct rcu_bulk_free, cpu_rbf);
 
 /* drain if atleast these many objects */
@@ -1696,6 +1697,7 @@ void kfree_call_rcu(struct rcu_head *head,
        __rcu_bulk_free(head, func);
 }
 EXPORT_SYMBOL_GPL(kfree_call_rcu);
+#endif

Previous Changes:

1) checkpatch.pl has been fixed, so kfree_rcu macro is much simpler

2) To handle preemption, preempt_enable()/preempt_disable() statements
   have been added to __rcu_bulk_free().

Rao Shoaib (2):
  Move kfree_call_rcu() to slab_common.c
  kfree_rcu() should use kfree_bulk() interface

 include/linux/mm.h       |   5 ++
 include/linux/rcupdate.h |  43 +-----------
 include/linux/rcutiny.h  |   8 ++-
 include/linux/rcutree.h  |   2 -
 include/linux/slab.h     |  42 ++++++++++++
 kernel/rcu/tree.c        |  24 +++----
 kernel/sysctl.c          |  40 +++++++++++
 mm/slab.h                |  23 +++++++
 mm/slab_common.c         | 174 +++++++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 304 insertions(+), 57 deletions(-)

-- 
2.7.4

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

end of thread, other threads:[~2018-04-04  7:29 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-02  5:31 [PATCH 0/2] Move kfree_rcu out of rcu code and use kfree_bulk rao.shoaib
2018-04-02  5:31 ` [PATCH 1/2] Move kfree_call_rcu() to slab_common.c rao.shoaib
2018-04-02  7:59   ` kbuild test robot
2018-04-02  9:45   ` kbuild test robot
2018-04-02 15:43     ` Paul E. McKenney
2018-04-02  5:31 ` [PATCH 2/2] kfree_rcu() should use kfree_bulk() interface rao.shoaib
2018-04-02  7:13   ` kbuild test robot
2018-04-02 17:20   ` Christopher Lameter
2018-04-04  7:28     ` Rao Shoaib
2018-04-03 17:22 [PATCH 0/2] Move kfree_rcu out of rcu code and use kfree_bulk rao.shoaib

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox