From 4654af4f6b6855787b83c605343f04387f2296af Mon Sep 17 00:00:00 2001 From: Nemo Yu Date: Sun, 10 Jan 2016 05:27:20 +0800 Subject: [PATCH 1/2] Decreasing the size of radix_tree_node The count in radix_tree_node does NOT need to be unsigned int but unsigned short is enough. For the disability of calculating logarithm in compile time, original authors defined RADIX_TREE_HEIGHT_SHIFT as RADIX_TREE_MAX_PATH + 1, but it should be log2(RADIX_TREE_MAX_PATH) + 1 indeed. I noticed that and, after calculating I am aware of unsigned long is not suitable for count but unsigned short. Between, I knew there is an alignment of radix_tree_node, so I cannot tell if the size of radix_tree_node will actually decrease. --- include/linux/radix-tree.h | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index 33170dbd9db402..e0fb446e4d06f2 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h @@ -76,17 +76,39 @@ static inline int radix_tree_is_indirect_ptr(void *ptr) #define RADIX_TREE_MAX_PATH (DIV_ROUND_UP(RADIX_TREE_INDEX_BITS, \ RADIX_TREE_MAP_SHIFT)) +/* log2(RADIX_TREE_INDEX_BITS) will not above 10. */ +#if sizeof(unsigned long) == 16 +#define RADIX_TREE_INDEX_BITS_LOG2 (4 + 3) +#elif sizeof(unsigned long) == 32 +#define RADIX_TREE_INDEX_BITS_LOG2 (5 + 3) +#elif sizeof(unsigned long) == 64 +#define RADIX_TREE_INDEX_BITS_LOG2 (6 + 3) +#elif sizeof(unsigned long) == 128 +#define RADIX_TREE_INDEX_BITS_LOG2 (7 + 3) +#endif +/* log2(RADIX_TREE_MAX_PATH) will not above 9. */ +#if RADIX_TREE_MAP_SHIFT == 3 +#define RADIX_TREE_MAX_PATH_LOG2 (RADIX_TREE_INDEX_BITS_LOG2 - 1) +#else +#define RADIX_TREE_MAX_PATH_LOG2 (RADIX_TREE_INDEX_BITS_LOG2 - 2) +#endif + /* Height component in node->path */ -#define RADIX_TREE_HEIGHT_SHIFT (RADIX_TREE_MAX_PATH + 1) +#define RADIX_TREE_HEIGHT_SHIFT (RADIX_TREE_MAX_PATH_LOG2 + 1) #define RADIX_TREE_HEIGHT_MASK ((1UL << RADIX_TREE_HEIGHT_SHIFT) - 1) /* Internally used bits of node->count */ #define RADIX_TREE_COUNT_SHIFT (RADIX_TREE_MAP_SHIFT + 1) #define RADIX_TREE_COUNT_MASK ((1UL << RADIX_TREE_COUNT_SHIFT) - 1) +/* + * The number of bits of height and offset will not above 12, which is only + * achieved in case of sizeof(unsigned long) == 16 and RADIX_TREE_MAP_SHIFT == 6. + * So unsigned short is enough to store them two, which has 18 bits at least. + */ struct radix_tree_node { - unsigned int path; /* Offset in parent & height from the bottom */ unsigned int count; + unsigned short path; /* Offset in parent & height from the bottom */ union { struct { /* Used when ascending tree */ From 2f150ef213f4728b97a6bd94e52350362c7384a5 Mon Sep 17 00:00:00 2001 From: Nemo Yu Date: Sun, 10 Jan 2016 05:51:17 +0800 Subject: [PATCH 2/2] Update radix-tree.h --- include/linux/radix-tree.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index e0fb446e4d06f2..10d291ec3b07bc 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h @@ -87,10 +87,10 @@ static inline int radix_tree_is_indirect_ptr(void *ptr) #define RADIX_TREE_INDEX_BITS_LOG2 (7 + 3) #endif /* log2(RADIX_TREE_MAX_PATH) will not above 9. */ -#if RADIX_TREE_MAP_SHIFT == 3 -#define RADIX_TREE_MAX_PATH_LOG2 (RADIX_TREE_INDEX_BITS_LOG2 - 1) -#else +#if RADIX_TREE_MAP_SHIFT == 6 #define RADIX_TREE_MAX_PATH_LOG2 (RADIX_TREE_INDEX_BITS_LOG2 - 2) +#else +#define RADIX_TREE_MAX_PATH_LOG2 (RADIX_TREE_INDEX_BITS_LOG2 - 1) #endif /* Height component in node->path */