File 0438-erts-Fix-ets-memstat-false-leak-of-FixedDeletion.patch of Package erlang
From 4253f875c73c577a768847639e9d2411f935d4d2 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Mon, 3 Sep 2018 20:05:32 +0200
Subject: [PATCH 1/2] erts: Fix ets memstat false leak of FixedDeletion
causing erlang:memory to report too much ets memory.
---
erts/emulator/beam/erl_db_hash.c | 1 +
lib/stdlib/test/ets_SUITE.erl | 45 ++++++++++++++++++++++++++++++++++++++--
2 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c
index b988a19cf4..b648965885 100644
--- a/erts/emulator/beam/erl_db_hash.c
+++ b/erts/emulator/beam/erl_db_hash.c
@@ -162,6 +162,7 @@ static ERTS_INLINE int link_fixdel(DbTableHash* tb,
if (NFIXED(tb) <= fixated_by_me) {
erts_db_free(ERTS_ALC_T_DB_FIX_DEL, (DbTable*)tb,
fixd, sizeof(FixedDeletion));
+ ERTS_ETS_MISC_MEM_ADD(-sizeof(FixedDeletion));
return 0; /* raced by unfixer */
}
exp_next = was_next;
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl
index 7a48d1d55e..d8912e548c 100644
--- a/lib/stdlib/test/ets_SUITE.erl
+++ b/lib/stdlib/test/ets_SUITE.erl
@@ -64,7 +64,7 @@
meta_lookup_named_read/1, meta_lookup_named_write/1,
meta_newdel_unnamed/1, meta_newdel_named/1]).
-export([smp_insert/1, smp_fixed_delete/1, smp_unfix_fix/1, smp_select_delete/1,
- otp_8166/1, otp_8732/1]).
+ otp_8166/1, otp_8732/1, delete_unfix_race/1]).
-export([exit_large_table_owner/1,
exit_many_large_table_owner/1,
exit_many_tables_owner/1,
@@ -156,6 +156,7 @@ all() ->
otp_9423,
ets_all,
take,
+ delete_unfix_race,
memory_check_summary]. % MUST BE LAST
@@ -5190,6 +5191,46 @@ smp_fixed_delete_do() ->
%%verify_table_load(T),
ets:delete(T).
+%% ERL-720
+%% Provoke race between ets:delete and table unfix (by select_count)
+%% that caused ets_misc memory counter to indicate false leak.
+delete_unfix_race(Config) when is_list(Config) ->
+ EtsMem = etsmem(),
+ Table = ets:new(t,[set,public,{write_concurrency,true}]),
+ InsertOp =
+ fun() ->
+ receive stop ->
+ false
+ after 0 ->
+ ets:insert(Table, {rand:uniform(10)}),
+ true
+ end
+ end,
+ DeleteOp =
+ fun() ->
+ receive stop ->
+ false
+ after 0 ->
+ ets:delete(Table, rand:uniform(10)),
+ true
+ end
+ end,
+ SelectOp =
+ fun() ->
+ ets:select_count(Table, ets:fun2ms(fun(X) -> true end))
+ end,
+ Main = self(),
+ Ins = spawn(fun()-> repeat_while(InsertOp), Main ! self() end),
+ Del = spawn(fun()-> repeat_while(DeleteOp), Main ! self() end),
+ spawn(fun()->
+ repeat(SelectOp, 10000),
+ Del ! stop,
+ Ins ! stop
+ end),
+ [receive Pid -> ok end || Pid <- [Ins,Del]],
+ ets:delete(Table),
+ verify_etsmem(EtsMem).
+
num_of_buckets(T) ->
element(1,ets:info(T,stats)).
--
2.16.4