Tarantool development patches archive
 help / color / mirror / Atom feed
From: Cyrill Gorcunov <gorcunov@gmail.com>
To: Vladimir Davydov <vdavydov.dev@gmail.com>
Cc: "Георгий Кириченко" <georgy@tarantool.org>,
	tarantool-patches@freelists.org
Subject: [RFC v3] fiber: Increase default stack size
Date: Tue, 26 Feb 2019 00:39:55 +0300	[thread overview]
Message-ID: <20190225213955.GI7198@uranus> (raw)
In-Reply-To: <20190225145516.6fdmob3tdkft5sky@esperanza>

The default 64K stack size used for years become too
small for modern distors (Fedora 29 and etc) where third
party libraries (such as ncurses) started to use 64K for
own buffers and we get SIGSGV early without reaching
interactive console phase.

To address this problem and hopefully eliminate such
problems in future we increase default size up to 1M.
Because this value may be too big for old distros or
other libraries, which would never use such deep stack,
we do a trick: put watermark at 64K offset of the stack
and once fiber get recycled we try to relax memory
pressue with madvise syscall.

https://github.com/tarantool/tarantool/issues/3418
---
Vladimir, take a look please. That is what you mean?
I'm not yet familiar with slab engine, does it allocates
pages on lazy fashion or we need to pass 'dontneed' on
first fiber creation too?

And please re-check stack/mark position calculus once again,
brain is off already I might miss something obvious.

Also should not we give user a way to configure this early
params, maybe via getenv?

 src/fiber.c |   87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 86 insertions(+), 1 deletion(-)

Index: tarantool.git/src/fiber.c
===================================================================
--- tarantool.git.orig/src/fiber.c
+++ tarantool.git/src/fiber.c
@@ -91,11 +91,26 @@ pthread_t main_thread_id;
 static size_t page_size;
 static int stack_direction;
 
+static void
+stack_recycle(struct fiber *fiber);
+
+/*
+ * A random unique value with help of uuidgen.
+ *
+ * 39ee5420-13f7-417b-9610-ea100c591ab6
+ */
+static const char stack_wmark[] = {
+	0x39, 0xee, 0x54, 0x20, 0x13, 0xf7, 0x41, 0x7b,
+	0x96, 0x10, 0xea, 0x10, 0x0c, 0x59, 0x1a, 0xb6
+};
+
 enum {
 	/* The minimum allowable fiber stack size in bytes */
 	FIBER_STACK_SIZE_MINIMAL = 16384,
+	/* Stack size for stack relaxed tasks */
+	FIBER_STACK_MIDDLE_LIMIT = 65536,
 	/* Default fiber stack size in bytes */
-	FIBER_STACK_SIZE_DEFAULT = 65536
+	FIBER_STACK_SIZE_DEFAULT = 1048576
 };
 
 /** Default fiber attributes */
@@ -623,6 +638,7 @@ fiber_recycle(struct fiber *fiber)
 	assert(diag_is_empty(&fiber->diag));
 	/* no pending wakeup */
 	assert(rlist_empty(&fiber->state));
+	stack_recycle(fiber);
 	bool has_custom_stack = fiber->flags & FIBER_CUSTOM_STACK;
 	fiber_reset(fiber);
 	fiber->name[0] = '\0';
@@ -710,6 +726,74 @@ page_align_up(void *ptr)
 	return page_align_down(ptr + page_size - 1);
 }
 
+static inline void *
+stack_wmark_pos(struct fiber *fiber)
+{
+	void *pos;
+
+	assert(fiber->stack);
+	assert(fiber->stack_size);
+
+	if (stack_direction < 0) {
+		pos  = fiber->stack + fiber->stack_size;
+		pos -= FIBER_STACK_MIDDLE_LIMIT;
+		return page_align_up(pos);
+	} else {
+		pos  = fiber->stack - fiber->stack_size;
+		pos += FIBER_STACK_MIDDLE_LIMIT;
+		return page_align_down(pos);
+	}
+}
+
+/*
+ * Set watermark to the predefined place thus on
+ * fiber sched-out procedure we may detect if
+ * a task was too eager for stack usage.
+ */
+static inline void
+stack_set_wmark(struct fiber *fiber)
+{
+	void *pos = stack_wmark_pos(fiber);
+	memcpy(pos, stack_wmark, sizeof(stack_wmark));
+}
+
+static inline bool
+stack_has_wmark(struct fiber *fiber)
+{
+	void *pos = stack_wmark_pos(fiber);
+	return memcmp(pos, stack_wmark, sizeof(stack_wmark)) == 0;
+}
+
+static void
+stack_recycle(struct fiber *fiber)
+{
+	if (!fiber->stack || (fiber->flags & FIBER_CUSTOM_STACK))
+		return;
+
+	/*
+	 * If a fiber was too eager for memory, just arm
+	 * a watermark back and mark the rest as unneeded.
+	 * This will hint OS to release the memory but if
+	 * a fiber ask for it again it will be shipped on
+	 * back on demand.
+	 */
+	if (!stack_has_wmark(fiber)) {
+		size_t size;
+		void *tail;
+
+		stack_set_wmark(fiber);
+
+		if (stack_direction < 0) {
+			tail = stack_wmark_pos(fiber) - page_size;
+			size = tail - fiber->stack;
+		} else {
+			tail = stack_wmark_pos(fiber) + page_size;
+			size = fiber->stack - tail;
+		}
+		madvise(fiber->stack, size, MADV_DONTNEED);
+	}
+}
+
 static int
 fiber_stack_create(struct fiber *fiber, size_t stack_size)
 {
@@ -751,6 +835,7 @@ fiber_stack_create(struct fiber *fiber,
 						  fiber->stack_size);
 
 	mprotect(guard, page_size, PROT_NONE);
+	stack_set_wmark(fiber);
 	return 0;
 }
 

  parent reply	other threads:[~2019-02-25 21:39 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-22 20:16 [tarantool-patches] [RFC v2] " Cyrill Gorcunov
2019-02-25 14:55 ` Vladimir Davydov
2019-02-25 15:25   ` Cyrill Gorcunov
2019-02-25 21:39   ` Cyrill Gorcunov [this message]
2019-02-26  8:58     ` [RFC v3] " Vladimir Davydov
2019-02-26  9:12       ` Cyrill Gorcunov
2019-02-26 10:26         ` Vladimir Davydov
2019-02-26 10:36           ` Vladimir Davydov
2019-02-26 11:17             ` Cyrill Gorcunov
2019-02-26 12:25               ` Vladimir Davydov
2019-02-26 11:16           ` Cyrill Gorcunov
2019-02-26 12:34             ` Vladimir Davydov
2019-02-26 12:54               ` Cyrill Gorcunov
2019-02-26 13:06                 ` Vladimir Davydov
2019-02-26 13:26               ` [tarantool-patches] " Konstantin Osipov
2019-02-26 14:02                 ` Cyrill Gorcunov
2019-02-26 10:32     ` Vladimir Davydov
2019-02-26 11:18       ` Cyrill Gorcunov

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=20190225213955.GI7198@uranus \
    --to=gorcunov@gmail.com \
    --cc=georgy@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --cc=vdavydov.dev@gmail.com \
    --subject='Re: [RFC v3] fiber: Increase default stack size' \
    /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