작성 중
리눅스가 디스크에서 버퍼링 되는 데이터를 위해 free 메모리를 사용하는 것처럼, 프로세스가 사용하는 페이지에 대한 free 메모리가 필요하다. 디스크 파일로 지원되는 페이지와 다르게 이러한 페이지는 추후에 사용될 수 있기 때문에 삭제되면 안 된다. 그래서 이러한 페이지들은 백업 스토리지에 복사되는 대신에, swap area에 복사되어야 한다.
스왑 공간이 필요한 두 가지 이유가 있다.
페이지 폴트 처리를 통해 주소 지정된 메모리 양이 RAM을 초과할 수 있다. 메모리가 충분하면 스왑이 불필요하겠지만, 프로세스 수명 초기에 참조한 페이지의 상당수는 초기화만 사용된 다음 다시는 사용되지 않을 수 있다. 따라서 해당 페이지를 교체하고 사용하지 않고 상주하는 것보다 더 많은 디스크 버퍼를 만드는 것이 좋다.
디스크는 매우 느린데, 프로세스가 많은 양의 메모리를 자주 다루게 되면 더 많은 RAM만이 합리적인 수행 시간을 수행할 수 있을 것이다. 이것이 올바른 페이지 교체가 중요한 이유이며 관련 페이지를 스왑 공간에 함께 저장하여 프리페칭 하도록 하는 이유이다.
각 활성 스왑 영역은 파일이나 파티션에 관계 없이 swap_info_struct
를 구성하고 있다. 수행 중인 시스템의 스왑 영역은 MAX_SWAPFILES
길이(32)로 static하게 선언된 배열인 swap_info
에 저장되며, 이것은 32개의 스왑 영역을 가질 수 있다는 뜻이다. swap_info_struct
는 <linux/swap.h>에 다음과 같이 구현되어 있다.
64 struct swap_info_struct {
65 unsigned int flags;
66 kdev_t swap_device;
67 spinlock_t sdev_lock;
68 struct dentry * swap_file;
69 struct vfsmount *swap_vfsmnt;
70 unsigned short * swap_map;
71 unsigned int lowest_bit;
72 unsigned int highest_bit;
73 unsigned int cluster_next;
74 unsigned int cluster_nr;
75 int prio;
76 int pages;
77 unsigned long max;
78 int next;
79 };
SWP_USED
는 활성화 되었다는 뜻이고, SWP_WRITEOK
는 write 연산 작업 준비가 완료됐다는 뜻이다. swap_map
을 주로 보호하는 spin lock, swap_device_lock
및 swap_device_unlock
을 사용/dev/
디렉토리의 파일에 대한 dentry일 수 있다.vfs_mount
objectSWAP_MAP_MAX
인 경우, 슬롯은 영구적으로 할당된다. SWAP_MAP_BAD
인 경우, 슬롯은 사용되지 않는다.-p
플래그를 사용하여 지정할 수도 있다.SWAP_MAP_BAD
로 표시된 슬롯이 계산되지 않는다는 점에서 MAX
와 다르다.swap_info
배열 인덱스.스왑 영역은 배열에 저장되지만 swap_list
라는 pseudo 목록에 유지되며, 이는 <linux/swap.h>에 선언된 매우 간단한 유형이다.
153 struct swap_list_t {
154 int head; /* head of priority-ordered swapfile list */
155 int next; /* swapfile to be used next */
156 };
적절한 영역을 검색할 때는 우선 순위에 따라 영역을 정렬할 수 있지만 필요한 때는 배열에서 빠르게 찾아볼 수 있다.
각 스왑 영역은 디스크의 페이지 사이즈 슬롯으로 나뉘어져 있다. 첫 번째 슬롯은 항상 스왑 영역의 정보를 담으며, 덮어써지지 않는다. 스왑 영역의 첫 1KB는 user-space에서 사용하는 파티션을 위해 디스크의 이름을 저장하는 데 사용한다. 남는 공간은 시스템 프로그램이 mkswap
함수를 통해 스왑 영역을 생성할 때 정보를 저장하는 데 사용된다. 정보는 swap_header
로 채워지며, <linux/swap.h>에 구현되어 있다.
25 union swap_header {
26 struct
27 {
28 char reserved[PAGE_SIZE - 10];
29 char magic[10];
30 } magic;
31 struct
32 {
33 char bootbits[1024];
34 unsigned int version;
35 unsigned int last_page;
36 unsigned int nr_badpages;
37 unsigned int padding[125];
38 unsigned int badpages[1];
39 } info;
40 };
magic
문자열을 식별하는 데 사용. 스왑 영역이 아닌 파티션이 사용될 지 확인하고, 스왑 영역의 버전을 결정한다. SWAP_SPACE
이면 스왑 파일 형식의 버전 1, SWAP_SPACE2
이면 버전 2. MAX_SWAP_BADPAGE
의 인덱스를 저장하는 데 사용.MAX_SWAP_BADPAGES
는 구조가 바뀌면 변하는 컴파일 타임 상수이지만, 단순 방정식에 의해 주어진 현재 형태의 637개 항목이다.
MAX_SWAP_BADPAGES = (PAGE_SIZE - 1024 - 512 - 10) / sizeof(long)
1024는 bootclock이고, 512는 패딩 사이즈이며, 10은 magic string 길이이다.
페이지가 스왑 아웃 되면, 리눅스는 디스크에 페이지를 위치시키는 정보를 충분히 저장하기 위해 PTE
를 사용한다. PTE
는 페이지가 위치한 디스크를 저장하는 데에 충분하지 않으나, swap_info
배열에 인덱스를 저장하고 swap_map
내의 오프셋을 저장하는 데 충분하다.
아키텍처와 상관없이, 각 PTE
는 swp_entry_t
를 저장하기에 충분하며, 이는 <linux/shmem_fs.h>에 구현되어 있다.
16 typedef struct {
17 unsigned long val;
18 } swp_entry_t;
PTE
를 swap_entry_t
로 변환하기 위해 두 가지 매크로가 사용된다. pte_to_swp_entry()
, swp_entry_to_pte()
각 아키텍처는 PTE
가 스왑아웃 됐는지 결정할 수 있다. 아래 그림에서 x86 시스템에서 이것이 어떻게 구현됐는지 보여준다. swp_entry_t
에서 두 비트가 항상 유휴하게 존재한다. x86에서 0 비트는 _PAGE_PRESENT
플래그이고, 7 비트는 _PAGE_PROTNONE
이다. 1~6 비트는 swp_type()
매크로에서 반환되는 swap_info
배열 내의 인덱스인 유형에 대한 것이다.
8~31 비트는 swp_entry_t
의 swap_map
내에 오프셋을 저장하는 데 사용한다. x86에서는 24비트를 사용할 수 있으며, 스왑 영역의 크기를 64GB로 제한한다. swp_offset
매크로는 오프셋을 추출하는 데 사용된다. type과 offset을 swp_entry_t
로 인코딩하기 위해서는 swp_entry()
매크로를 사용할 수 있으며, 단순히 관련 비트를 이동시키는 연산을 수행한다.
![swp_entry_t](C:\Users\choi\OneDrive - UNIST\바탕 화면\CS\Linux\swp_entry_t.png)
32비트 아키텍처에서 type
을 위한 6비트는 MAX_SWAPFILES
의 제한인 32비트 대신 최대 64개의 스왑 영역이 존재하도록 허용해야 한다. 이 제한은 vmalloc
주소 공간의 사용으로 인해 발생한다. 스왑 영역이 가능한 최대인 경우, swap_map
에 32MB가 필요하다. 각 페이지는 참조 카운트에 대해 하나의 짧은 시간을 사용한다. MAX_SWAPFILES
최대 스왑 영역 수만 존재하려면 사용자/커널 선형 주소 공간 분할로 인해 불가능한 1GB 가상 malloc
공간이 필요하다.
모든 페이지 크기의 슬롯은 unsigned short
타입의 배열인 swap_info_struct->swap_map
에 의해 추적된다. 각 엔트리는 공유 페이지 케이스에서 발생하는 슬롯의 사용자 수에 대한 참조 횟수이고 비어있으면 0이다. SWAP_MAP_MAX
인 경우 해당 슬롯은 영구적으로 할당된다. 이것은 참조 카운트가 오버플로우 되지 않도록 하기 위해 존재하며, SWAP_MAP_BAD
인 경우 슬롯을 사용할 수 없다.
스왑 슬롯을 찾고 할당하는 일은 두 단계로 이루어져 있다.
get_swap_page()
: high level function에서 수행되며, swap_list->next
로 시작하여 적절한 슬롯을 스왑 영역에서 찾는다. 슬롯을 찾으면, 다음에 사용될 스왑 영역을 기록하고 할당된 엔트리를 반환한다.scan_swap_map()
: 맵을 찾아보는 일은 이 함수가 수행한다. 유휴 슬롯을 찾기 위해 배열을 선형 탐색하고 반환한다.리눅스는 SWAPFILE_CLUSTER
크기의 디스크 클러스터로 페이지를 조직화하려 한다. 페이지의 SWAPFILE_CLUSTER
수를 swap_info_struct->cluster_nr
에 순차적으로 할당된 페이지의 수를 유지하도록 순차적으로 할당하고, 현재 오프셋을 swap_info_struct->cluster_next
에 기록한다.
스왑 영역에서 충분히 큰 사용 가능한 클러스터를 찾을 수 없는 경우 swap_info_swap→swap_bit에서 시작하는 간단한 1차 무료 검색이 수행됩니다. 목적은 서로 교환된 페이지들이 서로 연관되어 있다는 전제하에 동시에 서로 교환된 페이지들을 서로 가깝게 하는 것이다. 언뜻 이상해 보이는 이 전제는 페이지 교환 알고리즘이 페이지 교환을 선형적으로 스캔할 때 스왑 공간을 가장 많이 사용한다는 점을 고려할 때 상당히 견고하다. 큰 빈 블록을 검색하여 사용하지 않으면 검색 결과가 첫 번째 빈 검색으로 변질되어 전혀 개선되지 않을 수 있다. 이를 통해 프로세스를 종료하면 큰 블록의 슬롯을 확보할 수 있다.
언급한 바와 같이 페이지를 참조하는 모든 PTE에 매핑할 수 있는 빠른 방법이 없기 때문에 많은 프로세스 간에 공유되는 페이지는 쉽게 스왑할 수 없다. 이로 인해 한 PTE에 대한 페이지가 존재하고 다른 PTE로 스왑 아웃된 페이지가 디스크에 동기화되지 않고 업데이트되어 업데이트가 손실되는 경합 상태가 발생한다.
이 문제를 해결하기 위해 백업 스토리지에 예약된 슬롯이 있는 공유 페이지는 스왑 캐시의 일부로 간주된다. 스왑 캐시는 단순히 페이지 캐시의 전문화이기 때문에 순수하게 개념적이다. 페이지 캐시가 아닌 스왑 캐시에 있는 페이지 간의 첫 번째 주요 차이점은 스왑 캐시에 있는 페이지는 항상 page→message의 address_space로 swapper_space를 사용한다는 것이다. 두 번째 차이점은 페이지가 add_to_page_cache() 대신 add_to_swap_cache()를 사용하여 스왑 캐시에 추가된다는 점이다.
<그림>
익명 페이지는 스왑 아웃을 시도할 때까지 스왑 캐시의 일부가 아니다. 변수 swapper_space
는 swap_state.c에서 다음과 같이 선언된다.
39 struct address_space swapper_space = {
40 LIST_HEAD_INIT(swapper_space.clean_pages),
41 LIST_HEAD_INIT(swapper_space.dirty_pages),
42 LIST_HEAD_INIT(swapper_space.locked_pages),
43 0,
44 &swap_aops,
45 };
PageSwapCache()
매크로에서 테스트되는 page→syspace 필드가 swapper_space로 설정되면 페이지가 스왑 캐시의 일부로 식별됩니다. 리눅스는 스왑과 메모리 사이의 페이지를 동기화하기 위해 파일 백업 페이지와 메모리를 동기화하기 위해 사용하는 것과 정확히 동일한 코드를 사용한다.
스토리지를 백업하기 위한 주소 공간인 swapper_space는 address_space→a_ops에 swap_ops를 사용합니다. 그런 다음 page→index 필드는 일반적인 목적인 파일 오프셋 대신 swp_entry_t 구조를 저장하는 데 사용됩니다. address_space_operations struct swap_aops는 swap_state.c에서 다음과 같이 선언됩니다.
34 static struct address_space_operations swap_aops = {
35 writepage: swap_writepage,
36 sync_page: block_sync_page,
37 };
페이지를 스왑 캐시에 추가할 때 슬롯은 get_swap_page()로 할당되고 add_to_swap_cache()로 페이지 캐시에 추가된 다음 더티로 표시됩니다. 다음 번에 페이지를 세탁하면 일반 페이지 캐시가 작동하는 것처럼 실제로 디스크의 백업 스토리지에 기록됩니다. 이 프로세스는 그림 11.4에 설명되어 있습니다.
<그림>
공유 PTE에서 페이지를 이후에 스와핑하면 swap_duplicate()로 호출되어 swap_map의 슬롯에 대한 참조가 증가합니다. 쓰기 결과로 PTE가 하드웨어에 의해 더티로 표시되면 비트는 지워지고 구조 페이지는 set_page_dirty()로 더티로 표시되므로 페이지가 삭제되기 전에 디스크 상의 복사본이 동기화됩니다. 이렇게 하면 페이지에 대한 모든 참조가 삭제될 때까지 디스크의 데이터가 페이지 프레임의 데이터와 일치하는지 확인할 수 있습니다.
페이지에 대한 참조 카운트가 마침내 0에 도달하면 페이지를 페이지 캐시에서 삭제할 수 있으며 스왑 맵 카운트는 슬롯이 너무 일찍 해제되지 않도록 디스크 슬롯이 속한 PTE의 수를 갖습니다. 10장에서 설명한 것과 동일한 LRU 에이징 및 로직으로 세척하고 최종적으로 폐기한다.
반면에 "swap out" 페이지에 대해 페이지 장애가 발생하면 do_swap_page()의 로직은 lookup_swap_cache()를 호출하여 페이지가 스왑 캐시에 존재하는지 확인합니다. 이 경우 PTE가 페이지 프레임을 가리키도록 업데이트되고 페이지 참조 카운트가 증가하고 스왑 슬롯이 swap_free()로 감소합니다.
swp_entry_t get_swap_page()
This function allocates a slot in a swap_map
by searching active swap areas. This is covered in greater detail in Section [11.3](https://www.kernel.org/doc/gorman/html/understand/understand014.html#sec: Allocating a swap slot) but included here as it is principally used in conjunction with the swap cacheint add_to_swap_cache(struct page *page, swp_entry_t entry)
This function adds a page to the swap cache. It first checks if it already exists by calling swap_duplicate()
and if not, is adds it to the swap cache via the normal page cache interface functionadd_to_page_cache_unique()
struct page * lookup_swap_cache(swp_entry_t entry)
This searches the swap cache and returns the struct page
corresponding to the suppliedentry
. It works by searching the normal page cache based onswapper_space
and theswap_map
offsetint swap_duplicate(swp_entry_t entry)
This function verifies a swap entry is valid and if so, increments its swap map count void swap_free(swp_entry_t entry)
The complement function to swap_duplicate()
. It decrements the relevant counter in theswap_map
. When the count reaches zero, the slot is effectively free
페이지에서 읽을 때 사용되는 주요 함수는 read_swap_cache_async()
이며 주로 페이지 장애 시 호출됩니다. 함수는 find_get_page()
를 사용하여 스왑 캐시 검색을 시작합니다. 일반적으로 스왑 캐시 검색은 lookup_swap_cache()
에 의해 수행되지만 이 함수는 수행된 검색 수에 대한 통계를 업데이트하며 캐시를 여러 번 검색해야 할 수 있으므로 대신 find_get_page()
가 사용됩니다.
<그림>
다른 프로세스가 동일한 페이지를 매핑했거나 동시에 여러 프로세스가 동일한 페이지에서 오류를 발생시키는 경우 페이지가 스왑 캐시에 이미 존재할 수 있습니다. 페이지가 스왑 캐시에 없으면 페이지를 할당하고 백업 스토리지의 데이터로 채워야 합니다.
페이지가 alloc_page()
로 할당되면 스왑 캐시의 페이지에서만 스왑 캐시 작업을 수행할 수 있으므로 add_to_swap_cache()
로 스왑 캐시에 추가됩니다. 페이지를 스왑 캐시에 추가할 수 없는 경우 스왑 캐시를 다시 검색하여 다른 프로세스가 데이터를 스왑 캐시에 아직 넣지 않았는지 확인합니다.
백업 스토리지에서 정보를 읽기 위해 rw_swap_page()
가 호출되며, 이는 섹션 11.7에서 논의됩니다. 함수가 완료되면 page_cache_release()
를 호출하여 find_get_page()
에서 가져온 페이지에 대한 참조를 삭제합니다.
디스크에 페이지를 쓸 때 address_space→a_ops
를 참조하여 적절한 쓰기 기능을 찾습니다. 스토리지를 백업하는 경우 address_space
는 swapper_space
이고 스왑 작업은 swap_aops
에 포함됩니다. swap_aops
구조체는 쓰기 함수로 swap_writepage()
를 등록한다.
<그림>
swap_writepage() 함수는 쓰기 프로세스가 스왑 캐시 페이지의 마지막 사용자인지 여부에 따라 다르게 동작합니다. remove_exclusive_swap_page()를 호출하여 페이지를 사용하는 다른 프로세스가 있는지 확인합니다. 이것은 페이지 cache_lock을 누른 상태에서 페이지 수를 검사하는 간단한 경우입니다. 다른 프로세스가 페이지를 매핑하지 않으면 스왑 캐시에서 제거되고 해제됩니다.
remove_exclusive_swap_page()가 스왑 캐시에서 페이지를 제거하고 해제하면 swap_writepage()가 더 이상 사용되지 않으므로 페이지의 잠금을 해제합니다. 스왑 캐시에 여전히 존재하는 경우 rw_swap_page()를 호출하여 데이터를 백업 스토리지에 씁니다.
스왑 영역에 대한 읽기 및 쓰기를 위한 최상위 함수는 rw_swap_page()입니다. 이 기능은 모든 작업이 스왑 캐시를 통해 수행되어 업데이트 손실을 방지합니다. rw_page_base는 실제 작업을 수행하는 핵심 함수입니다.
작업이 읽기인지 확인하는 것으로 시작합니다. 데이터 입력에 IO가 필요한 경우 페이지가 최신이 아니므로 ClearPageUpdate()를 사용하여 최신 플래그를 지웁니다. 디스크에서 페이지를 성공적으로 읽으면 이 플래그가 다시 설정됩니다. 그런 다음 get_swaphandle_info()를 호출하여 스왑 파일을 위한 아이노드의 스왑 파티션을 위한 장치를 획득합니다. 이것들은 실제 IO를 수행할 블록 계층에서 필요합니다.
코어 함수는 블록 계층 함수 brw_page()를 사용하여 실제 디스크 IO를 수행하므로 스왑 파티션 또는 파일과 함께 작동할 수 있습니다. 스왑 영역이 파일인 경우 bmap()은 페이지 데이터를 포함하는 파일 시스템의 모든 블록 목록으로 로컬 어레이를 채우는 데 사용됩니다. 파일 시스템은 파일 및 디스크를 저장하는 고유한 방법을 사용할 수 있으며 디스크에 직접 정보를 쓸 수 있는 스왑 파티션만큼 간단하지 않습니다. 백업 스토리지가 파티션인 경우 한 페이지 크기의 블록만 IO를 필요로 하며 관련된 파일 시스템이 없으므로 bmap()은 필요하지 않습니다.
읽거나 써야 하는 블록이 알려지면 brw_page()를 사용하여 일반적인 블록 IO 작업이 수행됩니다. 수행되는 IO는 모두 비동기이므로 기능이 빠르게 돌아갑니다. IO가 완료되면 블록 계층이 페이지를 잠금 해제하고 대기 프로세스가 시작됩니다.
이제 스왑 영역이 무엇인지, 스왑 영역이 어떻게 표현되고 페이지가 어떻게 추적되는지 살펴보았으므로, 영역을 활성화하기 위해 모든 영역이 어떻게 연계되는지 살펴봐야 할 때입니다. 영역을 활성화하는 것은 개념적으로 매우 간단합니다. 파일을 열고 디스크에서 헤더 정보를 로드한 후 swap_info_struct를 채우고 스왑 목록에 추가합니다.
스왑 영역의 활성화를 담당하는 함수는 sys_swapon()이며, 두 개의 매개 변수, 즉 스왑 영역의 특수 파일에 대한 경로와 플래그 집합이 필요합니다. 스왑이 활성화된 동안에는 BKL(Big Kernel Lock)이 유지되어 이 작업이 수행되는 동안 응용 프로그램이 커널 공간에 들어가는 것을 방지합니다. 이 기능은 매우 크지만 다음과 같은 간단한 단계로 나눌 수 있습니다.
swap_info 어레이에서 사용 가능한 swap_info_struct를 찾아 기본값으로 초기화합니다.
제공된 특수 파일에 대한 디렉토리 트리를 가로지르는 user_path_walk()를 호출하고 파일의 사용 가능한 데이터(예: 항목 및 저장 위치에 대한 파일 시스템 정보)로 namidata 구조를 채웁니다(vfsmount).
스왑 영역의 치수 및 찾는 방법과 관련된 swap_info_struct 필드를 채웁니다. 스왑 영역이 파티션인 경우 크기를 계산하기 전에 블록 크기가 PAGE_SIZE로 구성됩니다. 파일일 경우, 정보는 inode에서 직접 가져옵니다.
영역이 아직 활성화되지 않았는지 확인합니다. 그렇지 않은 경우 메모리에서 페이지를 할당하고 스왑 영역에서 첫 번째 페이지 크기 슬롯을 읽습니다. 이 페이지에는 양호한 슬롯 수 및 swap_info_slots→slots_map을 잘못된 항목으로 채우는 방법과 같은 정보가 포함되어 있습니다.
swap_info_swap→swap_map에 대해 vmalloc를 사용하여 메모리를 할당하고 양호한 슬롯에 대해서는 각 항목을 0으로 초기화하며 그렇지 않으면 SWAP_MAP_BAD를 초기화합니다. x863과 같이 페이지 크기가 4KiB인 아키텍처의 경우 버전 1이 128MiB 미만의 영역만 스왑할 수 있었기 때문에 헤더 정보는 버전 2 파일 형식이 되는 것이 이상적입니다.
헤더에 표시된 정보가 실제 스왑 영역과 일치하는지 확인한 후 swap_info_struct에 최대 페이지 수 및 사용 가능한 정상 페이지와 같은 나머지 정보를 입력합니다. nr_swap_pages 및 total_swap_pages에 대한 글로벌 통계 업데이트
이제 스왑 영역이 완전히 활성화되고 초기화되므로 새로 활성화된 영역의 우선 순위에 따라 올바른 위치에 스왑 목록에 삽입됩니다.
기능이 끝나면 BKL이 해제되고 시스템은 페이징에 사용할 수 있는 새 스왑 영역을 갖게 됩니다.
스왑 영역을 활성화하는 것과 비교할 때 비활성화에는 엄청난 비용이 듭니다. 주요 문제는 영역을 간단히 제거할 수 없다는 것입니다. 이제 스왑 아웃된 모든 페이지를 다시 스왑 인해야 합니다. 구조 페이지를 참조하는 모든 PTE에 신속하게 매핑할 수 없는 것처럼 스왑 항목을 PTE에 매핑할 수 있는 빠른 방법도 없습니다. 이렇게 하려면 비활성화할 스왑 영역을 참조하고 스왑 인하는 PTE를 찾기 위해 모든 프로세스 페이지 테이블을 이동해야 합니다. 이는 물론 물리적 메모리를 사용할 수 없는 경우 스왑 비활성화 작업이 실패한다는 것을 의미합니다.
영역을 비활성화하는 함수는 충분히 예측 가능한 sys_swapoff()라고 불린다. 이 함수는 주로 swap_info_struct 업데이트와 관련이 있습니다. 페이지 아웃된 각 페이지에서 페이징하는 주요 작업은 매우 비싼 try_to_unuse()의 책임이다. swap_map에 사용된 각 슬롯에 대해 프로세스의 페이지 테이블을 탐색하여 검색해야 합니다. 최악의 경우, 모든 mm_structs에 속하는 모든 페이지 테이블을 넘어야 할 수도 있다. 따라서 지역을 비활성화하기 위해 취해야 할 과제는 대체로 다음과 같다.
user_path_walk()
to acquire the information about the special file to be deactivated and then take the BKLswap_info_struct
from the swap list and update the global statistics on the number of swap pages available (nr_swap_pages
) and the total number of swap entries (total_swap_pages
. Once this is acquired, the BKL can be released againread_swap_cache_async()
to allocate a page for the slot saved on disk. Ideally it exists in the swap cache already but the page allocator will be called if it is notunuse_process()
for every process that has a PTE referencing the page. This function traverses the page table searching for the relevant PTE and then updates it to point to the struct page
. If the page is a shared memory page with no remaining reference, shmem_unuse()
is called insteadtry_to_swap_out()
referencing a page in the event it still somehow has a reference in swap mapswap_info_struct
is placed into an uninitialised state and the swap_map
memory freed with vfree()