Получение pid страниц, которые выгружаются

Моя цель - узнать идентификатор процесса страниц, которые выгружаются. Функция ядра Linux swap_writepage() принимает указатель на страницу структуры как часть формального аргумента при замене страницы в резервном хранилище. Все операции подкачки выполняются процессом "kswapd". Мне нужно узнать pid(s) процессов, страница которых передается в качестве аргумента в функцию swap_writepage(). Чтобы получить это, я смог найти все записи таблицы страниц, связанные с этой страницей, используя структуры rmap.

Как я могу получить pid из pte или из страницы структуры? Я использовал systemtap для получения значения указателя страницы структуры, полученного в функции swap_writepage() в качестве аргумента. Кроме того, функция pid() печатает pid текущего запущенного процесса, а не pid процесса, которому принадлежит эта страница, что всегда дает процесс kswapd.


person Abhinav Site    schedule 15.04.2015    source источник
comment
Обратите внимание, что не обязательно однозначное отображение. Выгружаемая страница может принадлежать (т. е. быть отображена) нескольким различным процессам. IIRC, ядро ​​​​не сохраняет эту страницу, прикрепленную к структуре обратного просмотра этих процессов, но только к этому процессу прикреплены эти страницы / диапазоны ... Одна из причин, по которой удаление области подкачки может быть ужасно неэффективным / медленным.   -  person twalberg    schedule 15.04.2015


Ответы (1)


Вот пример того, как обратное отображение используется в современном Linux (скопировано из 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 }

В этом примере показано, как rmap используется для отмены сопоставления страниц. Таким образом, каждая анонимная страница в поле ->mapping содержит объект anon_vma. anon_vma содержит список областей vma, с которыми сопоставлена ​​страница. Имея vma у вас есть mm, имея mm у вас есть task_struct. это оно. Если есть сомнения - вот иллюстрация reverse mapping

Даниэль П. Бове, Марко Чезати. Понимание ядра Linux, глава 17.2.

person Alex Hoppus    schedule 15.04.2015