mwrap (Perl version) user+dev discussion/patches/pulls/bugs/help
 help / color / mirror / code / Atom feed
* [PATCH 0/2] support file-backed mmap on Linux
@ 2022-11-30  6:49 Eric Wong
  2022-11-30  6:49 ` [PATCH 1/2] use " Eric Wong
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Eric Wong @ 2022-11-30  6:49 UTC (permalink / raw)
  To: mwrap-perl

Modern Linux has O_TMPFILE which makes dealing with temporary
files much easier, especially when we can't use tmpfile(3)
before malloc is initialized.

I needed these two patches to pack an objstore for linux.git
containing 771 remotes and over 500k refs without OOM-ing.

Adding more swap wouldn't have been desirable in my case since
this was a "production" system and I didn't want high-priority,
public-facing processes to suffer from swap traffic.  And my
/proc/sys/vm/max_map_count was already much larger than the
system default.

Eric Wong (2):
  use file-backed mmap on Linux
  increase DEFAULT_GRANULARITY to 64M

 mymalloc.h | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/2] use file-backed mmap on Linux
  2022-11-30  6:49 [PATCH 0/2] support file-backed mmap on Linux Eric Wong
@ 2022-11-30  6:49 ` Eric Wong
  2022-11-30 20:43   ` Eric Wong
  2022-11-30  6:49 ` [PATCH 2/2] increase DEFAULT_GRANULARITY to 64M Eric Wong
  2022-11-30 21:08 ` [PATCH v2 0/2] support file-backed mmap on Linux Eric Wong
  2 siblings, 1 reply; 8+ messages in thread
From: Eric Wong @ 2022-11-30  6:49 UTC (permalink / raw)
  To: mwrap-perl

Due to the high memory usage of mwrap, it may be useful to force
allocations onto file-backed maps.  This means more physical
memory for the rest of the system.  As opposed to adding swap
indiscriminately, this provides the ability to give the
equivalent of swap space only to the processes using mwrap.

O_TMPFILE in Linux makes supporting this a breeze, since we
can't expect to use tmpfile(3) before malloc is initialized.
---
 mymalloc.h | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/mymalloc.h b/mymalloc.h
index 4904b74..f5a171e 100644
--- a/mymalloc.h
+++ b/mymalloc.h
@@ -24,6 +24,46 @@
 #include <urcu/rculist.h>
 #include <urcu/wfcqueue.h>
 #include <urcu-bp.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#if !defined(MWRAP_FILE_BACKED) && defined(__linux__) && defined(O_TMPFILE)
+#	define MWRAP_FILE_BACKED 1
+#else
+#	define MWRAP_FILE_BACKED 0
+#endif
+#if MWRAP_FILE_BACKED
+#	include <sys/mman.h>
+static void *my_mmap(size_t size)
+{
+	int flags = MAP_PRIVATE;
+	const char *tmpdir = getenv("TMPDIR");
+	int fd;
+	void *ret;
+
+	if (!tmpdir)
+		tmpdir = "/tmp";
+
+	fd = open(tmpdir, O_TMPFILE|O_RDWR|S_IRUSR);
+	if (fd < 0) {
+		flags |= MAP_ANONYMOUS;
+	} else {
+		ssize_t w = pwrite(fd, "", 1, size - 1); /* sparse file */
+
+		if (w < 0)
+			flags |= MAP_ANONYMOUS;
+	}
+	ret = mmap(NULL, size, PROT_READ|PROT_WRITE, flags, fd, 0);
+	if (fd >= 0) {
+		int err = errno;
+		close(fd);
+		errno = err;
+	}
+	return ret;
+}
+#endif /* MWRAP_FILE_BACKED */
 
 /* knobs for dlmalloc */
 #define FOOTERS 1 /* required for remote_free_* stuff */
@@ -32,6 +72,10 @@
 #define DLMALLOC_EXPORT static inline
 /* #define NO_MALLOC_STATS 1 */
 #define USE_LOCKS 0 /* we do our own global_mtx + ms_tsd */
+#if MWRAP_FILE_BACKED
+#	define MMAP(size) my_mmap(size)
+#	define HAVE_MREMAP 0
+#endif
 #include "dlmalloc_c.h"
 #undef ABORT /* conflicts with Perl */
 

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/2] increase DEFAULT_GRANULARITY to 64M
  2022-11-30  6:49 [PATCH 0/2] support file-backed mmap on Linux Eric Wong
  2022-11-30  6:49 ` [PATCH 1/2] use " Eric Wong
@ 2022-11-30  6:49 ` Eric Wong
  2022-11-30 21:08 ` [PATCH v2 0/2] support file-backed mmap on Linux Eric Wong
  2 siblings, 0 replies; 8+ messages in thread
From: Eric Wong @ 2022-11-30  6:49 UTC (permalink / raw)
  To: mwrap-perl

Since Linux maps are file-backed, it won't provide an increase
in physical memory.  Using larger chunks reduces syscalls and
avoids hitting the Linux system-wide /proc/sys/vm/max_map_count
limit.

It's probably safe for all x86-64 systems these days, and 32-bit
is prone to overflow and not a target of this project (though
this project aims to make other projects suitable for
underpowered 32-bit systems).
---
 mymalloc.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/mymalloc.h b/mymalloc.h
index f5a171e..024075b 100644
--- a/mymalloc.h
+++ b/mymalloc.h
@@ -29,6 +29,9 @@
 #include <fcntl.h>
 #include <errno.h>
 
+/* this is fine on most x86-64, especially with file-backed mmap(2) */
+#define DEFAULT_GRANULARITY (64U * 1024U * 1024U)
+
 #if !defined(MWRAP_FILE_BACKED) && defined(__linux__) && defined(O_TMPFILE)
 #	define MWRAP_FILE_BACKED 1
 #else

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] use file-backed mmap on Linux
  2022-11-30  6:49 ` [PATCH 1/2] use " Eric Wong
@ 2022-11-30 20:43   ` Eric Wong
  0 siblings, 0 replies; 8+ messages in thread
From: Eric Wong @ 2022-11-30 20:43 UTC (permalink / raw)
  To: mwrap-perl

Eric Wong <e@80x24.org> wrote:
> +	fd = open(tmpdir, O_TMPFILE|O_RDWR|S_IRUSR);
> +	if (fd < 0) {
> +		flags |= MAP_ANONYMOUS;
> +	} else {
> +		ssize_t w = pwrite(fd, "", 1, size - 1); /* sparse file */
> +
> +		if (w < 0)
> +			flags |= MAP_ANONYMOUS;
> +	}

Will squash this to better handle pwrite errors and short writes
(likely due to ENOSPC):

diff --git a/mymalloc.h b/mymalloc.h
index f5a171e..88190d5 100644
--- a/mymalloc.h
+++ b/mymalloc.h
@@ -52,8 +52,11 @@ static void *my_mmap(size_t size)
 	} else {
 		ssize_t w = pwrite(fd, "", 1, size - 1); /* sparse file */
 
-		if (w < 0)
+		if (w <= 0) { /* 0 may be ENOSPC */
 			flags |= MAP_ANONYMOUS;
+			close(fd);
+			fd = -1;
+		}
 	}
 	ret = mmap(NULL, size, PROT_READ|PROT_WRITE, flags, fd, 0);
 	if (fd >= 0) {

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 0/2] support file-backed mmap on Linux
  2022-11-30  6:49 [PATCH 0/2] support file-backed mmap on Linux Eric Wong
  2022-11-30  6:49 ` [PATCH 1/2] use " Eric Wong
  2022-11-30  6:49 ` [PATCH 2/2] increase DEFAULT_GRANULARITY to 64M Eric Wong
@ 2022-11-30 21:08 ` Eric Wong
  2022-11-30 21:08   ` [PATCH v2 1/2] use " Eric Wong
  2022-11-30 21:08   ` [PATCH v2 2/2] increase DEFAULT_GRANULARITY to 64M Eric Wong
  2 siblings, 2 replies; 8+ messages in thread
From: Eric Wong @ 2022-11-30 21:08 UTC (permalink / raw)
  To: mwrap-perl

Modern Linux has O_TMPFILE which makes dealing with temporary
files much easier, especially when we can't use tmpfile(3)
before malloc is initialized.

I needed these two patches to pack an objstore for linux.git
containing 771 remotes and over 500k refs without OOM-ing.

Adding more swap wouldn't have been desirable in my case since
this was a "production" system and I didn't want high-priority,
public-facing processes to suffer from swap traffic.  And my
/proc/sys/vm/max_map_count was already much larger than the
system default.

Eric Wong (2):
  use file-backed mmap on Linux
  increase DEFAULT_GRANULARITY to 64M

 mymalloc.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/2] use file-backed mmap on Linux
  2022-11-30 21:08 ` [PATCH v2 0/2] support file-backed mmap on Linux Eric Wong
@ 2022-11-30 21:08   ` Eric Wong
  2022-12-02 10:14     ` Eric Wong
  2022-11-30 21:08   ` [PATCH v2 2/2] increase DEFAULT_GRANULARITY to 64M Eric Wong
  1 sibling, 1 reply; 8+ messages in thread
From: Eric Wong @ 2022-11-30 21:08 UTC (permalink / raw)
  To: mwrap-perl

Due to the high memory usage of mwrap, it may be useful to force
allocations onto file-backed maps.  This means more physical
memory for the rest of the system.  As opposed to adding swap
indiscriminately, this provides the ability to give the
equivalent of swap space only to the processes using mwrap.

O_TMPFILE in Linux makes supporting this a breeze, since we
can't expect to use tmpfile(3) before malloc is initialized.
---
 mymalloc.h | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/mymalloc.h b/mymalloc.h
index 4904b74..88190d5 100644
--- a/mymalloc.h
+++ b/mymalloc.h
@@ -24,6 +24,49 @@
 #include <urcu/rculist.h>
 #include <urcu/wfcqueue.h>
 #include <urcu-bp.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#if !defined(MWRAP_FILE_BACKED) && defined(__linux__) && defined(O_TMPFILE)
+#	define MWRAP_FILE_BACKED 1
+#else
+#	define MWRAP_FILE_BACKED 0
+#endif
+#if MWRAP_FILE_BACKED
+#	include <sys/mman.h>
+static void *my_mmap(size_t size)
+{
+	int flags = MAP_PRIVATE;
+	const char *tmpdir = getenv("TMPDIR");
+	int fd;
+	void *ret;
+
+	if (!tmpdir)
+		tmpdir = "/tmp";
+
+	fd = open(tmpdir, O_TMPFILE|O_RDWR|S_IRUSR);
+	if (fd < 0) {
+		flags |= MAP_ANONYMOUS;
+	} else {
+		ssize_t w = pwrite(fd, "", 1, size - 1); /* sparse file */
+
+		if (w <= 0) { /* 0 may be ENOSPC */
+			flags |= MAP_ANONYMOUS;
+			close(fd);
+			fd = -1;
+		}
+	}
+	ret = mmap(NULL, size, PROT_READ|PROT_WRITE, flags, fd, 0);
+	if (fd >= 0) {
+		int err = errno;
+		close(fd);
+		errno = err;
+	}
+	return ret;
+}
+#endif /* MWRAP_FILE_BACKED */
 
 /* knobs for dlmalloc */
 #define FOOTERS 1 /* required for remote_free_* stuff */
@@ -32,6 +75,10 @@
 #define DLMALLOC_EXPORT static inline
 /* #define NO_MALLOC_STATS 1 */
 #define USE_LOCKS 0 /* we do our own global_mtx + ms_tsd */
+#if MWRAP_FILE_BACKED
+#	define MMAP(size) my_mmap(size)
+#	define HAVE_MREMAP 0
+#endif
 #include "dlmalloc_c.h"
 #undef ABORT /* conflicts with Perl */
 

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 2/2] increase DEFAULT_GRANULARITY to 64M
  2022-11-30 21:08 ` [PATCH v2 0/2] support file-backed mmap on Linux Eric Wong
  2022-11-30 21:08   ` [PATCH v2 1/2] use " Eric Wong
@ 2022-11-30 21:08   ` Eric Wong
  1 sibling, 0 replies; 8+ messages in thread
From: Eric Wong @ 2022-11-30 21:08 UTC (permalink / raw)
  To: mwrap-perl

Since Linux maps are file-backed, it won't provide an increase
in physical memory.  Using larger chunks reduces syscalls and
avoids hitting the Linux system-wide /proc/sys/vm/max_map_count
limit.

It's probably safe for all x86-64 systems these days, and 32-bit
is prone to overflow and not a target of this project (though
this project aims to make other projects suitable for
underpowered 32-bit systems).
---
 mymalloc.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/mymalloc.h b/mymalloc.h
index 88190d5..94f2c7a 100644
--- a/mymalloc.h
+++ b/mymalloc.h
@@ -29,6 +29,9 @@
 #include <fcntl.h>
 #include <errno.h>
 
+/* this is fine on most x86-64, especially with file-backed mmap(2) */
+#define DEFAULT_GRANULARITY (64U * 1024U * 1024U)
+
 #if !defined(MWRAP_FILE_BACKED) && defined(__linux__) && defined(O_TMPFILE)
 #	define MWRAP_FILE_BACKED 1
 #else

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/2] use file-backed mmap on Linux
  2022-11-30 21:08   ` [PATCH v2 1/2] use " Eric Wong
@ 2022-12-02 10:14     ` Eric Wong
  0 siblings, 0 replies; 8+ messages in thread
From: Eric Wong @ 2022-12-02 10:14 UTC (permalink / raw)
  To: mwrap-perl

Eric Wong <e@80x24.org> wrote:
> +	fd = open(tmpdir, O_TMPFILE|O_RDWR|S_IRUSR);

Erm, missing S_IWUSR bit :x  pushed with the following:

diff --git a/mymalloc.h b/mymalloc.h
index 94f2c7a..7b18486 100644
--- a/mymalloc.h
+++ b/mymalloc.h
@@ -49,7 +49,7 @@ static void *my_mmap(size_t size)
 	if (!tmpdir)
 		tmpdir = "/tmp";
 
-	fd = open(tmpdir, O_TMPFILE|O_RDWR|S_IRUSR);
+	fd = open(tmpdir, O_TMPFILE|O_RDWR|S_IRUSR|S_IWUSR);
 	if (fd < 0) {
 		flags |= MAP_ANONYMOUS;
 	} else {

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2022-12-02 10:14 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-30  6:49 [PATCH 0/2] support file-backed mmap on Linux Eric Wong
2022-11-30  6:49 ` [PATCH 1/2] use " Eric Wong
2022-11-30 20:43   ` Eric Wong
2022-11-30  6:49 ` [PATCH 2/2] increase DEFAULT_GRANULARITY to 64M Eric Wong
2022-11-30 21:08 ` [PATCH v2 0/2] support file-backed mmap on Linux Eric Wong
2022-11-30 21:08   ` [PATCH v2 1/2] use " Eric Wong
2022-12-02 10:14     ` Eric Wong
2022-11-30 21:08   ` [PATCH v2 2/2] increase DEFAULT_GRANULARITY to 64M Eric Wong

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mwrap-perl.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).