FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

indexer: Avoid one `mmap(2)`/`munmap(2)` pair per `git_indexer_append` call by lhchavez · Pull Request #6039 · libgit2/libgit2 · GitHub

indexer: Avoid one mmap(2)/munmap(2) pair per git_indexer_append call - #6039

Merged
ethomson merged 4 commits into
libgit2:mainfrom
lhchavez:avoid-mmap-in-git-indexer-append
Sep 14, 2021
Merged

ethomson merged 4 commits into
libgit2:mainfrom
lhchavez:avoid-mmap-in-git-indexer-append

Conversation

lhchavez commented Sep 7, 2021
edited
Loading

Copy link
Copy Markdown
Contributor

This change makes append_to_pack completely rely on p_pwrite to do
all its I/O instead of splitting it between p_pwrite and a
mmap(2)/munmap(2)+memcpy(3). This saves a good chunk of user CPU
time and avoids making two syscalls per round, but doesn't really cut
down a lot of wall time (~1% on cloning the
git repository).

Part of: #6038
Fixes: #5556

…` call

This change makes `append_to_pack` completely rely on `p_pwrite` to do
all its I/O instead of splitting it between `p_pwrite` and a
`mmap(2)`/`munmap(2)`+`memcpy(3)`. This saves a good chunk of user CPU
time and avoids making two syscalls per round, but doesn't really cut
down a lot of wall time (~1% on cloning the
[git](https://github.com/git/git.git) repository).

boretrk commented Sep 7, 2021

Copy link
Copy Markdown
Contributor

It seems to me that this will make it possible to remove the p_ftruncate in git_indexer_commit
That should solve #5556 and close #5935
Does the preceding git_mwindow_free_all also have something to do with this?

diff --git a/src/indexer.c b/src/indexer.c
index d546888cc..eb56ccc92 100644
--- a/src/indexer.c
+++ b/src/indexer.c
@@ -1279,12 +1279,6 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats)
        if (git_mwindow_free_all(&idx->pack->mwf) < 0)
                goto on_error;

-       /* Truncate file to undo rounding up to next page_size in append_to_pack */
-       if (p_ftruncate(idx->pack->mwf.fd, idx->pack->mwf.size) < 0) {
-               git_error_set(GIT_ERROR_OS, "failed to truncate pack file '%s'", idx->pack->pack_name);
-               return -1;
-       }
-
        if (idx->do_fsync && p_fsync(idx->pack->mwf.fd) < 0) {
                git_error_set(GIT_ERROR_OS, "failed to fsync packfile");
                goto on_error;

With that being the only use of ftruncate it can be removed from the posix layer and the tests too, but I don't see any harm in keeping it around in case it is needed in the future.

Now that we're not using `mmap(2)` for writing stuff, we don't need to
truncate the file afterwards, since it'll have the correct size at the
end of the process. Whee~!

lhchavez commented Sep 7, 2021

Copy link
Copy Markdown
Contributor Author

It seems to me that this will make it possible to remove the p_ftruncate in git_indexer_commit
That should solve #5556 and close #5935
Does the preceding git_mwindow_free_all also have something to do with this?

diff --git a/src/indexer.c b/src/indexer.c
index d546888cc..eb56ccc92 100644
--- a/src/indexer.c
+++ b/src/indexer.c
@@ -1279,12 +1279,6 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats)
        if (git_mwindow_free_all(&idx->pack->mwf) < 0)
                goto on_error;

-       /* Truncate file to undo rounding up to next page_size in append_to_pack */
-       if (p_ftruncate(idx->pack->mwf.fd, idx->pack->mwf.size) < 0) {
-               git_error_set(GIT_ERROR_OS, "failed to truncate pack file '%s'", idx->pack->pack_name);
-               return -1;
-       }
-
        if (idx->do_fsync && p_fsync(idx->pack->mwf.fd) < 0) {
                git_error_set(GIT_ERROR_OS, "failed to fsync packfile");
                goto on_error;

With that being the only use of ftruncate it can be removed from the posix layer and the tests too, but I don't see any harm in keeping it around in case it is needed in the future.

neat!

ethomson commented Sep 7, 2021

Copy link
Copy Markdown
Member

This seems reasonable to me. @carlosmn any objections?

ethomson added the bugfix label Sep 7, 2021

carlosmn commented Sep 8, 2021

Copy link
Copy Markdown
Member

This looks fine except this probably re-opens #2338 which is why we're so mmap-heavy. The issue here is that Windows may keep different views to a networked file for the mmap- and open-accessed versions of the file, so writing via write() is not reflected on the data mmap() is able to read.

IIUC this is a Windows quirk so you could disable the mmap stuff on non-Windows systems to keep it working there.

It turns out that if we use `mmap(2)`, non-Windows remote filesystems
break due to permissions. If we don't, _Windows_ remote filesystems
break due to lack of coherence between memory mapped views of the file
and direct I/O operations done to the files.

To break out of this impossible situation, conditionally-compile
versions of Windows-specific `write_at` and `append_to_pack`.

lhchavez commented Sep 8, 2021

Copy link
Copy Markdown
Contributor Author

This looks fine except this probably re-opens #2338 which is why we're so mmap-heavy. The issue here is that Windows may keep different views to a networked file for the mmap- and open-accessed versions of the file, so writing via write() is not reflected on the data mmap() is able to read.

IIUC this is a Windows quirk so you could disable the mmap stuff on non-Windows systems to keep it working there.

turns out, supporting multiple platforms is hard! thanks for the pointer, i added a comment to explain the oddness of the code for future spelunkers.

i also tested this locally (Linux) with NFS and SMB and they both work! \o/

Turns out, double negatives are harder to parse than positive
statements.

lhchavez commented Sep 8, 2021

Copy link
Copy Markdown
Contributor Author

And it also works in AWS-EFS per the other thread \o/².

Copy link
Copy Markdown
Member

Great fix, thanks again @lhchavez!

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unable to clone on AWS-EFS (NFS) failed to truncate pack file Permission denied

4 participants


Back | FazBrowse Home | New Git URL