git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Erik Faye-Lund <kusmabite@gmail.com>
To: "Shawn O. Pearce" <spearce@spearce.org>
Cc: Junio C Hamano <gitster@pobox.com>, git@vger.kernel.org
Subject: Re: [PATCH v2] Limit file descriptors used by packs
Date: Mon, 28 Feb 2011 22:13:22 +0100	[thread overview]
Message-ID: <AANLkTikpBSi9CDHBsThGyumJ0CLd2xP+wD18vr1NQr3J@mail.gmail.com> (raw)
In-Reply-To: <1298926359-26438-1-git-send-email-spearce@spearce.org>

On Mon, Feb 28, 2011 at 9:52 PM, Shawn O. Pearce <spearce@spearce.org> wrote:
> Rather than using 'errno == EMFILE' after a failed open() call
> to indicate the process is out of file descriptors and an LRU
> pack window should be closed, place a hard upper limit on the
> number of open packs based on the actual rlimit of the process.
>
> By using a hard upper limit that is below the rlimit of the current
> process it is not necessary to check for EMFILE on every single
> fd-allocating system call.  Instead reserving 25 file descriptors
> makes it safe to assume the system call won't fail due to being over
> the filedescriptor limit.  Here 25 is chosen as a WAG, but considers
> 3 for stdin/stdout/stderr, and at least a few for other Git code
> to operate on temporary files.  An additional 20 is reserved as it
> is not known what the C library needs to perform other services on
> Git's behalf, such as nsswitch or name resolution.
>
> This fixes a case where running `git gc --auto` in a repository
> with more than 1024 packs (but an rlimit of 1024 open fds) fails
> due to the temporary output file not being able to allocate a
> file descriptor.  The output file is opened by pack-objects after
> object enumeration and delta compression are done, both of which
> have already opened all of the packs and fully populated the file
> descriptor table.
>
> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
> ---
>  sha1_file.c |   43 ++++++++++++++++++++++++++++++-------------
>  1 files changed, 30 insertions(+), 13 deletions(-)
>
> diff --git a/sha1_file.c b/sha1_file.c
> index d949b35..7850c18 100644
> --- a/sha1_file.c
> +++ b/sha1_file.c
> @@ -418,6 +418,8 @@ static unsigned int pack_used_ctr;
>  static unsigned int pack_mmap_calls;
>  static unsigned int peak_pack_open_windows;
>  static unsigned int pack_open_windows;
> +static unsigned int pack_open_fds;
> +static unsigned int pack_max_fds;
>  static size_t peak_pack_mapped;
>  static size_t pack_mapped;
>  struct packed_git *packed_git;
> @@ -597,6 +599,7 @@ static int unuse_one_window(struct packed_git *current, int keep_fd)
>                        lru_p->windows = lru_w->next;
>                        if (!lru_p->windows && lru_p->pack_fd != keep_fd) {
>                                close(lru_p->pack_fd);
> +                               pack_open_fds--;
>                                lru_p->pack_fd = -1;
>                        }
>                }
> @@ -681,8 +684,10 @@ void free_pack_by_name(const char *pack_name)
>                if (strcmp(pack_name, p->pack_name) == 0) {
>                        clear_delta_base_cache();
>                        close_pack_windows(p);
> -                       if (p->pack_fd != -1)
> +                       if (p->pack_fd != -1) {
>                                close(p->pack_fd);
> +                               pack_open_fds--;
> +                       }
>                        close_pack_index(p);
>                        free(p->bad_object_sha1);
>                        *pp = p->next;
> @@ -708,9 +713,29 @@ static int open_packed_git_1(struct packed_git *p)
>        if (!p->index_data && open_pack_index(p))
>                return error("packfile %s index unavailable", p->pack_name);
>
> +       if (!pack_max_fds) {
> +               struct rlimit lim;
> +               unsigned int max_fds;
> +
> +               if (getrlimit(RLIMIT_NOFILE, &lim))
> +                       die_errno("cannot get RLIMIT_NOFILE");
> +

We don't have getrlimit on Windows :(

I guess something like should work, but untested. Limit of 2048 taken from MSDN:

http://msdn.microsoft.com/en-us/library/6e3b887c(v=vs.71).aspx

---8<---

diff --git a/compat/mingw.h b/compat/mingw.h
index 9c00e75..9155ce3 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -234,6 +234,22 @@ int mingw_getpagesize(void);
 #define getpagesize mingw_getpagesize
 #endif

+struct rlimit {
+	unsigned int rlim_cur;
+};
+#define RLIMIT_NOFILE 0
+
+static inline int getrlimit(int resource, struct rlimit *rlp)
+{
+	if (resource != RLIMIT_NOFILE) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	rlp->rlim_cur = 2048;
+	return 0;
+}
+
 /* Use mingw_lstat() instead of lstat()/stat() and
  * mingw_fstat() instead of fstat() on Windows.
  */

---8<---

  reply	other threads:[~2011-02-28 21:13 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-28 20:27 [PATCH] Limit file descriptors used by packs Shawn O. Pearce
2011-02-28 20:35 ` Bernhard R. Link
2011-02-28 20:44   ` Shawn O. Pearce
2011-02-28 20:38 ` Junio C Hamano
2011-02-28 20:47   ` Shawn O. Pearce
2011-02-28 20:52     ` [PATCH v2] " Shawn O. Pearce
2011-02-28 21:13       ` Erik Faye-Lund [this message]
2011-03-01 14:24     ` [PATCH] " Junio C Hamano
2011-03-01 14:58       ` Shawn Pearce
2011-03-02 18:01         ` [PATCH 2/1] sha1_file.c: Don't retain open fds on small packs Shawn O. Pearce

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=AANLkTikpBSi9CDHBsThGyumJ0CLd2xP+wD18vr1NQr3J@mail.gmail.com \
    --to=kusmabite@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=spearce@spearce.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).