[patch 093/114] radix-tree: move rcu_head into a union with private_list

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Matthew Wilcox <willy@xxxxxxxxxxxxx>
Subject: radix-tree: move rcu_head into a union with private_list

I want to be able to reference node->parent after freeing node.  Currently
node->parent is in a union with rcu_head, so it is overwritten when the
node is put on the RCU list.  We know that private_list is not referenced
after the node is freed, so it is safe for these two members to share
space.

Link: http://lkml.kernel.org/r/1480369871-5271-50-git-send-email-mawilcox@xxxxxxxxxxxxxxxxx
Signed-off-by: Matthew Wilcox <willy@xxxxxxxxxxxxx>
Tested-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx>
Cc: Konstantin Khlebnikov <koct9i@xxxxxxxxx>
Cc: Ross Zwisler <ross.zwisler@xxxxxxxxxxxxxxx>
Cc: Matthew Wilcox <mawilcox@xxxxxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
---

 include/linux/radix-tree.h |   14 ++++----------
 lib/radix-tree.c           |    1 +
 2 files changed, 5 insertions(+), 10 deletions(-)

diff -puN include/linux/radix-tree.h~radix-tree-move-rcu_head-into-a-union-with-private_list include/linux/radix-tree.h
--- a/include/linux/radix-tree.h~radix-tree-move-rcu_head-into-a-union-with-private_list
+++ a/include/linux/radix-tree.h
@@ -85,18 +85,12 @@ struct radix_tree_node {
 	unsigned char	offset;		/* Slot offset in parent */
 	unsigned char	count;		/* Total entry count */
 	unsigned char	exceptional;	/* Exceptional entry count */
+	struct radix_tree_node *parent;		/* Used when ascending tree */
+	void *private_data;			/* For tree user */
 	union {
-		struct {
-			/* Used when ascending tree */
-			struct radix_tree_node *parent;
-			/* For tree user */
-			void *private_data;
-		};
-		/* Used when freeing node */
-		struct rcu_head	rcu_head;
+		struct list_head private_list;	/* For tree user */
+		struct rcu_head	rcu_head;	/* Used when freeing node */
 	};
-	/* For tree user */
-	struct list_head private_list;
 	void __rcu	*slots[RADIX_TREE_MAP_SIZE];
 	unsigned long	tags[RADIX_TREE_MAX_TAGS][RADIX_TREE_TAG_LONGS];
 };
diff -puN lib/radix-tree.c~radix-tree-move-rcu_head-into-a-union-with-private_list lib/radix-tree.c
--- a/lib/radix-tree.c~radix-tree-move-rcu_head-into-a-union-with-private_list
+++ a/lib/radix-tree.c
@@ -325,6 +325,7 @@ static void radix_tree_node_rcu_free(str
 		tag_clear(node, i, 0);
 
 	node->slots[0] = NULL;
+	INIT_LIST_HEAD(&node->private_list);
 
 	kmem_cache_free(radix_tree_node_cachep, node);
 }
_
--
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux