Commit b97d9336 authored by Libor Peltan's avatar Libor Peltan

Merge branch 'axfr_async_zone_free_rcu_rebase' into 'master'

xfr: async free zone

See merge request !684
parents 23283c41 102c7f4f
...@@ -206,6 +206,35 @@ static void axfr_cleanup(struct refresh_data *data) ...@@ -206,6 +206,35 @@ static void axfr_cleanup(struct refresh_data *data)
zone_contents_deep_free(&data->axfr.zone); zone_contents_deep_free(&data->axfr.zone);
} }
/*! \brief Routine for calling call_rcu() easier way.
*
* TODO: move elsewhere, as it has no direct relation to AXFR
*/
typedef struct {
struct rcu_head rcuhead;
void (*ptr_free_fun)(void **);
void *ptr;
} callrcu_wrapper_t;
static void callrcu_wrapper_cb(struct rcu_head *param)
{
callrcu_wrapper_t * wrap = (callrcu_wrapper_t *)param;
wrap->ptr_free_fun(&wrap->ptr);
free(wrap);
}
/* note: does nothing if not-enough-memory */
static void callrcu_wrapper(void *ptr, void (*ptr_free_fun)(void **))
{
callrcu_wrapper_t * wrap = malloc(sizeof(callrcu_wrapper_t));
if (wrap != NULL) {
wrap->ptr = ptr;
wrap->ptr_free_fun = ptr_free_fun;
call_rcu((struct rcu_head *)wrap, callrcu_wrapper_cb);
}
}
static int axfr_finalize(struct refresh_data *data) static int axfr_finalize(struct refresh_data *data)
{ {
zone_contents_t *new_zone = data->axfr.zone; zone_contents_t *new_zone = data->axfr.zone;
...@@ -229,11 +258,9 @@ static int axfr_finalize(struct refresh_data *data) ...@@ -229,11 +258,9 @@ static int axfr_finalize(struct refresh_data *data)
zone_contents_t *old_zone = zone_switch_contents(data->zone, new_zone); zone_contents_t *old_zone = zone_switch_contents(data->zone, new_zone);
xfr_log_publish(data->zone->name, data->remote, old_zone, new_zone); xfr_log_publish(data->zone->name, data->remote, old_zone, new_zone);
synchronize_rcu();
data->axfr.zone = NULL; // seized data->axfr.zone = NULL; // seized
zone_contents_deep_free(&old_zone); callrcu_wrapper(old_zone, (void (*)(void **))zone_contents_deep_free);
return KNOT_EOK; return KNOT_EOK;
} }
...@@ -369,18 +396,30 @@ static void ixfr_cleanup(struct refresh_data *data) ...@@ -369,18 +396,30 @@ static void ixfr_cleanup(struct refresh_data *data)
changesets_free(&data->ixfr.changesets); changesets_free(&data->ixfr.changesets);
} }
static void ixfr_finalize_cleanup(void **ptr)
{
apply_ctx_t *ctx = *ptr;
update_free_zone(&ctx->contents);
update_cleanup(ctx);
free(ctx);
}
static int ixfr_finalize(struct refresh_data *data) static int ixfr_finalize(struct refresh_data *data)
{ {
zone_contents_t *new_zone = NULL; zone_contents_t *new_zone = NULL;
apply_ctx_t ctx = { 0 }; apply_ctx_t *ctx = calloc(1, sizeof(apply_ctx_t));
if (ctx == NULL) {
return KNOT_ENOMEM;
}
apply_init_ctx(&ctx, NULL, APPLY_STRICT); apply_init_ctx(ctx, NULL, APPLY_STRICT);
int ret = apply_changesets(&ctx, data->zone->contents, int ret = apply_changesets(ctx, data->zone->contents,
&data->ixfr.changesets, &new_zone); &data->ixfr.changesets, &new_zone);
if (ret != KNOT_EOK) { if (ret != KNOT_EOK) {
IXFRIN_LOG(LOG_WARNING, data->zone->name, data->remote, IXFRIN_LOG(LOG_WARNING, data->zone->name, data->remote,
"failed to apply changes to zone (%s)", "failed to apply changes to zone (%s)",
knot_strerror(ret)); knot_strerror(ret));
free(ctx);
return ret; return ret;
} }
...@@ -388,8 +427,9 @@ static int ixfr_finalize(struct refresh_data *data) ...@@ -388,8 +427,9 @@ static int ixfr_finalize(struct refresh_data *data)
ret = xfr_validate(new_zone, data); ret = xfr_validate(new_zone, data);
if (ret != KNOT_EOK) { if (ret != KNOT_EOK) {
update_rollback(&ctx); update_rollback(ctx);
update_free_zone(&new_zone); update_free_zone(&new_zone);
free(ctx);
return ret; return ret;
} }
...@@ -399,18 +439,17 @@ static int ixfr_finalize(struct refresh_data *data) ...@@ -399,18 +439,17 @@ static int ixfr_finalize(struct refresh_data *data)
IXFRIN_LOG(LOG_WARNING, data->zone->name, data->remote, IXFRIN_LOG(LOG_WARNING, data->zone->name, data->remote,
"failed to write changes to journal (%s)", "failed to write changes to journal (%s)",
knot_strerror(ret)); knot_strerror(ret));
update_rollback(&ctx); update_rollback(ctx);
update_free_zone(&new_zone); update_free_zone(&new_zone);
free(ctx);
return ret; return ret;
} }
zone_contents_t *old_zone = zone_switch_contents(data->zone, new_zone); zone_contents_t *old_zone = zone_switch_contents(data->zone, new_zone);
xfr_log_publish(data->zone->name, data->remote, old_zone, new_zone); xfr_log_publish(data->zone->name, data->remote, old_zone, new_zone);
synchronize_rcu(); ctx->contents = old_zone;
callrcu_wrapper(ctx, ixfr_finalize_cleanup);
update_free_zone(&old_zone);
update_cleanup(&ctx);
return KNOT_EOK; return KNOT_EOK;
} }
......
{
liburcu/call_rcu
Memcheck:Leak
match-leak-kinds: possible,reachable
fun:calloc
...
fun:call_rcu_memb
}
...@@ -167,6 +167,9 @@ class Test(object): ...@@ -167,6 +167,9 @@ class Test(object):
srv.valgrind = [params.valgrind_bin] + \ srv.valgrind = [params.valgrind_bin] + \
params.valgrind_flags.split() + \ params.valgrind_flags.split() + \
["--log-file=%s" % srv.valgrind_log] ["--log-file=%s" % srv.valgrind_log]
suppressions_file = "%s/%s.supp" % (params.common_data_dir, server)
if os.path.isfile(suppressions_file):
srv.valgrind.append("--suppressions=%s" % suppressions_file)
self.servers.add(srv) self.servers.add(srv)
return srv return srv
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment