|
|
DescriptionRe-land: base: Use MADV_REMOVE instead of ftruncate to purge discardable memory segments.
This makes the discardable memory implementation use
madvise(MADV_REMOVE) to tell the kernel to free resources
associated with purged pages. This cleans up the code as
madvise - unlike ftruncate - doesn't require us to keep the
file descriptor open and it has the huge advantage that
discardable memory can be shared between a renderer and
the GPU process.
This also works with Ashmem for which ftrunctate is not
supported.
BUG=543633
TEST=base_unittests --gtest_filter=DiscardableSharedMemoryTest.ZeroFilledPagesAfterPurge, content_unittests --gtest_filter=HostDiscardableSharedMemoryManagerTest.ReduceMemoryAfterSegmentHasBeenDeleted
Committed: https://crrev.com/adfe91aac022080722ba8a24d4de79700dc38da4
Cr-Commit-Position: refs/heads/master@{#355663}
Patch Set 1 #
Total comments: 4
Patch Set 2 : remove unnecessary HANDLE_EINTR #Patch Set 3 : use MADV_REMOVE instead #Patch Set 4 : include DISCARDABLE_SHARED_MEMORY_REMOVE #Patch Set 5 : try MADV_FREE if MADV_REMOVE is missing #Patch Set 6 : how about MADV_DONTNEED? #Patch Set 7 : linux and android only #
Total comments: 2
Patch Set 8 : use MADV_FREE when MADV_REMOVE is missing #Patch Set 9 : add comment explaining the use of MADV_FREE #
Total comments: 6
Patch Set 10 : update comments #
Total comments: 4
Patch Set 11 : better name for define and improved comments #Patch Set 12 : fix problem with segment having been released before we try to purge #
Messages
Total messages: 56 (23 generated)
The CQ bit was checked by reveman@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/1409743002/1 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/1409743002/1
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
reveman@chromium.org changed reviewers: + primiano@chromium.org
LGTM, one doubt from my side: do we ever run into cases where memory is mapped and page-faulted on both browser and child side? If that happens is only one of the two going to madvise? In that case (more that 1 process having faulted on the pages) I think that the madvise will only have the effect of unreferencing pages from one process, but the physical pages will still be there in the pagecache as they are still referenced by another process. In other words, mind that madvise() doesn't have global effect and won't cause eviction if there are other processes referencing (i.e. having actually page faulted) those pages. The good news is that we can see this after ssid's mincore() patch to the discardable dumper, as mincore doesn't report just the referenced pages, but the fact that the mapped paged are resident in the pagecache or not. https://codereview.chromium.org/1409743002/diff/1/base/memory/discardable_sha... File base/memory/discardable_shared_memory.cc (right): https://codereview.chromium.org/1409743002/diff/1/base/memory/discardable_sha... base/memory/discardable_shared_memory.cc:329: if (HANDLE_EINTR(madvise(reinterpret_cast<char*>(shared_memory_.memory()) + madvise shouldn't be interruptible (manpage doesn't mention EINTR), but I guess this won't hurt just in the case somebody makes it interruptible in the future. https://codereview.chromium.org/1409743002/diff/1/base/memory/discardable_sha... base/memory/discardable_shared_memory.cc:331: AlignToPageSize(mapped_size_), MADV_DONTNEED))) { Just doublechecking: isn't mapped_size_ including also the sharedState page? In other words, shouldn't the 2nd argument have -extra_page_due_to_shared_state ?
On 2015/10/16 at 09:31:43, primiano wrote: > LGTM, one doubt from my side: > do we ever run into cases where memory is mapped and page-faulted on both browser and child side? > If that happens is only one of the two going to madvise? > > In that case (more that 1 process having faulted on the pages) I think that the madvise will only have the effect of unreferencing pages from one process, but the physical pages will still be there in the pagecache as they are still referenced by another process. > In other words, mind that madvise() doesn't have global effect and won't cause eviction if there are other processes referencing (i.e. having actually page faulted) those pages. > > The good news is that we can see this after ssid's mincore() patch to the discardable dumper, as mincore doesn't report just the referenced pages, but the fact that the mapped paged are resident in the pagecache or not. > Yes, I'm not sure this actually works. The browser is using madvise but it's only the child process that will page fault on those pages. I'm going to hold off on this until ssid's patch lands and we can check what the actual results are. https://codereview.chromium.org/1409743002/diff/1/base/memory/discardable_sha... File base/memory/discardable_shared_memory.cc (right): https://codereview.chromium.org/1409743002/diff/1/base/memory/discardable_sha... base/memory/discardable_shared_memory.cc:329: if (HANDLE_EINTR(madvise(reinterpret_cast<char*>(shared_memory_.memory()) + On 2015/10/16 at 09:31:43, Primiano Tucci wrote: > madvise shouldn't be interruptible (manpage doesn't mention EINTR), but I guess this won't hurt just in the case somebody makes it interruptible in the future. Good catch. I removed HANDLE_EINTR. https://codereview.chromium.org/1409743002/diff/1/base/memory/discardable_sha... base/memory/discardable_shared_memory.cc:331: AlignToPageSize(mapped_size_), MADV_DONTNEED))) { On 2015/10/16 at 09:31:43, Primiano Tucci wrote: > Just doublechecking: isn't mapped_size_ including also the sharedState page? In other words, shouldn't the 2nd argument have -extra_page_due_to_shared_state ? |mapped_size_| is the size exposed to the user of this class. It doesn't include the shared state page. See l.123.
The CQ bit was checked by reveman@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/1409743002/20001 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/1409743002/20001
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
Description was changed from ========== base: Use MADV_DONTNEED instead of ftruncate to purge discardable memory segments. Use madvise(DONTNEED) to advise the kernel to free resources associated with purged pages. This cleans up the code as madvise, unlike ftruncate, doesn't require us to keep the file descriptor open. This also has the potential to work with Ashmem for which ftrunctate is not supported. BUG=543633 ========== to ========== base: Use MADV_REMOVE instead of ftruncate to purge discardable memory segments. Use madvise(MADV_REMOVE) to advise the kernel to free resources associated with purged pages. This cleans up the code as madvise, unlike ftruncate, doesn't require us to keep the file descriptor open. This also works with Ashmem for which ftrunctate is not supported. BUG=543633 ==========
Description was changed from ========== base: Use MADV_REMOVE instead of ftruncate to purge discardable memory segments. Use madvise(MADV_REMOVE) to advise the kernel to free resources associated with purged pages. This cleans up the code as madvise, unlike ftruncate, doesn't require us to keep the file descriptor open. This also works with Ashmem for which ftrunctate is not supported. BUG=543633 ========== to ========== base: Use MADV_REMOVE instead of ftruncate to purge discardable memory segments. This makes the discardable memory implementation use madvise(MADV_REMOVE) to tell the kernel to free resources associated with purged pages. This cleans up the code as madvise - unlike ftruncate - doesn't require us to keep the file descriptor open. This also works with Ashmem for which ftrunctate is not supported. The downside is that we lose ftrunctate on MacOSX where MADV_REMOVE and similar advice arguments are not supported. This leaves MacOSX in the same situation as Windows where we rely on the child process giving up discardable segments in a reasonable time. BUG=543633 TEST=base_unittests --gtest_filter=DiscardableSharedMemoryTest.ZeroFilledPagesAfterPurge ==========
Description was changed from ========== base: Use MADV_REMOVE instead of ftruncate to purge discardable memory segments. This makes the discardable memory implementation use madvise(MADV_REMOVE) to tell the kernel to free resources associated with purged pages. This cleans up the code as madvise - unlike ftruncate - doesn't require us to keep the file descriptor open. This also works with Ashmem for which ftrunctate is not supported. The downside is that we lose ftrunctate on MacOSX where MADV_REMOVE and similar advice arguments are not supported. This leaves MacOSX in the same situation as Windows where we rely on the child process giving up discardable segments in a reasonable time. BUG=543633 TEST=base_unittests --gtest_filter=DiscardableSharedMemoryTest.ZeroFilledPagesAfterPurge ========== to ========== base: Use MADV_REMOVE instead of ftruncate to purge discardable memory segments. This makes the discardable memory implementation use madvise(MADV_REMOVE) to tell the kernel to free resources associated with purged pages. This cleans up the code as madvise - unlike ftruncate - doesn't require us to keep the file descriptor open and it has the huge advantage that discardable memory can be shared between a renderer and the GPU process. This also works with Ashmem for which ftrunctate is not supported. The downside of this change is that we lose ftrunctate on MacOSX where MADV_REMOVE and similar madvice arguments are not supported. This leaves MacOSX in the same situation as Windows where we rely on the child process giving up discardable segments in a reasonable time. However, by switching to MACH based shared memory on MacOSX we will restore the ability to synchronously free resources associated with purged segments. BUG=543633 TEST=base_unittests --gtest_filter=DiscardableSharedMemoryTest.ZeroFilledPagesAfterPurge ==========
The CQ bit was checked by reveman@chromium.org to run a CQ dry run
reveman@chromium.org changed reviewers: + avi@chromium.org, danakj@chromium.org
+avi for content/ +danakj for base/
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/1409743002/120001 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/1409743002/120001
https://codereview.chromium.org/1409743002/diff/120001/base/memory/discardabl... File base/memory/discardable_shared_memory.cc (right): https://codereview.chromium.org/1409743002/diff/120001/base/memory/discardabl... base/memory/discardable_shared_memory.cc:7: #if defined(OS_POSIX) && !defined(OS_NACL) Why this and not #ifdef DISCARDABLE_SHARED_MEMORY_REMOVE? How come OS_POSIX/OS_NACL is not part of the define of DISCARDABLE_SHARED_MEMORY_REMOVE?
lgtm when danakj is happy
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
Description was changed from ========== base: Use MADV_REMOVE instead of ftruncate to purge discardable memory segments. This makes the discardable memory implementation use madvise(MADV_REMOVE) to tell the kernel to free resources associated with purged pages. This cleans up the code as madvise - unlike ftruncate - doesn't require us to keep the file descriptor open and it has the huge advantage that discardable memory can be shared between a renderer and the GPU process. This also works with Ashmem for which ftrunctate is not supported. The downside of this change is that we lose ftrunctate on MacOSX where MADV_REMOVE and similar madvice arguments are not supported. This leaves MacOSX in the same situation as Windows where we rely on the child process giving up discardable segments in a reasonable time. However, by switching to MACH based shared memory on MacOSX we will restore the ability to synchronously free resources associated with purged segments. BUG=543633 TEST=base_unittests --gtest_filter=DiscardableSharedMemoryTest.ZeroFilledPagesAfterPurge ========== to ========== base: Use MADV_REMOVE instead of ftruncate to purge discardable memory segments. This makes the discardable memory implementation use madvise(MADV_REMOVE) to tell the kernel to free resources associated with purged pages. This cleans up the code as madvise - unlike ftruncate - doesn't require us to keep the file descriptor open and it has the huge advantage that discardable memory can be shared between a renderer and the GPU process. This also works with Ashmem for which ftrunctate is not supported. BUG=543633 TEST=base_unittests --gtest_filter=DiscardableSharedMemoryTest.ZeroFilledPagesAfterPurge ==========
PTAL https://codereview.chromium.org/1409743002/diff/120001/base/memory/discardabl... File base/memory/discardable_shared_memory.cc (right): https://codereview.chromium.org/1409743002/diff/120001/base/memory/discardabl... base/memory/discardable_shared_memory.cc:7: #if defined(OS_POSIX) && !defined(OS_NACL) On 2015/10/19 at 20:03:09, danakj wrote: > Why this and not #ifdef DISCARDABLE_SHARED_MEMORY_REMOVE? > > How come OS_POSIX/OS_NACL is not part of the define of DISCARDABLE_SHARED_MEMORY_REMOVE? Yes, this should have been DISCARDABLE_SHARED_MEMORY_REMOVE in this patch. OS_POSIX/OS_NACL was from an earlier version. After discussing this patch a bit more with primiano I changed it so OS_POSIX/OS_NACL is actually correct here but it's also now what we use below in Purge(). It turns out that on MacOS where MADV_REMOVE is not available, MADV_FREE is available and should be working in a similar way just not providing the guarantee that pages are zero-filled. It means we can't test it but it's still a good idea to use it. Latest patch uses MADV_FREE when MADV_REMOVE is missing.
The CQ bit was checked by reveman@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/1409743002/60002 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/1409743002/60002
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
Still LGTM with just some comments on comments. Just a note: remember that if in the future you plan to use this on the renderer side, on Linux desktop the sandbox will fail the madvise request with EPERM. You'll need to change the code in the sandbox [1] to make it pass through, provided that security is ok with that. [1] https://code.google.com/p/chromium/codesearch#chromium/src/sandbox/linux/secc... https://codereview.chromium.org/1409743002/diff/60002/base/memory/discardable... File base/memory/discardable_shared_memory.cc (right): https://codereview.chromium.org/1409743002/diff/60002/base/memory/discardable... base/memory/discardable_shared_memory.cc:23: // Use MADV_FREE when MADV_REMOVE is not available. MADV_FREE doesn't give us I'd probably make this comment a bit more explicit, something like: - say explicitly that this is for mac. - the problem is not that the page is not zero-filled, rather that it gets purged lazily. https://codereview.chromium.org/1409743002/diff/60002/base/memory/discardable... base/memory/discardable_shared_memory.cc:340: DPLOG(ERROR) << "madvise(MADV_REMOVE) failed"; On mac if this fails you will say that madvise(MADV_REMOVE) failed, but in reality you did a madv(MADV_FREE) Probably better to not mention "MADV_REMOVE" from the log message here, just for the sake of making the error message on Mac less cryptic.
https://codereview.chromium.org/1409743002/diff/60002/base/memory/discardable... File base/memory/discardable_shared_memory.cc (right): https://codereview.chromium.org/1409743002/diff/60002/base/memory/discardable... base/memory/discardable_shared_memory.cc:7: #if defined(OS_POSIX) && !defined(OS_NACL) I'm still kinda uncomfortable with this statement being POSIX but the #define being LINUX||ANDROID. POSIX includes a lot more platforms than mac|linux|android. Could this maybe be #if defined(DISCARDABLE..REMOVE) || defined(OS_MAC)? Or can you leave a comment explaining why POSIX is really right here?
On 2015/10/20 at 13:33:39, primiano wrote: > Still LGTM with just some comments on comments. > > Just a note: remember that if in the future you plan to use this on the renderer side, on Linux desktop the sandbox will fail the madvise request with EPERM. > You'll need to change the code in the sandbox [1] to make it pass through, provided that security is ok with that. > > [1] https://code.google.com/p/chromium/codesearch#chromium/src/sandbox/linux/secc... Acknowledged. Thanks. FYI, I changed latest patch to instead of only defining DISCARDABLE..REMOVE on linux and android it defines it on all posix platforms except MacOSX. The reasoning behind that is that if we ever start supporting a new posix platform, then we'd rather see compile error here when MADV_REMOVE is missing than silently using MADV_FREE. https://codereview.chromium.org/1409743002/diff/60002/base/memory/discardable... File base/memory/discardable_shared_memory.cc (right): https://codereview.chromium.org/1409743002/diff/60002/base/memory/discardable... base/memory/discardable_shared_memory.cc:7: #if defined(OS_POSIX) && !defined(OS_NACL) On 2015/10/20 at 18:04:03, danakj wrote: > I'm still kinda uncomfortable with this statement being POSIX but the #define being LINUX||ANDROID. > > POSIX includes a lot more platforms than mac|linux|android. > > Could this maybe be #if defined(DISCARDABLE..REMOVE) || defined(OS_MAC)? > > Or can you leave a comment explaining why POSIX is really right here? madvise() is part of the POSIX standard. It was added as posix_madvise() but madvise() is what everyone seem to still use and implement. Added a comment to explain what this include is for. https://codereview.chromium.org/1409743002/diff/60002/base/memory/discardable... base/memory/discardable_shared_memory.cc:23: // Use MADV_FREE when MADV_REMOVE is not available. MADV_FREE doesn't give us On 2015/10/20 at 13:33:39, Primiano Tucci wrote: > I'd probably make this comment a bit more explicit, something like: > - say explicitly that this is for mac. > - the problem is not that the page is not zero-filled, rather that it gets purged lazily. Done. https://codereview.chromium.org/1409743002/diff/60002/base/memory/discardable... base/memory/discardable_shared_memory.cc:340: DPLOG(ERROR) << "madvise(MADV_REMOVE) failed"; On 2015/10/20 at 13:33:39, Primiano Tucci wrote: > On mac if this fails you will say that madvise(MADV_REMOVE) failed, but in reality you did a madv(MADV_FREE) > Probably better to not mention "MADV_REMOVE" from the log message here, just for the sake of making the error message on Mac less cryptic. Done.
The CQ bit was checked by reveman@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/1409743002/170001 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/1409743002/170001
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
https://codereview.chromium.org/1409743002/diff/170001/base/memory/discardabl... File base/memory/discardable_shared_memory.cc (right): https://codereview.chromium.org/1409743002/diff/170001/base/memory/discardabl... base/memory/discardable_shared_memory.cc:29: #define MADV_REMOVE MADV_FREE Rather than defining MADV_REMOVE ourselves, can you define your own macro or static variable and assign it to either MADV_REMOVE or MADV_FREE conditionally? https://codereview.chromium.org/1409743002/diff/170001/base/memory/discardabl... base/memory/discardable_shared_memory.cc:340: AlignToPageSize(mapped_size_), MADV_REMOVE)) { Then this doesn't read like it's doing MADV_REMOVE magically always, which it is not. https://codereview.chromium.org/1409743002/diff/170001/base/memory/discardabl... File base/memory/discardable_shared_memory.h (right): https://codereview.chromium.org/1409743002/diff/170001/base/memory/discardabl... base/memory/discardable_shared_memory.h:23: #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_NACL) Thanks for the extra comments, I'm finally wrapping my head around this a bit. From what I understand MADV_REMOVE only exists on linux (and android cuz it's linux)? This define as is would include FREEBSD and NETBSD etc.. which it won't exist on? I tried to google search and I didn't find anything saying it would exist. So I guess LINUX||ANDROID is actually what you want, but how come you don't just use the existance of MADV_REMOVE to inform this decision? I like that you explain madvice will always be used tho, this comment is good. Maybe you could say this is a linux-specific extension to madvise() and android has it also (if this is true)?
https://codereview.chromium.org/1409743002/diff/170001/base/memory/discardabl... File base/memory/discardable_shared_memory.h (right): https://codereview.chromium.org/1409743002/diff/170001/base/memory/discardabl... base/memory/discardable_shared_memory.h:23: #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_NACL) On 2015/10/21 at 18:34:25, danakj wrote: > Thanks for the extra comments, I'm finally wrapping my head around this a bit. From what I understand MADV_REMOVE only exists on linux (and android cuz it's linux)? > > This define as is would include FREEBSD and NETBSD etc.. which it won't exist on? I tried to google search and I didn't find anything saying it would exist. > > So I guess LINUX||ANDROID is actually what you want, but how come you don't just use the existance of MADV_REMOVE to inform this decision? > > I like that you explain madvice will always be used tho, this comment is good. Maybe you could say this is a linux-specific extension to madvise() and android has it also (if this is true)? Changed things a bit in latest patch, including a less cryptic name for this define. I think it's in line with what you're asking for. Let me know what you think.
The CQ bit was checked by reveman@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/1409743002/190001 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/1409743002/190001
Thanks! LGTM
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
The CQ bit was checked by reveman@chromium.org
The patchset sent to the CQ was uploaded after l-g-t-m from avi@chromium.org, primiano@chromium.org Link to the patchset: https://codereview.chromium.org/1409743002/#ps190001 (title: "better name for define and improved comments")
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/1409743002/190001 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/1409743002/190001
Message was sent while issue was closed.
Committed patchset #11 (id:190001)
Message was sent while issue was closed.
Patchset 11 (id:??) landed as https://crrev.com/dc9010e6a83e6cc0e424d482fe038d4b1c889f60 Cr-Commit-Position: refs/heads/master@{#355391}
Message was sent while issue was closed.
A revert of this CL (patchset #11 id:190001) has been created in https://codereview.chromium.org/1413163006/ by reveman@chromium.org. The reason for reverting is: Causing crashes on MacOSX: crbug.com/546642.
Message was sent while issue was closed.
Description was changed from ========== base: Use MADV_REMOVE instead of ftruncate to purge discardable memory segments. This makes the discardable memory implementation use madvise(MADV_REMOVE) to tell the kernel to free resources associated with purged pages. This cleans up the code as madvise - unlike ftruncate - doesn't require us to keep the file descriptor open and it has the huge advantage that discardable memory can be shared between a renderer and the GPU process. This also works with Ashmem for which ftrunctate is not supported. BUG=543633 TEST=base_unittests --gtest_filter=DiscardableSharedMemoryTest.ZeroFilledPagesAfterPurge Committed: https://crrev.com/dc9010e6a83e6cc0e424d482fe038d4b1c889f60 Cr-Commit-Position: refs/heads/master@{#355391} ========== to ========== Re-land: base: Use MADV_REMOVE instead of ftruncate to purge discardable memory segments. This makes the discardable memory implementation use madvise(MADV_REMOVE) to tell the kernel to free resources associated with purged pages. This cleans up the code as madvise - unlike ftruncate - doesn't require us to keep the file descriptor open and it has the huge advantage that discardable memory can be shared between a renderer and the GPU process. This also works with Ashmem for which ftrunctate is not supported. BUG=543633 TEST=base_unittests --gtest_filter=DiscardableSharedMemoryTest.ZeroFilledPagesAfterPurge, content_unittests --gtest_filter=HostDiscardableSharedMemoryManagerTest.ReduceMemoryAfterSegmentHasBeenDeleted ==========
Latest patch fixes the problem that resulted in this causing crashes and includes a new HostDiscardableSharedMemoryManagerTest unit test for that problem. It should be safe to re-land this now.
The CQ bit was checked by reveman@chromium.org
The patchset sent to the CQ was uploaded after l-g-t-m from danakj@chromium.org, primiano@chromium.org, avi@chromium.org Link to the patchset: https://codereview.chromium.org/1409743002/#ps210001 (title: "fix problem with segment having been released before we try to purge")
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/1409743002/210001 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/1409743002/210001
Message was sent while issue was closed.
Committed patchset #12 (id:210001)
Message was sent while issue was closed.
Patchset 12 (id:??) landed as https://crrev.com/adfe91aac022080722ba8a24d4de79700dc38da4 Cr-Commit-Position: refs/heads/master@{#355663} |