- 论坛徽章:
- 11
|
看2.4代码看到, 当分配swap page时, 引用计数为1, 然后将该swap page 信息写入页表时, 引用计数+1, 那就不明白了, 照此而言, 自然是swap in 的时候, 计数减一, 但怎么减也减不到0, 也就是说, 这个swap page再也无法释放了。
static int try_to_swap_out(struct mm_struct * mm, struct vm_area_struct* vma, unsigned long address, pte_t * page_table, int gfp_mask)
39{
40 pte_t pte;
41 swp_entry_t entry;
42 struct page * page;
43 int onlist;
44
45 pte = *page_table;
46 if (!pte_present(pte))
47 goto out_failed;
48 page = pte_page(pte);
49 if ((!VALID_PAGE(page)) || PageReserved(page))
50 goto out_failed;
51
52 if (!mm->swap_cnt)
53 return 1;
54
55 mm->swap_cnt--;
56
57 onlist = PageActive(page);
58 /* Don't look at this pte if it's been accessed recently. */
59 if (ptep_test_and_clear_young(page_table)) {
60 age_page_up(page);
61 goto out_failed;
62 }
63 if (!onlist)
64 /* The page is still mapped, so it can't be freeable... */
65 age_page_down_ageonly(page);
66
67 /*
68 * If the page is in active use by us, or if the page
69 * is in active use by others, don't unmap it or
70 * (worse) start unneeded IO.
71 */
72 if (page->age > 0)
73 goto out_failed;
74
75 if (TryLockPage(page))
76 goto out_failed;
77
78 /* From this point on, the odds are that we're going to
79 * nuke this pte, so read and clear the pte. This hook
80 * is needed on CPUs which update the accessed and dirty
81 * bits in hardware.
82 */
83 pte = ptep_get_and_clear(page_table);
84 flush_tlb_page(vma, address);
85
86 /*
87 * Is the page already in the swap cache? If so, then
88 * we can just drop our reference to it without doing
89 * any IO - it's already up-to-date on disk.
90 *
91 * Return 0, as we didn't actually free any real
92 * memory, and we should just continue our scan.
93 */
94 if (PageSwapCache(page)) {
95 entry.val = page->index;
96 if (pte_dirty(pte))
97 set_page_dirty(page);
98set_swap_pte:
99 swap_duplicate(entry); // swap page 引用计数 +1
100 set_pte(page_table, swp_entry_to_pte(entry));
101drop_pte:
102 UnlockPage(page);
103 mm->rss--;
104 deactivate_page(page);
105 page_cache_release(page);
106out_failed:
107 return 0;
108 }
109
110 /*
111 * Is it a clean page? Then it must be recoverable
112 * by just paging it in again, and we can just drop
113 * it..
114 *
115 * However, this won't actually free any real
116 * memory, as the page will just be in the page cache
117 * somewhere, and as such we should just continue
118 * our scan.
119 *
120 * Basically, this just makes it possible for us to do
121 * some real work in the future in "refill_inactive()".
122 */
123 flush_cache_page(vma, address);
124 if (!pte_dirty(pte))
125 goto drop_pte;
126
127 /*
128 * Ok, it's really dirty. That means that
129 * we should either create a new swap cache
130 * entry for it, or we should write it back
131 * to its own backing store.
132 */
133 if (page->mapping) {
134 set_page_dirty(page);
135 goto drop_pte;
136 }
137
138 /*
139 * This is a dirty, swappable page. First of all,
140 * get a suitable swap entry for it, and make sure
141 * we have the swap cache set up to associate the
142 * page with that swap entry.
143 */
144 entry = get_swap_page(); // swa page 引用计数初始化 1
145 if (!entry.val)
146 goto out_unlock_restore; /* No swap space left */
147
148 /* Add it to the swap cache and mark it dirty */
149 add_to_swap_cache(page, entry);
150 set_page_dirty(page);
151 goto set_swap_pte;
152
153out_unlock_restore:
154 set_pte(page_table, pte);
155 UnlockPage(page);
156 return 0;
157}
158 |
|