1. introduction
Recently, you have a removal of memory recycling related code, and you find two functions / macros for Page An (Page) and PageSwapBacked (Page). From some information, both have the meaning of anonymous page or non-file page, and there are all kinds of combined uses in the kernel, which further exacerbates my confusion:
What will then appear in what scenarios will appear in the scenario:
PageAnon(page) && PageSwapBacked(page)
!PageAnon(page) && PageSwapBacked(page)
PageAnon(page) && !PageSwapBacked(page)
To understand their meaning, let’s take a look at their implementation details, the only achievements in the code level:
- PageAnon(page)
#define PAGE_MAPPING_ANON 0x1
static __always_inline int PageAnon(struct page *page)
{
page = compound_head(page);
return ((unsigned long)page->mapping & PAGE_MAPPING_ANON) != 0;
}
That is, the function determines whether the bit0 of Page->mapping is set, if it is, PageAnon () returns True.
- PageSwapBacked(page)
PageSwapBacked (Page) is judged whether or not PG_SWAPBACKED setting flag.
2. different combined scenes
2.1 Pageanon (Page) && pageswapBacked (Page) Scene
If a page pageAnon (Page) && PageSwapBacked (Page), this page is a standard anonymous page, which points to the corresponding VMA-> Anon_VMA.
It can be seen from this flowchart below:
The above process is the process of error distribution an anonymous page, and set the pg_swapBacked flag for the newly allocated Page Page Call __setpageswapBacked ().
Then call write_once (page-> mapping, (struct address_space *) anon_vma) to set up-> mapping, so after setting (page-> mapping & page_mapping_anon)! = 0, PageAnon () is TRUE.
2.2 !PageAnon(page) && PageSwapBacked(page)
This scene is the case of Page is Shmem, here in order to compare with the anonymous page, the Page process is also assigned:
This is the process of Shmem’s abnormalities. This process allocates a page and then calls __setpageswapBacked () to set the pg_swapbacked flag;
However, its page-> mapping pointing to the struct adress_space * type inode-> i_mapping, this is a pointer to meet 4 bytes (32-bit) or 8-byte (64-bit) alignment, thus (page-> mapping & page_mapping_anon) == 0, PageAnon () is false.
2.3 PageAnon(page) && !PageSwapBacked(page)
This is a particularly special case, called lazyfree pages, which sets MADV_FREE to the anonymous page via MADVISE ().
About MADV_FREE related situation specific reference: https: //man7.org/linux/man-pages/man2/madvise.2.html
However, it is not one of the states of Pageanon &&! PageSwapBacked (PAGE), but is divided into two phases:
-
Add Page to the LazyFree Cache Link table this_cpu_ptr (& lru_pVecs.lru_lazyfree), as shown in the following flowchart:
-
Clear PG_SWAPBACKED flag
Clear the point of the Lazyfree Pages PG_SWAPBACKED flag:
(1) LazyFree LRU Cache Links Overhead or PageCompound (Page)
(2) Situation of memory tension
Both of these cases call the LRU_LAZYFREE_FN () function to transfer Page on the LazyFree LRU cache table to the LRU linked list.
3. summary
In addition to several analyzes, you can actually refer to the incorporated for pg_swapbacked flags in the include / Linux / page-flaggs.h file:
PG_swapbacked is set when a page uses swap as a backing storage. This are
usually PageAnon or shmem pages but please note that even anonymous pages
might lose their PG_swapbacked flag when they simply can be dropped (e.g. as
a result of MADV_FREE).
Take probably using personal rough English translation: When a Page uses SWAP as a backup storage, you need to set the PG_SWAPBACKED flag. This is usually an anonymous page or a SHMEM page, but it is important to note that even an anonymous page may not set PG_SWAPBACKED (for example, MADV_FREE).