Tarantool development patches archive
 help / color / mirror / Atom feed
From: Cyrill Gorcunov <gorcunov@gmail.com>
To: tml <tarantool-patches@freelists.org>
Cc: Vladimir Davydov <vdavydov.dev@gmail.com>,
	Cyrill Gorcunov <gorcunov@gmail.com>
Subject: [PATCH 2/3] slab_arena: Provide slab_arena_madvise_create to madvice slabs
Date: Wed,  1 May 2019 18:50:05 +0300	[thread overview]
Message-ID: <20190501155006.14546-3-gorcunov@gmail.com> (raw)
In-Reply-To: <20190501155006.14546-1-gorcunov@gmail.com>

The purpose of this helper is to be able to eliminate
some of slab arenas from dumping, especially when huge
amount of memory involves.

For this sake one should call slab_arena_madvise_create
right after area's creation. Strictly speaking this helper
may be called in any time but then some of already created
slabs which are not inside preallocated area won't be
madvised.

Part of #3509
---
https://github.com/tarantool/tarantool/issues/3509

 small/slab_arena.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++
 small/slab_arena.h | 27 +++++++++++++++++++++++++
 2 files changed, 76 insertions(+)

diff --git a/small/slab_arena.c b/small/slab_arena.c
index 26e2620..12f6198 100644
--- a/small/slab_arena.c
+++ b/small/slab_arena.c
@@ -149,6 +149,9 @@ slab_arena_create(struct slab_arena *arena, struct quota *quota,
 	arena->used = 0;
 
 	arena->flags = flags;
+#ifdef TARANTOOL_SMALL_HAS_MADVISE
+	pm_atomic_store(&arena->advice, MADV_NORMAL);
+#endif
 
 	if (arena->prealloc) {
 		arena->arena = mmap_checked(arena->prealloc,
@@ -205,6 +208,12 @@ slab_map(struct slab_arena *arena)
 		__sync_sub_and_fetch(&arena->used, arena->slab_size);
 		quota_release(arena->quota, arena->slab_size);
 	}
+
+#ifdef TARANTOOL_SMALL_HAS_MADVISE
+	if (ptr && pm_atomic_load(&arena->advice) != MADV_NORMAL)
+		madvise(ptr, arena->slab_size, arena->advice);
+#endif
+
 	VALGRIND_MAKE_MEM_UNDEFINED(ptr, arena->slab_size);
 	return ptr;
 }
@@ -226,3 +235,43 @@ slab_arena_mprotect(struct slab_arena *arena)
 	if (arena->arena)
 		mprotect(arena->arena, arena->prealloc, PROT_READ);
 }
+
+#ifdef TARANTOOL_SMALL_HAS_MADVISE
+/**
+ * slab_arena_madvise_create - Initialize madvise permanent strategy
+ * @arena:	slab arena to madvise
+ * @advice:	strategy (MADV_DONTDUMP, ...)
+ *
+ * This function setups @slab_arena strategy so that new memory
+ * allocation with mmap() call gets madvise() call with @advice.
+ *
+ * Note that we don't allow to change strategy once choosen because
+ * otherwise we need to walk over all possible slab cache entry.
+ *
+ * This function should be called right after the slab arena creation,
+ * otherwise if called later some of the non-preallocated slabs won't be
+ * madvise'd.
+ */
+int
+slab_arena_madvise_create(struct slab_arena *arena, int advice)
+{
+	int expected = MADV_NORMAL;
+
+	if (!pm_atomic_compare_exchange_strong(&arena->advice,
+					       &expected, advice)) {
+		return -EBUSY;
+	}
+
+	if (arena->arena)
+		return madvise(arena->arena, arena->prealloc, advice);
+	return 0;
+}
+#else
+int
+slab_arena_madvise_create(struct slab_arena *arena, int advice)
+{
+	(void)arena;
+	(void)advice;
+	return -EINVAL;
+}
+#endif /* TARANTOOL_SMALL_HAS_MADVISE */
diff --git a/small/slab_arena.h b/small/slab_arena.h
index 364252f..4d86545 100644
--- a/small/slab_arena.h
+++ b/small/slab_arena.h
@@ -31,8 +31,10 @@
  * SUCH DAMAGE.
  */
 #include "lf_lifo.h"
+#include "config.h"
 #include <sys/mman.h>
 #include <limits.h>
+#include <errno.h>
 
 #if defined(__cplusplus)
 extern "C" {
@@ -97,6 +99,12 @@ struct slab_arena {
 	 * mmap() flags: MAP_SHARED or MAP_PRIVATE
 	 */
 	int flags;
+#ifdef TARANTOOL_SMALL_HAS_MADVISE
+	/**
+	 * madvise() flag
+	 */
+	int advice;
+#endif
 };
 
 /** Initialize an arena.  */
@@ -120,6 +128,25 @@ slab_unmap(struct slab_arena *arena, void *ptr);
 void
 slab_arena_mprotect(struct slab_arena *arena);
 
+/** madvise() all slabs. */
+int
+slab_arena_madvise_create(struct slab_arena *arena, int advice);
+
+/** handy helpers for slab_arena_madvise_create. */
+#ifdef TARANTOOL_SMALL_HAS_MADVISE
+static inline int
+slab_arena_madvise_dontdump(struct slab_arena *arena)
+{
+	return slab_arena_madvise_create(arena, MADV_DONTDUMP);
+}
+#else
+static inline int
+slab_arena_madvise_dontdump(struct slab_arena *arena)
+{
+	return -EINVAL;
+}
+#endif
+
 /**
  * Align a size - round up to nearest divisible by the given alignment.
  * Alignment must be a power of 2
-- 
2.20.1

  parent reply	other threads:[~2019-05-01 15:50 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-01 15:50 [PATCH 0/3] small: Prepare ground for madvise Cyrill Gorcunov
2019-05-01 15:50 ` [PATCH 1/3] build: Check for madvise syscall Cyrill Gorcunov
2019-05-06 10:25   ` Vladimir Davydov
2019-05-06 10:39     ` Cyrill Gorcunov
2019-05-01 15:50 ` Cyrill Gorcunov [this message]
2019-05-06 10:38   ` [PATCH 2/3] slab_arena: Provide slab_arena_madvise_create to madvice slabs Vladimir Davydov
2019-05-06 11:03     ` Cyrill Gorcunov
2019-05-06 13:46     ` Alexander Turenko
2019-05-01 15:50 ` [PATCH 3/3] test: slab_arena -- Verify madvise Cyrill Gorcunov
2019-05-06 10:45   ` Vladimir Davydov
2019-05-06 10:48     ` Cyrill Gorcunov
2019-05-06 10:55       ` Vladimir Davydov
2019-05-06 10:57         ` Cyrill Gorcunov
2019-05-06 11:04     ` Alexander Turenko

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=20190501155006.14546-3-gorcunov@gmail.com \
    --to=gorcunov@gmail.com \
    --cc=tarantool-patches@freelists.org \
    --cc=vdavydov.dev@gmail.com \
    --subject='Re: [PATCH 2/3] slab_arena: Provide slab_arena_madvise_create to madvice slabs' \
    /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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox