Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chunked: use mmap to load cache files #1857

Merged

Conversation

giuseppe
Copy link
Member

@giuseppe giuseppe commented Mar 5, 2024

reduce memory usage for the process by not loading entirely in memory any cache file for the layers.

The memory mapped files can be shared among multiple instances of Podman, as well as not being fully loaded in memory.

@openshift-ci openshift-ci bot added the approved label Mar 5, 2024
@giuseppe giuseppe force-pushed the improve-chunked-cache-loading branch 3 times, most recently from 7460370 to 36da862 Compare March 6, 2024 08:31
@rhatdan
Copy link
Member

rhatdan commented Mar 6, 2024

Is this something that will need to be back ported into podman 5.0 or wait for 5.1?

@giuseppe
Copy link
Member Author

giuseppe commented Mar 6, 2024

it is fine for 5.1

@giuseppe giuseppe force-pushed the improve-chunked-cache-loading branch 2 times, most recently from 07be00f to ec1aba0 Compare March 6, 2024 13:53
@rhatdan
Copy link
Member

rhatdan commented Mar 6, 2024

LGTM
@mtrmac PTAL

Copy link
Collaborator

@mtrmac mtrmac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now just a note on the public API, I didn’t read the actual cache part.

It’s possible that these things are not much a concern for the cache, I didn’t check.

store.go Outdated Show resolved Hide resolved
store.go Outdated Show resolved Hide resolved
@giuseppe giuseppe force-pushed the improve-chunked-cache-loading branch 2 times, most recently from 43b4236 to 99049ca Compare March 7, 2024 08:19
@giuseppe
Copy link
Member Author

giuseppe commented Mar 7, 2024

I've pushed a new version that doesn't require any API change, and try to cast the output from LayerBigData to a os.File

@mtrmac
Copy link
Collaborator

mtrmac commented Mar 7, 2024

Oh, that’s clever. Maybe worth a comment in the layers.go implementation, pointing at this assumption, so that it isn’t randomly broken by some wrapping helper.

@giuseppe
Copy link
Member Author

giuseppe commented Mar 8, 2024

@kolyshkin PTAL

@giuseppe giuseppe force-pushed the improve-chunked-cache-loading branch from 99049ca to fde18e6 Compare March 12, 2024 08:23
@giuseppe
Copy link
Member Author

rebased, please take a look

@kolyshkin
Copy link
Contributor

I'm still looking at it, hope to finish tomorrow.

Copy link
Contributor

@kolyshkin kolyshkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will continue tomorrow. For now, I've split this into two patches for easier review:

  1. rename manifest to cacheFile
  2. the rest of your changes

I might split it further as there are some code cleanups in here that may benefit from being in a separate commit.


var lcd chunkedLayerData
return buf, buf, err
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: for readability, I'd write this as return buf, buf, nil since err is always nil here.

pkg/chunked/cache_linux.go Outdated Show resolved Hide resolved
@giuseppe giuseppe force-pushed the improve-chunked-cache-loading branch 2 times, most recently from f911427 to d2801ec Compare March 14, 2024 09:42
Copy link
Contributor

@kolyshkin kolyshkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some more comments.

cacheFile, err := readCacheFileFromReader(bigData)
if err == nil {
c.addLayer(r.ID, cacheFile)
// the layer is present in the store and it is already loaded. Attempt to use
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// the layer is present in the store and it is already loaded. Attempt to use
// The layer is present in the store and it is already loaded. Attempt to

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

pkg/chunked/cache_linux.go Outdated Show resolved Hide resolved
pkg/chunked/cache_linux.go Outdated Show resolved Hide resolved
pkg/chunked/cache_linux.go Outdated Show resolved Hide resolved
pkg/chunked/cache_linux.go Show resolved Hide resolved
pkg/chunked/cache_linux.go Show resolved Hide resolved
@giuseppe giuseppe force-pushed the improve-chunked-cache-loading branch from d2801ec to 5259c9b Compare March 15, 2024 11:56
// The layer is present in the store and it is already loaded. Attempt to
// re-use it if mmap'ed.
if l, found := loadedLayers[r.ID]; found {
if l.mmapBuffer != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does that mean if a layer is loaded via io.ReadAll (rather than Mmap), we are re-reading it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was meant to be an optimization to use only when the file is first created, so we already have its content in memory and to avoid reloading it. I've fixed it to not reload the cache when the file was initially loaded using io.ReadAll.

Applied the following fixup patch and pushed the new version:

diff --git a/pkg/chunked/cache_linux.go b/pkg/chunked/cache_linux.go
index 386bda515..01bfc8d92 100644
--- a/pkg/chunked/cache_linux.go
+++ b/pkg/chunked/cache_linux.go
@@ -46,6 +46,12 @@ type layer struct {
 	// mmapBuffer is nil when the cache file is fully loaded in memory.
 	// Otherwise it points to a mmap'ed buffer that is referenced by cacheFile.vdata.
 	mmapBuffer []byte
+
+	// reloadWithMmap is set when the current process generates the cache file,
+	// and cacheFile reuses the memory buffer used by the generation function.
+	// Next time the layer cache is used, attempt to reload the file using
+	// mmap.
+	reloadWithMmap bool
 }
 
 type layersCache struct {
@@ -201,7 +207,12 @@ func (c *layersCache) createCacheFileFromTOC(layerID string) (*layer, error) {
 	if err != nil {
 		return nil, err
 	}
-	return c.createLayer(layerID, cacheFile, nil)
+	l, err := c.createLayer(layerID, cacheFile, nil)
+	if err != nil {
+		return nil, err
+	}
+	l.reloadWithMmap = true
+	return l, nil
 }
 
 func (c *layersCache) load() error {
@@ -222,8 +233,8 @@ func (c *layersCache) load() error {
 		// The layer is present in the store and it is already loaded.  Attempt to
 		// re-use it if mmap'ed.
 		if l, found := loadedLayers[r.ID]; found {
-			if l.mmapBuffer != nil {
-				// It is loaded through mmap.  Re-use it.
+			// If the layer is not marked for re-load, move it to newLayers.
+			if !l.reloadWithMmap {
 				delete(loadedLayers, r.ID)
 				newLayers = append(newLayers, l)
 				continue

@giuseppe giuseppe force-pushed the improve-chunked-cache-loading branch from 5259c9b to af646a8 Compare March 15, 2024 20:59
@giuseppe
Copy link
Member Author

@kolyshkin are you fine with the last version?

@giuseppe giuseppe force-pushed the improve-chunked-cache-loading branch from af646a8 to 2a4e4b3 Compare March 20, 2024 16:47
@giuseppe
Copy link
Member Author

rebased

Copy link
Collaborator

@mtrmac mtrmac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a comment around layerStore.BigData noting that pkg/chunked relies on the returned type being exactly *os.File.

LGTM otherwise.

pkg/chunked/cache_linux.go Outdated Show resolved Hide resolved
pkg/chunked/cache_linux.go Outdated Show resolved Hide resolved
pkg/chunked/cache_linux.go Outdated Show resolved Hide resolved
pkg/chunked/cache_linux.go Outdated Show resolved Hide resolved
reduce memory usage for the process by not loading entirely in memory
any cache file for the layers.

The memory mapped files can be shared among multiple instances of
Podman, as well as not being fully loaded in memory.

Signed-off-by: Giuseppe Scrivano <[email protected]>
@giuseppe giuseppe force-pushed the improve-chunked-cache-loading branch from 2a4e4b3 to 080dbaf Compare March 20, 2024 19:52
@giuseppe
Copy link
Member Author

@mtrmac addressed your comments and pushed a new version

Copy link
Collaborator

@mtrmac mtrmac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! LGTM. Up to @kolyshkin now.

@giuseppe
Copy link
Member Author

@kolyshkin @rhatdan PTAL

Copy link
Contributor

@kolyshkin kolyshkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Copy link
Contributor

openshift-ci bot commented Mar 26, 2024

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: giuseppe, kolyshkin

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@giuseppe
Copy link
Member Author

/lgtm

Copy link
Contributor

openshift-ci bot commented Mar 27, 2024

@giuseppe: you cannot LGTM your own PR.

In response to this:

/lgtm

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@rhatdan rhatdan added the lgtm label Mar 27, 2024
@rhatdan
Copy link
Member

rhatdan commented Mar 27, 2024

/lgtm

@openshift-merge-bot openshift-merge-bot bot merged commit 22f7c28 into containers:main Mar 27, 2024
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants