Analysis of the upper limit of the SLAB target XuWeiiii (ENTHUSIAST) 02-10-30 17:20 Core 2.4.0 In the memory initialization process included a common buffer initialization KMEM_CACHE_SIZES_INIT (), this function not only creates a cache_sizes [] array designated The 12 buffers also determined the number of SLAB objects of the CFLGS_OFF_SLAB flag, the statement is as follows: if (! (! (! (! (! (! (!)) {OFFSLAB_LIMIT = SIZES-> CS_SIZE-SIZEOF (SLAB_T); OFFSLAB_LIMIT / = 2; } for CFLGS_OFF_SLAB object, size of the structure required to manage sizeof (slab_t) num * sizeof (kmem_bufctl_t) is smaller than the size of the object, therefore sizeof (slab_t) offslab_limit * sizeof (kmem_bufctl_t) <= sizes-> cs_size, there sizeof (KMEM_BUFCTL_T) = 2, so OffsLab_Limit = (Sizes-> CS_SIZE-SIZEOF (SLAB_T)) / 2, this is the upper limit of the number of objects of each cflgs_off_slab of the SLAB. Why is CFLGS_OFF_SLAB's object size must be greater than its management structure size? cachep-> slabp_cache = kmem_find_general_cachep (slab_size, 0) by the kmem_cache_create () statements if (flags & CFLGS_OFF_SLAB); found, the object OFF_SLAB, which slab structure array must kmem_bufctl_t and as an object (referred to as a wish slabp objects) from Select the appropriate to allocation in a common buffer pool, the larger the number of objects in one SLAB, the larger the number of KMEM_BUFCTL_T structures of the management object, and when the number of objects reaches or exceeds OFFSLAB_LIMIT, the size and corresponding management structure of the object in the SLAB The size of the SLABP object is quite. At this time, the SLABP object is definitely OFF_SLAB (judging by object size), and it is possible to manage its SLABP objects or it is quite (if the number of objects does not limit the limit), this generates a dead cycle (ie object The management structure must allocate B objects. The management structure of the B object must be assigned C objects ... no endlessly).
Kernel 2.4.0 In the memory initialization process, the neutral buffer initializes KMEM_CACHE_SIZES_INIT (), which not only creates 12 buffers specified by the cache_sizes [] array, but also determines the number of SLAB objects of the CFLGS_OFF_SLAB flag. First, why is there a limit on the number of SLAB objects of CFLGS_OFF_SLAB? cachep-> slabp_cache = kmem_find_general_cachep (slab_size, 0) by the kmem_cache_create () statements if (flags & CFLGS_OFF_SLAB); found, for CFLGS_OFF_SLAB objects, which slab structure array must kmem_bufctl_t and as an object (referred to as a wish slabp objects) from Select the appropriate to allocation in a common buffer pool, the larger the number of objects in a SLAB, the larger the number of KMEM_BUFCTL_T structures of the management object, and when the number of objects reaches or exceeds OFFSLAB_LIMIT, the size of the SLABP object reaches the standard of cflgs_off_slab, this When the SLABP object is definitely cflgs_off_slab, and the SLABP object that manages it may be cflgs_off_slab (if the number of objects does not limit the limit), this generates a dead loop (ie the management structure of the A object must be assigned B object, B The management structure of the object must be assigned a C object ... no endlessly). Limit OFFSLAB_LIMIT (SIZES-> CS_SIZE-SIZEOF (SLAB_T)) / 2, the management structure of all CFLGS_OFF_SLAB objects will not be cflgs_off_slab, and avoid death cycles. Second, the OFFSLAB_LIMIT value of the OFFSLAB_LIMIT is the statement determined in KMEM_CACHE_SIZES_INIT () as follows: do {... if (! (@Slab (sizes-> cs_cachep))) {OFFSLAB_LIMIT = SIZES-> cs_size-sizeof (SLAB_T) }Lab_limit / = 2;} ...} while (SIZES-> CS_SIZE); By cycling, final implementation is made by the largest object of else! (OFF_SLAB (SIZES-> CS_CACACHEP) to determine why? Because of OFFSLAB_LIMIT value The principle is to ensure that the management structure object of the object of CFLGS_OFF_SLAB is no longer cflgs_off_slab. Since the management structure object is assigned in the general buffer pool, select the match in the general object! (Off_sLab (Sizes-> CS_CACHEP) maximum object To determine offslab_limit. When the number of SLAB objects of CFLGS_OFF_SLAB reaches the upper limit, its management structure object is just in line with it! (OFF_SLAB (SIZES-> CS_CACHEP) size Sizes-> cs_size, ie sizeof (SLAB_T) OFFSLAB_LIMIT * Size (kmem_bufctl_t) = SIZES-> CS_SIZE, because there is SIZEOF (kmem_bufctl_t) = 2, so OffsLab_Limit = (Sizes-> CS_SIZE-SIZEOF (SLAB_T)) / 2 This is the upper limit of the number of objects of each cflgs_off_slab. Core 2.4 .0 In the memory initialization process, the general buffer initializes KMEM_CACHE_SIZES_INIT (), which not only creates 12 buffers specified by the cache_sizes [] array, but also determines the number of SLAB objects of the CFLGS_OFF_SLAB flag.
First, why is there a limit on the number of SLAB objects of CFLGS_OFF_SLAB? cachep-> slabp_cache = kmem_find_general_cachep (slab_size, 0) by the kmem_cache_create () statements if (flags & CFLGS_OFF_SLAB); found, for CFLGS_OFF_SLAB objects, which slab structure array must kmem_bufctl_t and as an object (referred to as a wish slabp objects) from Select the appropriate to allocation in the general buffer pool, the larger the number of objects in one SLAB, the larger the KMEM_BUFCTL_T structure of the management object, and when the number of objects exceeds OFFSLAB_LIMIT, the size of the SLABP object may reach the standard of cflgs_off_slab, this When the SLABP object is cflgs_off_slab, and the SLABP object that manages it may be cflgs_off_slab (if the number of objects does not limit the limit), this generates a dead cycle (ie, the management structure of the A object must allocate B object, B object The management structure must allocate C objects ... no endlessly). Limit OFFSLAB_LIMIT (SIZES-> CS_SIZE-SIZEOF (SLAB_T)) / 2, the management structure of all CFLGS_OFF_SLAB objects will not be cflgs_off_slab, and avoid death cycles. Second, the OFFSLAB_LIMIT value of the OFFSLAB_LIMIT is the statement determined in KMEM_CACHE_SIZES_INIT () as follows: do {... if (! (@Slab (sizes-> cs_cachep))) {OFFSLAB_LIMIT = SIZES-> cs_size-sizeof (SLAB_T) ;} ...} while (SIZES-> CS_SIZE); through the loop, final implementation is in line with the general buffer pool! (OFF_SLAB (SIZES-> CS_CACHEP) to determine OFFSLAB_LIMIT. Why? Because The determination of the OFFSLAB_LIMIT value is to ensure that the management structure object of the object of the CFLGS_OFF_SLAB is no longer cflgs_off_slab. Since the management structure object is selected in the universal buffer pool, it is selected in the general object! (OFF_SLAB (SIZES-> CS_CACHEP The maximum object to determine OffsLab_limit. When the number of SLAB objects of CFLGS_OFF_SLAB reaches the upper limit, its management structure object just meets the match! (SIZES-> CS_CACHEP) size sizes-> cs_size, ie sizeof (SLAB_T) ) offslab_limit * size (kmem_bufctl_t) = sizes-> cs_size, however, because sizeof (kmem_bufctl_t) = 4, so offslab_limit = (sizes-> cs_size-sizeof (slab_t)) / 2 is bugs (because of type unsigned int is kmem_bufctl_t So 4 bytes) should be changed to: OFFSLAB_LIMIT = SIZES-> CS_SIZE-SIZEOF (SLAB_T); OFFSLAB_LIMIT / = SIZEOF (KMEM_BUFCTL_T); this is the upper limit of the number of SLABs of each cflgs_off_slab. Limit.