Persistent memory support progress
Persistent memory support progress
https://lwn.net/Articles/640113/
By Jonathan Corbet
April 15, 2015 Persistent memory (or non-volatile memory) has a number of nice features: it doesn't lose its contents when power is cycled, it is fast, and it is expected to be available in large quantities. Enabling proper support for this memory in the kernel has been a topic of discussion and development for some years; it was, predictably, an important topic at this year's Linux Storage, Filesystem, and Memory Management Summit. The 4.1 kernel will contain a new driver intended to improve support for persistent memory, but there is still a fair amount of work to be done.
2015년 4월 15일, Persistent memory (혹은 non-volatile memory)은 멋진 기능들을 가지고 있습니다. 전원이 꺼졌다가 켜져도 데이터가 그대로 남아있고, 빠르고, 대용량이기 때문입니다. 커널이 이 메모리를 제대로 지원하도록 구현하기 위해 몇년동안 토론을 해왔고 올해 LSF/MM에서 중요한 이슈중 하나였습니다. 4.1 커널이 persistent memory를 지원하기 위한 새로운 드라이버를 지원한 것입니다만 아직도 해야할 일이 많습니다.
At a first glance, persistent memory looks like normal RAM to the processor, so it might be tempting to simply use it that way. There are, though, some good reasons for not doing that. The performance characteristics of persistent memory are still not quite the same as RAM; in particular, write operations can be slower. Persistent memory may not wear out as quickly as older flash arrays did, but it is still best to avoid rewriting it many times per second, as could happen if it were used as regular memory. And the persistence of persistent memory is a valuable feature to take advantage of in its own right — but, to do so, the relevant software must know which memory ranges in the system are persistent. So persistent memory needs to be treated a bit differently.
간단하게는 persistent memory는 프로세서에게 보통 RAM처럼 보여야 합니다. 그래서 RAM에 접근하듯이 쓸 수 있어야 합니다. 하지만 몇가지 이유 때문에 그렇게 하지 않습니다. 성능이 아직 RAM하고 똑같지 않습니다. 특히 쓰기 동작이 느립니다. PM(persistent memory) 예전 플래시 메모리처럼 수명이 짧지는 않지만 어쨌든 일반 메모리처럼 초당 몇번씩 쓰기 동작을 하지 않아야 합니다. PM의 좋은 특성들을 제대로 활용하기 위해서 소프트웨어가 시스템의 어떤 메모리 영역이 persistent한지를 먼저 알야합니다. 그래서 결국 PM은 약간 다르게 접근되게 됩니다.
The usual approach, at least for a first step, is to separate persistent memory from normal RAM and treat it as if it were a block device. Various drivers implementing this type of access have been circulating for a while now. It appears that this driver from Ross Zwisler will be merged for the 4.1 release. It makes useful reading as it is something close to the simplest possible example of a working block device driver. It takes a region of memory, registers a block device to represent that memory, and implements block read and write operations with memcpy() calls.
일반적인 방법(초기 단계에서)은 보통 RAM 영역과 pm을 분리해서 블럭 장치처럼사용하는 것입니다. 많은 드라이버들이 이런 접근 방식으로 구현되서 배포되고 있습니다. Ross Swisler에서 이런 방식의 드라이버를 구현해서 4.1에 넣었습니다. 이것은 간단한 블럭 장치 드라이버처럼 동작합니다 메모리 영역을 만들고 해당 영영을 표현하는 블럭 장치를 만들어서 memcpy를 이용한 블럭 단위 읽기 쓰기를 구현합니다.
In his pull request to merge this driver, Ingo Molnar noted that a number of features that one might expect, including mmap() and execute-in-place, are not supported yet, and that persistent-memory contents would be copied in the page cache. What Ingo had missed is that the DAX patch set providing direct filesystem access to persistent memory was merged for the 4.0 release. If a DAX-supporting filesystem (ext4 now, XFS soon) is built in a persistent memory region, file I/O will avoid the page cache and operations like mmap() will be properly supported.
Ingo Molnar는 mmap이나 xip등 사람들이 기대할고 있는 많은 기능들이 아직 지원되지 않았다고 말했습니다. 그리고 pm의 내용이 페이지 캐시에도 복사되고 있다는 것도 거론했습니다. Ingo가 놓치고 있는건 DAX 패치를 이용해서 파일시스템이 pm에 직접 접근할 수 있게된게 4.0 부터라는 것입니다. DAX를 지원하는 파일시스템이 pm 영역에 적용된다면 파일 IO가 페이지 캐시를 사용하지 않을 것이고 mmap 연산이 제대로 지원될 것입니다.
That said, there are a few things that still will not work quite as expected. One of those is mlock(), which, as Yigal Korman pointed out, may seem a bit strange: data stored in persistent memory is almost by definition locked in memory. As noted by Kirill Shutemov, though, supporting mlock() is not a simple no-op; the required behavior depends on how the memory mapping was set up in the first place. Private mappings still need copy-on-write semantics, for example. A perhaps weirder case is direct I/O: if a region of persistent memory is mapped into a process's address space, the process cannot perform direct I/O between that region and an ordinary file. There may also be problems with direct memory access (DMA) I/O operations, some network transfers, and the vmsplice() system call, among others.
기대하는 것만큼 제대로 동작하지 않는게 더 있습니다. mlock이 그중 하나입니다. Yigal Korman이 지적한 것처럼 약간 이상하게도 pm에 저장된 데이터는 메모리에서 lock 된것과 거의 같습니다. 그렇지만 Kirill Shutemoy에 따르면 mlock을 그냥 no-op으로 만들 수도 없습니다. 최초에 메모리 맵핑이 어떻게 되었는지에 따라 동작이 달라지기 때문입니다. private 맵핑은 copy-on-write를 필요로 합니다. 더 이상한건 direct io입니다. pm 영역이 프로세스의 주소 공간에 맵핑되어 있을 때 프로세스는 일반 파일과 영역간의 direct io를 실행할 수 없습니다. DMA io 동작에도 문제가 있습니다. 네트워크 전송이나 vmsplice 시스템 콜도 그렇습니다.
Whither struct page?
In almost all cases, the restrictions with persistent memory come down to the lack of page structures for that memory. A page structure represents a page of physical memory in the system memory map; it contains just about everything the kernel knows about that page and how it is being used. See this article for the gory details of what can be found there. These structures are used with many internal kernel APIs that deal with memory. Persistent memory, lacking corresponding page structures, cannot be used with those APIs; as a result, various things don't work with persistent memory.
pm을 사용하지 못하는 대부분의 이유가 충분한 페이지 구조체를 만들 수 없기 때문입니다. 페이지 구조체는 시스템 메모리 맵에 있는 물리 페이지를 나타냅니다. 커널이 페이지에 대해 알아야할 모든 것을 가지고 있고 어떻게 사용되고 있는지를 가지고 있습니다.... 생략...... 이 구조체는 메모리를 다루는 많은 커널 내부 API에서 사용됩니다. pm을 관리하는 페이지 구조체가 없으므로 이런 API에서 사용될 수 없고 결국 많은 것들이 pm을 처리할 수 없게 됩니다.
Kernel developers have hesitated to add persistent memory to the system memory map because persistent-memory arrays are expected to be large — in the terabyte range. With the usual 4KB page size, 1TB of persistent memory would need 256 million page structures which would occupy several gigabytes of RAM. And they do need to be stored in RAM, rather than in the persistent memory itself; page structures can change frequently, so storing them in memory that is subject to wear is not advisable. Rather than dedicate a large chunk of RAM to the tracking of persistent memory, the development community has, so far, chosen to treat that memory as a separate type of device.
커널 개발자들이 pm을 시스템 메모리 맵에 추가하길 망설이는 이유가 pm이 몇 TB까지 커질 수 있기 때문입니다. 보통의 4KB 페이지 크기를 생각하면 1TB의 pm은 256백만개의 페이지 구조체를 필요로 하고 몇 GB의 메모리를 차지하게 됩니다. 그것들을 RAM에 저장할 필요는 없고 pm에 저장할 수 있습니다. 하지만 페이지 구조체는 자주 변경되므로 수명이 짧은 pm에 저장하는 것은 좋지 않습니다. 많은 RAM을 pm 관리에 사용하는 대신에 커뮤니티에서는 아직까진 다른 타입의 장치로 취급하기로 선택했습니다.
At some point, though, a way to lift the limitations around persistent memory will need to be found. There appear to be two points of view on how that might be done. One says that page structures should never be used with persistent memory. The logical consequence of this view is that the kernel interfaces that currently use page structures need to be changed to use something else — page-frame numbers, for example — that works with both RAM and persistent memory. Dan Williams posted a patch removing struct page usage from the block layer in March. It is not for the faint of heart: just over 100 files are touched to make this change. That led to complaints from some developers that getting rid of struct page usage in APIs would involve a lot of high-risk code churn and remove a useful abstraction while not necessarily providing a lot of benefit.
어떻게든 pm의 한계를 극복할 방법이 필요합니다. 두가지의 방향으로 진행되는것 같습니다. 한쪽에서는 페이지 구조체가 pm에는 절대 사용될 수 없다고 말합니다. 이런 관점에서 보면 현재 페이지 구조체를 사용하는 커널 인터페이스들은 페이지 프레임 번호와 같이 뭔가 다른 것을 사용하도록 바껴야만 RAM과 pm에서 사용될 수 있게됩니다. 3월에 Dan Williams가 블럭 레이어에서 struct page를 제거하는 패치를 포스팅했습니다. 100개 이상의 파일이 수정됐습니다. 일부 개발자들은 API에서 struct page를 없애는 것이 장점도 있지만 그에 비해 코드가 위험해지고 추상화가 깨지는 단점이 있다는 불평을 했습니다.
The alternative would be to bite the bullet and add struct page entries for persistent memory regions. Boaz Harrosh posted a patch to that end in August 2014; it works by treating persistent memory as a range of hot-pluggable memory and allocating the memory-map entries at initialization time. The patch is relatively simple, but it does nothing to address the memory-consumption issue.
대안은 pm 영역을 위한 항목을 struct page에 추가하는 것입니다. Boaz Harrosh가 2014년 8월말 올린 패치가 있습니다. pm을 hot-pluggable 메모리의 영역으로 잡고 초기화때 메모리 맵으로 할당합니다. 패치는 비교적 간단하지만 메모리가 과소비되는 이슈를 해결하지는 못합니다.
In the long run, the solution may take the form of something like a page structure that represents a larger chunk of memory. One obvious possibility is to make a version of struct page that refers to a huge page; that has the advantage of using a size that is understood by the processor's memory-management unit and would integrate well with the transparent huge page mechanism. An alternative would be a variable-size extent structure as is used by more recent filesystems. Either way, the changes required would be huge, so this is not something that is going to happen in the near future.
MMU를 활용해서 huge page를 지원하게해서 큰 메모리 영역을 표시하는 방법도 있다. 최근 파일 시스템들에서 사용하는 variable-size extent 구조체를 사용하는 방법도 있다. 둘다 너무 큰 변화를 요구하기 때문에 가까운 시일내에 적용할 수는 없습니다.
What will happen is that persistent memory devices will work on Linux as a storage medium for the major filesystems, providing good performance. There will be some rough edges with specific features that do not work, but most users are unlikely to run into them. With 4.1, the kernel will have a level of support for persistent-memory devices to allow that hardware to be put to good use, and to allow users to start figuring out what they actually want to do with that much fast, persistent storage.
PM 디바이스들이 리눅스에서 주요한 파일시스템들에 대해 스토리지로서 사용이 될때 무슨일이 일어날 것인가, 좋은 성능을 보여줄 것입니다. 특정 요소는 동작하지 않는 다소 거친 면이 존재하지만, 대부분의 유저는 그것들을 동작시키지 않을 것입니다. 4.1에서 커널은 PM 디바이스가 하드웨어를 사용할 수 있는 레벨의 지원을 할 것이고, 이것은 사용자들이 더빠르고, 영속적인 스토리를 통해 그들이 무엇을 하고자 하는지를 허용할 것이다.