From: Vladimir Davydov <vdavydov.dev@gmail.com> To: kostja@tarantool.org Cc: tarantool-patches@freelists.org Subject: [PATCH 14/18] vinyl: do not try to trigger dump if it is already in progress Date: Thu, 16 Aug 2018 19:12:08 +0300 [thread overview] Message-ID: <a63fc078e098d5a61e46880f638adf58b043b203.1534432819.git.vdavydov.dev@gmail.com> (raw) In-Reply-To: <cover.1534432819.git.vdavydov.dev@gmail.com> In-Reply-To: <cover.1534432819.git.vdavydov.dev@gmail.com> Currently, vy_quota_try_use() calls vy_quota_exceeded_cb() every time it sees that the memory usage exceeds the watermark. Actually, this is pointless, because the callback will return immediately if dump is already in progress. Let's introduce a flag vy_quota::dump_in_progress and skip the call to vy_quota_exceeded_cb() if dump has already been triggered. The flag is cleared when dump by vy_quota_dump(), which is called when dump is complete. This also gives us a place in the code where we can remember the time and memory usage at the time when dump was started, which will be useful for transaction throttling. --- src/box/vinyl.c | 5 +++-- src/box/vy_quota.c | 46 +++++++++++++++++++++++++++++++++------------- src/box/vy_quota.h | 12 ++++++++++-- 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/box/vinyl.c b/src/box/vinyl.c index 3699fff8..25a937bc 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -2366,7 +2366,7 @@ vinyl_engine_rollback_statement(struct engine *engine, struct txn *txn, /** {{{ Environment */ -static void +static bool vy_env_quota_exceeded_cb(struct vy_quota *quota) { struct vy_env *env = container_of(quota, struct vy_env, quota); @@ -2393,9 +2393,10 @@ vy_env_quota_exceeded_cb(struct vy_quota *quota) * quota has been consumed by pending transactions. * There's nothing we can do about that. */ - return; + return false; } vy_scheduler_trigger_dump(&env->scheduler); + return true; } static void diff --git a/src/box/vy_quota.c b/src/box/vy_quota.c index 620155ab..0250b3ab 100644 --- a/src/box/vy_quota.c +++ b/src/box/vy_quota.c @@ -79,6 +79,17 @@ vy_quota_signal(struct vy_quota *q) fiber_cond_signal(&q->cond); } +/** + * Trigger memory dump if memory usage is above the wateramrk + * and dump hasn't been triggered yet. + */ +static inline void +vy_quota_check_watermark(struct vy_quota *q) +{ + if (!q->dump_in_progress && q->used >= q->watermark) + q->dump_in_progress = q->quota_exceeded_cb(q); +} + static void vy_quota_timer_cb(ev_loop *loop, ev_timer *timer, int events) { @@ -109,8 +120,7 @@ vy_quota_timer_cb(ev_loop *loop, ev_timer *timer, int events) */ q->watermark = ((double)q->limit * q->dump_bw / (q->dump_bw + q->use_rate + 1)); - if (q->used >= q->watermark) - q->quota_exceeded_cb(q); + vy_quota_check_watermark(q); } int @@ -144,6 +154,7 @@ vy_quota_create(struct vy_quota *q, vy_quota_exceeded_f quota_exceeded_cb) q->too_long_threshold = TIMEOUT_INFINITY; q->dump_bw = VY_DEFAULT_DUMP_BANDWIDTH; q->quota_exceeded_cb = quota_exceeded_cb; + q->dump_in_progress = false; fiber_cond_create(&q->cond); ev_timer_init(&q->timer, vy_quota_timer_cb, 0, VY_QUOTA_UPDATE_INTERVAL); @@ -165,8 +176,7 @@ void vy_quota_set_limit(struct vy_quota *q, size_t limit) { q->limit = q->watermark = limit; - if (q->used >= limit) - q->quota_exceeded_cb(q); + vy_quota_check_watermark(q); vy_quota_signal(q); } @@ -182,8 +192,7 @@ vy_quota_force_use(struct vy_quota *q, size_t size) { q->used += size; q->use_curr += size; - if (q->used >= q->watermark) - q->quota_exceeded_cb(q); + vy_quota_check_watermark(q); } void @@ -191,6 +200,7 @@ vy_quota_dump(struct vy_quota *q, size_t size, double duration) { assert(q->used >= size); q->used -= size; + q->dump_in_progress = false; vy_quota_signal(q); /* Account dump bandwidth. */ @@ -211,9 +221,14 @@ vy_quota_try_use(struct vy_quota *q, size_t size, double timeout) { double start_time = ev_monotonic_now(loop()); double deadline = start_time + timeout; - while (q->used + size > q->limit && timeout > 0) { - q->quota_exceeded_cb(q); - if (fiber_cond_wait_deadline(&q->cond, deadline) != 0) + + q->used += size; + while (q->used > q->limit) { + vy_quota_check_watermark(q); + q->used -= size; + int rc = fiber_cond_wait_deadline(&q->cond, deadline); + q->used += size; + if (rc != 0) break; /* timed out */ } double wait_time = ev_monotonic_now(loop()) - start_time; @@ -221,12 +236,17 @@ vy_quota_try_use(struct vy_quota *q, size_t size, double timeout) say_warn("waited for %zu bytes of vinyl memory quota " "for too long: %.3f sec", size, wait_time); } - if (q->used + size > q->limit) + if (q->used > q->limit) { + /* + * In case of faiure diag should have been set by + * fiber_cond_wait_deadline(). + */ + assert(!diag_is_empty(diag_get())); + q->used -= size; return -1; - q->used += size; + } q->use_curr += size; - if (q->used >= q->watermark) - q->quota_exceeded_cb(q); + vy_quota_check_watermark(q); /* Wake up the next fiber in the line waiting for quota. */ vy_quota_signal(q); diff --git a/src/box/vy_quota.h b/src/box/vy_quota.h index 287c50f2..cb681386 100644 --- a/src/box/vy_quota.h +++ b/src/box/vy_quota.h @@ -31,6 +31,7 @@ * SUCH DAMAGE. */ +#include <stdbool.h> #include <stddef.h> #include <tarantool_ev.h> #include "fiber_cond.h" @@ -42,7 +43,7 @@ extern "C" { struct vy_quota; struct histogram; -typedef void +typedef bool (*vy_quota_exceeded_f)(struct vy_quota *quota); /** @@ -75,9 +76,16 @@ struct vy_quota { struct fiber_cond cond; /** * Called when quota is consumed if used >= watermark. - * It is supposed to trigger memory reclaim. + * It is supposed to trigger memory dump and return true + * on success, false on failure. */ vy_quota_exceeded_f quota_exceeded_cb; + /** + * Set if the last triggered memory dump hasn't completed + * yet, i.e. quota_exceeded_cb() was invoked and returned + * true, but vy_quota_dump() hasn't been called yet. + */ + bool dump_in_progress; /** Timer for updating quota watermark. */ ev_timer timer; /** -- 2.11.0
next prev parent reply other threads:[~2018-08-16 16:12 UTC|newest] Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-08-16 16:11 [PATCH 00/18] Implement write throttling for vinyl Vladimir Davydov 2018-08-16 16:11 ` [PATCH 01/18] vinyl: rework internal quota API Vladimir Davydov 2018-08-20 11:07 ` Konstantin Osipov 2018-08-24 8:32 ` Vladimir Davydov 2018-08-27 18:29 ` Vladimir Davydov 2018-08-16 16:11 ` [PATCH 02/18] vinyl: move quota methods implementation to vy_quota.c Vladimir Davydov 2018-08-20 11:07 ` Konstantin Osipov 2018-08-27 18:30 ` Vladimir Davydov 2018-08-16 16:11 ` [PATCH 03/18] vinyl: move quota related methods and variables from vy_env to vy_quota Vladimir Davydov 2018-08-20 11:08 ` Konstantin Osipov 2018-08-27 18:33 ` Vladimir Davydov 2018-08-16 16:11 ` [PATCH 04/18] vinyl: implement vy_quota_wait using vy_quota_try_use Vladimir Davydov 2018-08-20 11:09 ` Konstantin Osipov 2018-08-27 18:36 ` Vladimir Davydov 2018-08-16 16:11 ` [PATCH 05/18] vinyl: wake up fibers waiting for quota one by one Vladimir Davydov 2018-08-20 11:11 ` Konstantin Osipov 2018-08-24 8:33 ` Vladimir Davydov 2018-08-28 13:19 ` Vladimir Davydov 2018-08-28 14:04 ` Konstantin Osipov 2018-08-28 14:39 ` Vladimir Davydov 2018-08-16 16:12 ` [PATCH 06/18] vinyl: do not wake up fibers waiting for quota if quota is unavailable Vladimir Davydov 2018-08-20 11:13 ` Konstantin Osipov 2018-08-16 16:12 ` [PATCH 07/18] vinyl: tune dump bandwidth histogram buckets Vladimir Davydov 2018-08-20 11:15 ` Konstantin Osipov 2018-08-28 15:37 ` Vladimir Davydov 2018-08-16 16:12 ` [PATCH 08/18] vinyl: rename vy_quota::dump_bw to dump_bw_hist Vladimir Davydov 2018-08-20 11:15 ` Konstantin Osipov 2018-08-28 16:04 ` Vladimir Davydov 2018-08-16 16:12 ` [PATCH 09/18] vinyl: cache dump bandwidth for timer invocation Vladimir Davydov 2018-08-20 11:21 ` Konstantin Osipov 2018-08-28 16:10 ` Vladimir Davydov 2018-08-16 16:12 ` [PATCH 10/18] vinyl: do not add initial guess to dump bandwidth histogram Vladimir Davydov 2018-08-20 11:23 ` Konstantin Osipov 2018-08-23 20:15 ` Konstantin Osipov 2018-08-28 16:15 ` Vladimir Davydov 2018-08-16 16:12 ` [PATCH 11/18] vinyl: use snap_io_rate_limit for initial dump bandwidth estimate Vladimir Davydov 2018-08-20 11:24 ` Konstantin Osipov 2018-08-24 8:31 ` Vladimir Davydov 2018-08-28 16:18 ` Vladimir Davydov 2018-08-16 16:12 ` [PATCH 12/18] histogram: add function for computing lower bound percentile estimate Vladimir Davydov 2018-08-20 11:29 ` [tarantool-patches] " Konstantin Osipov 2018-08-24 8:30 ` Vladimir Davydov 2018-08-28 16:39 ` Vladimir Davydov 2018-08-16 16:12 ` [PATCH 13/18] vinyl: use lower bound percentile estimate for dump bandwidth Vladimir Davydov 2018-08-28 16:51 ` Vladimir Davydov 2018-08-16 16:12 ` Vladimir Davydov [this message] 2018-08-16 16:12 ` [PATCH 15/18] vinyl: improve dump start/stop logging Vladimir Davydov 2018-08-23 20:18 ` Konstantin Osipov 2018-08-16 16:12 ` [PATCH 16/18] vinyl: confine quota watermark within sane value range Vladimir Davydov 2018-08-16 16:12 ` [PATCH 17/18] vinyl: set quota timer period to 100 ms Vladimir Davydov 2018-08-23 20:49 ` Konstantin Osipov 2018-08-24 8:18 ` Vladimir Davydov 2018-08-16 16:12 ` [PATCH 18/18] vinyl: throttle tx rate if dump does not catch up Vladimir Davydov 2018-08-23 20:54 ` Konstantin Osipov 2018-08-23 20:58 ` [tarantool-patches] " Konstantin Osipov 2018-08-24 8:21 ` Vladimir Davydov
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=a63fc078e098d5a61e46880f638adf58b043b203.1534432819.git.vdavydov.dev@gmail.com \ --to=vdavydov.dev@gmail.com \ --cc=kostja@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='Re: [PATCH 14/18] vinyl: do not try to trigger dump if it is already in progress' \ /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