cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

split_page_table_lock.rst (3615B)


      1:Original: Documentation/vm/split_page_table_lock.rst
      2
      3:翻译:
      4
      5 司延腾 Yanteng Si <siyanteng@loongson.cn>
      6
      7:校译:
      8
      9
     10=================================
     11分页表锁(split page table lock)
     12=================================
     13
     14最初,mm->page_table_lock spinlock保护了mm_struct的所有页表。但是这种方
     15法导致了多线程应用程序的缺页异常可扩展性差,因为对锁的争夺很激烈。为了提高可扩
     16展性,我们引入了分页表锁。
     17
     18有了分页表锁,我们就有了单独的每张表锁来顺序化对表的访问。目前,我们对PTE和
     19PMD表使用分页锁。对高层表的访问由mm->page_table_lock保护。
     20
     21有一些辅助工具来锁定/解锁一个表和其他访问器函数:
     22
     23 - pte_offset_map_lock()
     24	映射pte并获取PTE表锁,返回所取锁的指针;
     25 - pte_unmap_unlock()
     26	解锁和解映射PTE表;
     27 - pte_alloc_map_lock()
     28	如果需要的话,分配PTE表并获取锁,如果分配失败,返回已获取的锁的指针
     29	或NULL;
     30 - pte_lockptr()
     31	返回指向PTE表锁的指针;
     32 - pmd_lock()
     33	取得PMD表锁,返回所取锁的指针。
     34 - pmd_lockptr()
     35	返回指向PMD表锁的指针;
     36
     37如果CONFIG_SPLIT_PTLOCK_CPUS(通常为4)小于或等于NR_CPUS,则在编译
     38时启用PTE表的分页表锁。如果分页锁被禁用,所有的表都由mm->page_table_lock
     39来保护。
     40
     41如果PMD表启用了分页锁,并且架构支持它,那么PMD表的分页锁就会被启用(见
     42下文)。
     43
     44Hugetlb 和分页表锁
     45==================
     46
     47Hugetlb可以支持多种页面大小。我们只对PMD级别使用分页锁,但不对PUD使用。
     48
     49Hugetlb特定的辅助函数:
     50
     51 - huge_pte_lock()
     52	对PMD_SIZE页面采取pmd分割锁,否则mm->page_table_lock;
     53 - huge_pte_lockptr()
     54	返回指向表锁的指针。
     55
     56架构对分页表锁的支持
     57====================
     58
     59没有必要特别启用PTE分页表锁:所有需要的东西都由pgtable_pte_page_ctor()
     60和pgtable_pte_page_dtor()完成,它们必须在PTE表分配/释放时被调用。
     61
     62确保架构不使用slab分配器来分配页表:slab使用page->slab_cache来分配其页
     63面。这个区域与page->ptl共享存储。
     64
     65PMD分页锁只有在你有两个以上的页表级别时才有意义。
     66
     67启用PMD分页锁需要在PMD表分配时调用pgtable_pmd_page_ctor(),在释放时调
     68用pgtable_pmd_page_dtor()。
     69
     70分配通常发生在pmd_alloc_one()中,释放发生在pmd_free()和pmd_free_tlb()
     71中,但要确保覆盖所有的PMD表分配/释放路径:即X86_PAE在pgd_alloc()中预先
     72分配一些PMD。
     73
     74一切就绪后,你可以设置CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK。
     75
     76注意:pgtable_pte_page_ctor()和pgtable_pmd_page_ctor()可能失败--必
     77须正确处理。
     78
     79page->ptl
     80=========
     81
     82page->ptl用于访问分割页表锁,其中'page'是包含该表的页面struct page。它
     83与page->private(以及union中的其他几个字段)共享存储。
     84
     85为了避免增加struct page的大小并获得最佳性能,我们使用了一个技巧:
     86
     87 - 如果spinlock_t适合于long,我们使用page->ptr作为spinlock,这样我们
     88   就可以避免间接访问并节省一个缓存行。
     89 - 如果spinlock_t的大小大于long的大小,我们使用page->ptl作为spinlock_t
     90   的指针并动态分配它。这允许在启用DEBUG_SPINLOCK或DEBUG_LOCK_ALLOC的
     91   情况下使用分页锁,但由于间接访问而多花了一个缓存行。
     92
     93PTE表的spinlock_t分配在pgtable_pte_page_ctor()中,PMD表的spinlock_t
     94分配在pgtable_pmd_page_ctor()中。
     95
     96请不要直接访问page->ptl - -使用适当的辅助函数。