Linux partner System (V)-implement anti-fragmentation through migration type grouping

Source: Internet
Author: User

Related links:
Linux partner System (1) -- Partner System Overview (2) -- Partner system initialization http://www.bkjia.com/ OS /201206/135691.html#linux System (3) -- allocate quota (4) -- release page http://www.bkjia.com/ OS /201206/134247.html linux introduces the concept of the migration type (migrate type) in the partner management system to avoid fragmentation during the long-term operation of the system. Some concepts about migration types were mentioned when introducing the data structure of the partner system (see <Linux partner system (I)>). However, considering the complexity of migration, therefore, how the migration type works is not described during parsing the assignment page. Here, we take this part for analysis separately. Before analyzing the specific code, let's talk about why the migration type should be introduced. We all know that the partner system is designed to solve the problem of external fragmentation. Why should we introduce this concept to avoid fragmentation? We have noticed that fragments generally refer to small memory segments distributed in the memory. As they have been allocated and inserted into large memory segments, they cannot be allocated large blocks of continuous memory. After the partner system allocates the memory, it needs to recycle it and re-create a large block of memory. In this process, two partner blocks must be created on the basis of idle memory, if one of the partners is not idle, or even one of the pages is not idle, a continuous block of memory cannot be allocated. Let's refer to the previous example to see this problem: in the figure www.2cto.com, if the corresponding page of 15 is idle, the partner system can allocate 16 consecutive page boxes, as the page box 15 is allocated, up to eight consecutive page boxes can be allocated. If this page is recycled back to the partner system, fragments are generated at least during this period of time, and worse, if this page is used to store some permanent kernel data and won't be recycled back, fragments will never be eliminated, this means that the maximum memory block of the page 15 will never be allocated continuously. If the allocated pages are non-movable pages, a memory segment can be used to allocate non-movable pages. Although there are fragments in the memory segment, however, fragments are not distributed to other types of memory. All the memory in the system is marked as movable! That is to say, at first none of the other types have their own memory, and when you want to allocate these types of memory, you must capture part of the removable memory, in this way, other types of memory can be allocated according to the actual situation. Now let's take a look at the partner system allocation page. When the specified migration type has insufficient memory, how does the system [cpp] <span style = "font-size: 12px; ">/* Remove an element from the buddy allocator from the fallback list */static inline struct page * _ rmqueue_fallback (struct zone * zone, int order, int start_migratetype) {struct free_area * area; int current_order; struct page * page; int migratetype, I;/* Find the largest possible block of pages in the other list * // * The large memory block linked list starts to traverse the order, the kernel tends to find a large memory block to meet the allocation */for (current_order = MAX_ORDER-1; current_order> = order; -- current_order) {www.2cto.com for (I = 0; I <MIGRATE_TYPES-1; I ++) {/* traverse the next migration type based on the sequence defined in fallbacks */migratetype = fallbacks [start_migratetype] [I]; /* MIGRATE_RESERVE handled later if necessary */if (migratetype === MIGRATE_RESERVE) continue; area = & (zone-> free_area [current_order]); if (list_empty (& ar Ea-> free_list [migratetype]) continue;/* obtain the first page of the block */page = list_entry (area-> free_list [migratetype]. next, struct page, lru); area-> nr_free --;/** If breaking a large block of pages, move all free * pages to the preferred allocation list. if falling * back for a reclaimable kernel allocation, be more * agressive about taking ownership of free pages * // * pageblock_order defines what the kernel considers as a large block of memory * // * If 1. current Block Is a relatively large block, that is, the order is greater than pageblock_order/2 = 5 or 2. the previously specified migration type can be a recycling page or 3. migration grouping mechanism not enabled */if (unlikely (current_order> = (pageblock_order> 1) | start_migratetype = MIGRATE_RECLAIMABLE | page_group_by_equality_disabled) {unsigned long pages; www.2cto.com/* tries to move the maximum memory block of the current page to the linked list corresponding to the previously specified migration type. Only idle pages will be moved, therefore, the actual number of pages that can be moved may be less than 2 ^ pageblock_order */pages = move_freepages_block (zone, page, start_migratetype);/* Claim Whole block if over half of it is free * // * The number of moved pages is more than half of the size of large memory blocks, modify the migration type of the entire block */if (pages> = (1 <(pageblock_order-1) | page_group_by_equality_disabled) set_pageblock_migratetype (page, start_migratetype); migratetype = start_migratetype ;} /* Remove the page from the freelists */list_del (& page-> lru); rmv_page_order (page ); /* Take ownership for orders> = pageblock_order * // * If current_order is greater than or equal to 10 The migration type of the output part is set to start_migratetype */if (current_order> = pageblock_order) change_pageblock_range (page, current_order, start_migratetype);/* split, if migratetype is changed, the split partner block is added to the new migration type linked list */www.2cto.com expand (zone, page, order, current_order, area, migratetype); trace_mm_page_alloc_extfrag (page, order, current_order, start_migratetype, migratetype); return page ;}} return NULL ;}</span> first we can see unusual The for loop preferentially traverses large memory blocks, that is, allocating large memory blocks preferentially. This seems to be contrary to the principle that the partner system preferentially allocates small memory blocks, but think about this to avoid introducing fragments in the new migration type. How to say it? Now, if the memory of type A is insufficient, ask for assistance from Type B. If only one of the most suitable small blocks is allocated from type B, OK, then we will request to allocate the memory of type A later, you have to seek assistance from B type again. In this way, the memory allocated from in B type will cause scattered fragments in B type memory. If these memories are not released ...... I can't imagine the kernel ...... B may cause fragments introduced by type A to no longer allocate large memory blocks. For this reason, the kernel chooses to allocate the largest block of memory directly to A. You can do whatever you like. It is all in type, as long as the B type is not dragged down, it can be more active when the memory allocated by the request is large or the initial request type is recyclable, that is, I mentioned previously to move the corresponding maximum memory block to the linked list corresponding to the original request type. In my understanding, the condition for judging a relatively large memory type here is to echo the for loop that first traverses large memory blocks, that is to say, if the obtained memory block is a relatively small memory block, it means that the memory type itself does not have a large contiguous memory that can be allocated, so the migration will not be performed. The memory of the recycle type needs to be relocated because, in some cases, the kernel may frequently apply for small memory of the recycle type. When the migrated memory is more than half the size of the large block of memory, the memory will be completely converted into self-owned, that is to say, the page type identification bitmap area corresponding to this large memory area is marked as the memory type originally applied. To sum up, we use a paragraph in <deep into Linux kernel architecture>, "In fact, during startup, there are few situations where removable memory areas are allocated, then the distributor has a high probability of allocating the memory area with the maximum length and converting it from the removable list to the non-removable list. Because the allocated memory area length is the largest, fragments are not introduced to the removable memory. All in all, this approach avoids the distribution of memory allocated by the kernel during startup (which is often not released throughout the system) to the physical memory, this protects other types of memory allocation from fragmentation, which is also one of the most important goals of the page mobility grouping framework, "author vanbreaker

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.