Linux kernel radix Tree (one)

Source: Internet
Author: User

I. Overview

The most extensive use of the Linux radix tree is for memory management, and the structure address_space binds to the core page on the address map through radix tree tracking, which allows memory management code to quickly find pages identified as dirty or writeback. The API functions of the Linux radix tree are implemented in lib/radix-tree.c.

The Linux cardinality tree (radix trees) is a mechanism that associates pointers with long integer key values, which are stored efficiently and can be queried quickly for mapping pointers to integer values (such as the IDR mechanism), memory management, and so on.

A radix tree with 3 levels of nodes is displayed, with each data entry (item) indexed with 3 6-bit key values (key), and the key values from left to right represent the 1th to 3rd-level node location. nodes without children do not appear in the diagram. Therefore, the radix tree provides efficient storage for sparse trees, instead of a fixed size array, which provides quick lookups of key values to pointers.
Take index=0x5bfb68 as an example, to binary, every 6 bits for a group: 10110 (22, first layer number) 111111 (63 second number) 101101 (45 third tier number) 101000 (40 fourth layer number)

II. BASIC Data Structures

struct Radix_tree_root {
unsigned int height;
gfp_t Gfp_mask;
struct Radix_tree_node *rnode;/* An indirect pointer to a node rather than a data entry, by setting the low of the root->rnode to indicate whether it is a pointer */
};

struct Radix_tree_node {
unsigned int height; /* Tree height calculated from the leaf upward */
unsigned int count; /* The non-leaf node contains a count field that indicates the number of children that are present at the node */
struct Rcu_head rcu_head;
void *slots[radix_tree_map_size]; 64 pointers, 64 sub-nodes per layer
unsigned long tags[radix_tree_max_tags][radix_tree_tag_longs];
2x2 array, each member is 32 bits,
In the node structure Radix_tree_node, the tags domain is a two-dimensional array, each slot with 2-bit identification, which is a typical use of space-time application. The tags field is used to record the node below which the sub-node has no corresponding flag bit.
Node Label array = maximum number of label bits required per slot number of long type variables required for *slot number
/*tag[0]64 bits, 2 long, each representing a slot that represents its pg_dirty
Tag[0]64 bits, 2 long, each representing a slot that represents its pg_writeback
If the current node's tags[0] value is 1, then its subtree node has a page_cache_dirty node, otherwise this subtree branch does not exist such a node, you do not have to find this subtree. For example, when looking for pg_dirty pages, you do not need to traverse the entire tree, but can skip those tags[0] 0 values of the subtree, which improves the search efficiency * *
};

Third, global definition

#define RADIX_TREE_MAP_SHIFT 6
/* has a value of 6 o'clock, indicating that each node has 2^6=64 slots and a value of 4 o'clock, indicating 2^4=16 slot*/
#define RADIX_TREE_MAP_ SIZE (1UL <<radix_tree_map_shift)//1000000,2^6=64
/* represents 1 leaf nodes with a mapped number of pages, such as: 1<<6=64, which represents 64 slot mappings for 64 pages */
#define RADIX_TREE_MAP_MASK (radix_tree_map_size-1)//111111
#define radix_tree_tag_longs \
((radix_tree_ Map_size + bits_per_long-1)/bits_per_long)//(64+32-1)/32=2
#define RADIX_TREE_INDEX_BITS (8/* char_bit */* Sizeo F (unsignedlong))//32
#define Radix_tree_max_path (div_round_up (radix_tree_index_bits, \
Radix_tree_map_ SHIFT)//(32+6-1)/6=6
#define RADIX_TREE_MAX_TAGS 2
/* Defines the number of long type lengths used by the slots, each slot is marked with a bitmap 1 bit, for example: 64 slots with a value of /

Static unsigned long Height_to_maxindex[radix_tree_max_path + 1]
Global array, on a 32-bit machine, the array size is 7, which indicates the maximum number of slots per layer
Height=0:maxindex=0, there's only one radix_tree_node on the first floor.
Height=1:maxindex=2^6-1, a maximum of 63 on the second floor
Height=2:maxindex=2^12-1,
Height=3:maxindex=2^18-1,
Height=4:maxindex=2^24-1, if each slot is 4k, it supports 64G
Height=5:maxindex=2^30-1,
Height=6:maxindex=2^32-1, 16T

Iv. initialization functions

Initializes a name that is the root of name. Mask is a GFP-related mask that is used in memory management.
#define RADIX_TREE (name, mask)
struct Radix_tree_root my_tree;
Init_radix_tree (My_tree, Gfp_mask);
248 void __init radix_tree_init (void)
1249 {
1250 Radix_tree_node_cachep = kmem_cache_create ("Radix_tree_node",
1251 sizeof (struct Radix_tree_node), 0, Slab_panic | Slab_reclaim_account,
1253 radix_tree_node_ctor);
1254 Radix_tree_init_maxindex ();//Initialize global array Height_to_maxindex
1255 Hotcpu_notifier (radix_tree_callback, 0);
1256}

v. Inserting entries

int Radix_tree_insert (struct radix_tree_root *root, unsigned long, void *item);
The Radix_tree_insert function inserts the entry item into the tree root and returns an error-enomem if the memory allocation error is inserted in the entry. The function cannot overwrite entries that have a positive existence. If the index key value index already exists in the tree, an error-eexist is returned. The insert operation returned successfully to 0.
The following pair of functions prevent the insert operation from failing for situations where the Insert entry operation fails to cause serious problems:
int Radix_tree_preload (gfp_t gfp_mask);
void Radix_tree_preload_end (void);
The function Radix_tree_preload attempts to allocate enough memory with the given gfp_mask to ensure that the next insert operation does not fail. This function is called before the insert operation function is called, and the allocated structure is stored in each CPU variable. After the function radix_tree_preload operation succeeds, the kernel preemption is completed. Therefore, after the insert operation is complete, the user should call the function radix_tree_preload_end to open the kernel preemption.
vi. deletion of entries
void *radix_tree_delete (struct radix_tree_root *root, unsigned long index)
The function Radix_tree_delete deletes the entry associated with index key value index, returns a pointer to the entry if the entry is deleted in the tree, otherwise returns NULL.
vii. Query Entries
/* Find the entry for the specified key value in the tree, look for a successful, return pointer to the entry, otherwise, return null*/
void *radix_tree_lookup (struct radix_tree_root *root, unsigned long index);
/* Returns a pointer to the slot containing a pointer to the Find entry */
void **radix_tree_lookup_slot (struct radix_tree_root *root, unsigned long index);
/* Multi-key lookup, Max_items is the number of items that need to be looked up, results represents the query result. Index of key value at query start from First_index */
Radix_tree_gang_lookup (struct radix_tree_root *root, void **results, unsigned long first_index, unsigned int max_items);

Eight, label Operation
/* Sets the entry for the key value index to tag tag, and returns the entry for the set label */
void *radix_tree_tag_set (struct radix_tree_root *root, unsigned long index, unsigned int tag);
/* Clears the tag tag from the entry of the key value index and returns the entry with the clear label */
void *radix_tree_tag_clear (struct radix_tree_root *root, unsigned long index, unsigned int tag);
/* Check that the key value index corresponds to the entry tag is set. The tag parameter is either 0 or 1, indicating the dirty bit or WB bit
Returns 0 if the key value does not exist, if the key value exists but the label is not set, returns-1 if the key value exists, and the label is set, returns 1*/
int radix_tree_tag_get (struct radix_tree_root *root, unsigned long index, unsigned int tag);
/* from First_index the entry with tag value in tree root is returned in results */
unsigned int radix_tree_gang_lookup_tag (struct radix_tree_root *root, void **results, unsigned long first_index, unsigned int max_items, unsigned int tag);
/* If any entries in the tree root use the tag tag, return the key value */
int radix_tree_tagged (struct radix_tree_root *root, unsigned int tag);

Reference http://blog.csdn.net/joker0910/article/details/8250085

Linux kernel radix Tree (one)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.