1

My goal is to find out process-id of pages which are being swapped out. The Linux Kernel function swap_writepage() takes a pointer to struct page as a part of formal argument while swapping a page on backing store. All swap-out operations are done by "kswapd" process. I need to find out pid(s) of the processes whose page is passed as argument in the swap_writepage() function. In order to get that, I was able to find all page table entries associated with that page using rmap structures.

How can I get pid from a pte or from struct page? I have used sytemtap to get the value of struct page pointer, received in swap_writepage() function as argument. Also, the pid() function prints the pid of current process running not the pid of process to which that page belongs which always gives kswapd process.

tux3
  • 7,171
  • 6
  • 39
  • 51
  • Note that there is not necessarily a one-to-one mapping. A page being swapped out might "belong" to (i.e. be mapped into) several different processes. IIRC, the kernel does not keep a "this page is attached to these processes" reverse lookup structure, but only "this process has these pages/ranges attached to it"... One of the reasons that deleting a swap area can be horribly inefficient/slow. – twalberg Apr 15 '15 at 16:29

1 Answers1

2

Here is the example of how reverse mapping used in modern Linux (copied from lxr):

1435 static int try_to_unmap_anon(struct page *page, enum ttu_flags flags)
1436 {
1437         struct anon_vma *anon_vma;
1438         struct anon_vma_chain *avc;
1439         int ret = SWAP_AGAIN;
1440 
1441         anon_vma = page_lock_anon_vma(page);
1442         if (!anon_vma)
1443                 return ret;
1444 
1445         list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
1446                 struct vm_area_struct *vma = avc->vma;
1447                 unsigned long address;
1448 
1449                 /*
1450                  * During exec, a temporary VMA is setup and later moved.
1451                  * The VMA is moved under the anon_vma lock but not the
1452                  * page tables leading to a race where migration cannot
1453                  * find the migration ptes. Rather than increasing the
1454                  * locking requirements of exec(), migration skips
1455                  * temporary VMAs until after exec() completes.
1456                  */
1457                 if (PAGE_MIGRATION && (flags & TTU_MIGRATION) &&
1458                                 is_vma_temporary_stack(vma))
1459                         continue;
1460 
1461                 address = vma_address(page, vma);
1462                 if (address == -EFAULT)
1463                         continue;
1464                 ret = try_to_unmap_one(page, vma, address, flags);
1465                 if (ret != SWAP_AGAIN || !page_mapped(page))
1466                         break;
1467         }
1468 
1469         page_unlock_anon_vma(anon_vma);
1470         return ret;
1471 }

This example shows for rmap used for unmapping pages. So each anonymous page in ->mapping field holds anon_vma object. anon_vma holds a list of vma areas page is mapped to. Having vma you have mm, having mm you have a task_struct. that's it. If you have any doubts - here is the illustraction reverse mapping

Daniel P. Bovet, Marco Cesati Understanding Linux Kernel chapter 17.2

Alex Hoppus
  • 3,821
  • 4
  • 28
  • 47