[内核文档] PAT(页面属性表Page Attribute Table)

PAT(页面属性表Page Attribute Table

 

         X86的页面属性表(PAT)能够在页面级的粒度上设置内存属性。PAT是对MTRR的补充,通过MTRR可以为物理地址区域设置内存类型。但是PATMTRR更灵活,因为它可以在页面级别设置属性,而且硬件上也不限制属性设置的数量。PAT相当灵活,即使多个虚拟内存地址映射到同一个物理内存地址,也不会引起内存类型的冲突。

         通过PAT能够设置多种类型的内存属性,其中最常用的有4种:写回(Write-back),不缓存(Uncached),写联合(Write-combined)以及Uncached Minus

 

PAT APIs

内核中提供了很多能够在页面级设置内存属性的API。为了避免混淆,需要小心地使用这些接口。下表中列出了这些接口、它们的功能以及它们与内存属性的关系。这些API都使用reserve_memtype()/free_memtype()接口来操作物理地址区域,以避免冲突。

API

RAM

ACPI,...

Reserved/Holes

ioremap

--

UC-

UC-

ioremap_cache

--

WB

WB

ioremap_nocache

--

UC-

UC-

ioremap_wc

--

--

WC

set_memory_uc

set_memory_wb

UC-

--

--

set_memory_wc

set_memory_wb

WC

--

--

pci sysfs resource

--

--

UC-

pci sysfs resource_wc

is IORESOURCE_PREFETCH

--

--

WC

pci proc

!PCIIOC_WRITE_COMBINE

--

--

UC-

pci proc

PCIIOC_WRITE_COMBINE

--

--

WC

/dev/mem

read-write

--

WB/WC/UC-

WB/WC/UC-

/dev/mem

mmap SYNC flag

--

UC-

UC-

/dev/mem

mmap !SYNC flag

and

any alias to this area

--

WB/WC/UC-

(from existing alias)

WB/WC/UC-

(from existing alias)

/dev/mem

mmap !SYNC flag

no alias to this area

and

MTRR says WB

--

WB

WB

/dev/mem

mmap !SYNC flag

no alias to this area

and

MTRR says !WB

--

--

UC-

 

针对设备驱动的高级APIs

A. 如果要将页面导出到用户空间,可以使用接口remap_pfn_range io_remap_pfn_range,vm_insert_pfn

在驱动程序中,有时会希望将一些页面导出到用户空间。此时可以使用mmap接口与下列函数的组合。

1)       pgprot_noncached()

2)       io_remap_pfn_range() remap_pfn_range() vm_insert_pfn()

PAT的支持下,Linux引入了一个新的APIpgprot_writecombine。因此,驱动能够持续地使用上述操作序列。首先,在步骤1调用pgprot_noncached()pgprot_writecombine()。然后在采取步骤二。

步骤二为了确保不会产生映射冲突,将跟踪内存类型列表中那些标记为UCWC的区域。

需要指出的是,这组API仅仅对IO地址空间有效,对RAM则无效。如果驱动程序希望导出一个RAM区域,则需在步骤1之前再执行一个步骤0,即调用set_memory_uc()set_memory_wc(),同时也需要跟踪那些页面的使用情况,在页面被释放到空闲池之前调用函数set_memory_wb()

 

注意:

         上面表格中的“--”符号表示“不推荐使用此API”。其中一些是内核严格规定不能使用的。其它一些,虽然目前没有这么严格的限制,但是将来有可能会出现这样的情况。

         对于通过/sys/proc进行的ioremappci访问,如果在被访问的地址上存在冲突,将返回一个较为严格的内存类型。比如:如果已经存在了uncached映射,那么操作ioremap_wc()会返回uncached映射而不是申请的write-combine

         set_memory_[uc|wc]set_memory_wb需要成对的使用,此时,驱动将首先申请一个ucwc区域,在使用之后,再将该区域切换为wb

         /proc/mtrr的操作已经不再被推荐了,取而代之,可以使用基于PAT的接口。

         驱动程序可以使用ioremap_[uc|wc]访问PCI BARs,相应的访问类型为[uc|wc]

         驱动程序可以使用set_memory_[uc|wc]RAM区域设置访存类型。

 

PAT调试

         如果使能了CONFIG_DEBUG_FS选项,仅能够通过下面的方式检查PAT的内存类型列表。

# mount -t debugfs debugfs /sys/kernel/debug

# cat /sys/kernel/debug/x86/pat_memtype_list

PAT memtype list:

uncached-minus @ 0x7fadf000-0x7fae0000

uncached-minus @ 0x7fb19000-0x7fb1a000

uncached-minus @ 0x7fb1a000-0x7fb1b000

uncached-minus @ 0x7fb1b000-0x7fb1c000

uncached-minus @ 0x7fb1c000-0x7fb1d000

uncached-minus @ 0x7fb1d000-0x7fb1e000

uncached-minus @ 0x7fb1e000-0x7fb25000

uncached-minus @ 0x7fb25000-0x7fb26000

uncached-minus @ 0x7fb26000-0x7fb27000

uncached-minus @ 0x7fb27000-0x7fb28000

uncached-minus @ 0x7fb28000-0x7fb2e000

uncached-minus @ 0x7fb2e000-0x7fb2f000

uncached-minus @ 0x7fb2f000-0x7fb30000

uncached-minus @ 0x7fb31000-0x7fb32000

uncached-minus @ 0x80000000-0x90000000

         这个列表说明了物理地址区域以及访问这些区域的PAT设置。

         另外,通过内核启动选项“debugpat”可以获取更加详细的PAT调试信息。设置此参数后,各种调试信息将打印在dmesg日志中。

阅读更多

没有更多推荐了,返回首页