 include/linux/types.h | 1 +
 include/net/dst.h     | 2 +-
 kernel/rcu.h          | 1 +
 kernel/rcutree.c      | 6 ++++++
 4 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/include/linux/types.h b/include/linux/types.h
index 4d118ba11349..3f0d9daff906 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -209,6 +209,7 @@ struct ustat {
 struct callback_head {
 	struct callback_head *next;
 	void (*func)(struct callback_head *head);
+	unsigned long magic;
 };
 #define rcu_head callback_head
 
diff --git a/include/net/dst.h b/include/net/dst.h
index 1f8fd109e225..6f8acd031948 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -89,7 +89,7 @@ struct dst_entry {
 	 * (L1_CACHE_SIZE would be too much)
 	 */
 #ifdef CONFIG_64BIT
-	long			__pad_to_align_refcnt[2];
+	long			__pad_to_align_refcnt[1];
 #endif
 	/*
 	 * __refcnt wants to be on a different cache line from
diff --git a/kernel/rcu.h b/kernel/rcu.h
index 7f8e7590e3e5..0381ed3721bb 100644
--- a/kernel/rcu.h
+++ b/kernel/rcu.h
@@ -98,6 +98,7 @@ static inline bool __rcu_reclaim(char *rn, struct rcu_head *head)
 {
 	unsigned long offset = (unsigned long)head->func;
 
+	head->magic = 0;
 	if (__is_kfree_rcu_offset(offset)) {
 		RCU_TRACE(trace_rcu_invoke_kfree_callback(rn, head, offset));
 		kfree((void *)head - offset);
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 5b8ad827fd86..80f9cfb63748 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -2221,6 +2221,9 @@ static void __call_rcu_core(struct rcu_state *rsp, struct rcu_data *rdp,
 	}
 }
 
+/* Unlikely bit-pattern to check double RCU calls! */
+#define RCU_HEAD_MAGIC ((unsigned long)(0xfeeddead1acef8edll))
+
 /*
  * Helper function for call_rcu() and friends.  The cpu argument will
  * normally be -1, indicating "currently running CPU".  It may specify
@@ -2235,9 +2238,12 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
 	struct rcu_data *rdp;
 
 	WARN_ON_ONCE((unsigned long)head & 0x3); /* Misaligned rcu_head! */
+	if (WARN_ON_ONCE(head->magic == RCU_HEAD_MAGIC))
+		return;
 	debug_rcu_head_queue(head);
 	head->func = func;
 	head->next = NULL;
+	head->magic = RCU_HEAD_MAGIC;
 
 	/*
 	 * Opportunistically note grace-period endings and beginnings.
