Skip to content
Snippets Groups Projects
Commit 3e157c8b authored by Piotr Balcer's avatar Piotr Balcer
Browse files

obj: fix recycler not locating unused chunks


In scenarios where free() is done very rarely the memory in the recycler
would not be looked at because the estimates would indicate that no memory
was freed and there's no reason to search the tree. Normally that's OK,
because eventually the heap would trigger a forced search of the entire
recycler for the allocation class, locating all the memory that might have
been missed. But, the forced recalculation erronously looked at the
estimates and required that at least some memory were freed since the
last recycler run - which might have not been the case.
This patch makes the forced recycling run without looking at the estimates.

Reported-by: default avatarDenny Zhao <denny.zhao@memverge.com>
parent c819d297
No related branches found
No related tags found
No related merge requests found
/* /*
* Copyright 2016-2018, Intel Corporation * Copyright 2016-2019, Intel Corporation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -285,7 +285,7 @@ recycler_recalc(struct recycler *r, int force) ...@@ -285,7 +285,7 @@ recycler_recalc(struct recycler *r, int force)
uint64_t units = r->unaccounted_total; uint64_t units = r->unaccounted_total;
if (units == 0 || (!force && units < (r->recalc_threshold))) if (!force && units < r->recalc_threshold)
return runs; return runs;
if (util_mutex_trylock(&r->lock) != 0) if (util_mutex_trylock(&r->lock) != 0)
......
#!/usr/bin/env bash
#
# Copyright 2019, Intel Corporation
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# * Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
. ../unittest/unittest.sh
# too large
configure_valgrind force-disable
require_test_type medium
# runs too long on debug builds
require_build_type nondebug
setup
create_holey_file 64G $DIR/testfile1
PMEM_IS_PMEM_FORCE=1 PMEM_NO_FLUSH=1 expect_normal_exit\
./obj_zones$EXESUFFIX $DIR/testfile1 f
check
pass
/* /*
* Copyright 2015-2018, Intel Corporation * Copyright 2015-2019, Intel Corporation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -92,6 +92,46 @@ test_open(const char *path) ...@@ -92,6 +92,46 @@ test_open(const char *path)
pmemobj_close(pop); pmemobj_close(pop);
} }
/*
* test_malloc_free -- test if alloc until OOM/free/alloc until OOM sequence
* produces the same number of allocations for the second alloc loop.
*/
static void
test_malloc_free(const char *path)
{
PMEMobjpool *pop = NULL;
if ((pop = pmemobj_create(path, LAYOUT_NAME,
0, S_IWUSR | S_IRUSR)) == NULL)
UT_FATAL("!pmemobj_create: %s", path);
size_t alloc_size = 128 * 1024;
size_t max_allocs = 1000000;
PMEMoid *oid = MALLOC(sizeof(PMEMoid) * max_allocs);
size_t n = 0;
while (1) {
if (pmemobj_alloc(pop, &oid[n], alloc_size, 0, NULL, NULL) != 0)
break;
n++;
UT_ASSERTne(n, max_allocs);
}
size_t first_run_allocated = n;
for (size_t i = 0; i < n; ++i) {
pmemobj_free(&oid[i]);
}
n = 0;
while (1) {
if (pmemobj_alloc(pop, &oid[n], alloc_size, 0, NULL, NULL) != 0)
break;
n++;
}
UT_ASSERTeq(first_run_allocated, n);
pmemobj_close(pop);
FREE(oid);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
...@@ -106,6 +146,8 @@ main(int argc, char *argv[]) ...@@ -106,6 +146,8 @@ main(int argc, char *argv[])
test_create(path); test_create(path);
else if (op == 'o') else if (op == 'o')
test_open(path); test_open(path);
else if (op == 'f')
test_malloc_free(path);
else else
UT_FATAL("invalid operation"); UT_FATAL("invalid operation");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment