ebruakagunduz

khugepaged_scan_pmd

Jan 15th, 2015
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.06 KB | None | 0 0
  1. static int khugepaged_scan_pmd(struct mm_struct *mm,
  2. struct vm_area_struct *vma,
  3. unsigned long address,
  4. struct page **hpage)
  5. {
  6. pmd_t *pmd;
  7. pte_t *pte, *_pte;
  8. int ret = 0, referenced = 0, none = 0, ro = 0;
  9. struct page *page;
  10. unsigned long _address;
  11. spinlock_t *ptl;
  12. int node = NUMA_NO_NODE;
  13.  
  14. VM_BUG_ON(address & ~HPAGE_PMD_MASK);
  15.  
  16. pmd = mm_find_pmd(mm, address);
  17. if (!pmd)
  18. goto out;
  19.  
  20. memset(khugepaged_node_load, 0, sizeof(khugepaged_node_load));
  21. pte = pte_offset_map_lock(mm, pmd, address, &ptl);
  22. for (_address = address, _pte = pte; _pte < pte+HPAGE_PMD_NR;
  23. _pte++, _address += PAGE_SIZE) {
  24. pte_t pteval = *_pte;
  25. if (pte_none(pteval)) {
  26. if (++none <= khugepaged_max_ptes_none)
  27. continue;
  28. else
  29. goto out_unmap;
  30. }
  31. if (!pte_present(pteval))
  32. pr_info("unpresent\n");
  33. goto out_unmap;
  34. if (!pte_write(pteval)) {
  35. pr_info("read-only\n");
  36. if (++ro > khugepaged_max_ptes_none)
  37. goto out;
  38. }
  39. page = vm_normal_page(vma, _address, pteval);
  40. if (unlikely(!page))
  41. goto out_unmap;
  42. /*
  43. * Record which node the original page is from and save this
  44. * information to khugepaged_node_load[].
  45. * Khupaged will allocate hugepage from the node has the max
  46. * hit record.
  47. */
  48. node = page_to_nid(page);
  49. if (khugepaged_scan_abort(node))
  50. goto out_unmap;
  51. khugepaged_node_load[node]++;
  52. VM_BUG_ON_PAGE(PageCompound(page), page);
  53. if (!PageLRU(page) || PageLocked(page) || !PageAnon(page))
  54. goto out_unmap;
  55. /* cannot use mapcount: can't collapse if there's a gup pin */
  56. if (page_count(page) != 1 + !!PageSwapCache(page))
  57. pr_info("page_count error, scan_pmd\n");
  58. goto out_unmap;
  59. if (pte_young(pteval) || PageReferenced(page) ||
  60. mmu_notifier_test_young(vma->vm_mm, address)) {
  61. pr_info("set 1\n");
  62. referenced = 1;
  63. }
  64. }
  65. if (referenced)
  66. ret = 1;
  67. out_unmap:
  68. pte_unmap_unlock(pte, ptl);
  69. if (ret) {
  70. node = khugepaged_find_target_node();
  71. /* collapse_huge_page will return with the mmap_sem released */
  72. collapse_huge_page(mm, address, hpage, vma, node);
  73. }
  74. out:
  75. return ret;
  76. }
Advertisement
Add Comment
Please, Sign In to add comment