summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRickard Green <rickard@erlang.org>2020-01-29 14:30:28 +0100
committerRickard Green <rickard@erlang.org>2020-01-31 14:54:16 +0100
commit258e0e7955f99e49f76bb3a66ab2275cc27e45fd (patch)
tree345b922ae828375174bba8fe9d6cabe7fbae8c7b
parentdb6059a9217767a6e42e93cec05089c0ec977d20 (diff)
downloaderlang-258e0e7955f99e49f76bb3a66ab2275cc27e45fd.tar.gz
Prevent endless reschedule of sys-task due to high prio dirty-job
Higher prio dirty-job in combination with lower prio sys-task could cause an endless rescheduling of the sys-task without making any progress. This since we refuse to execute on a dirty scheduler if we got sys-tasks as well as refuse to execute lower prio sys-tasks if we got other higher prio work to do. Solved by executing lower prio sys-task even though we got higher prio dirty-jobs. This since it is non-trivial to reschedule already scheduled sys-tasks for handling while executing dirty and we do not now how long time it takes until we return from dirty work.
-rw-r--r--erts/emulator/beam/erl_process.c8
-rw-r--r--erts/emulator/test/process_SUITE.erl15
2 files changed, 19 insertions, 4 deletions
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 9f6adb03d0..42a310d60a 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -11077,10 +11077,14 @@ fetch_sys_task(Process *c_p, erts_aint32_t state, int *qmaskp, int *priop)
qmask = c_p->sys_task_qs->qmask;
- if ((state & (ERTS_PSFLG_ACTIVE
+ if ((state & (ERTS_PSFLGS_DIRTY_WORK
+ | ERTS_PSFLG_ACTIVE
| ERTS_PSFLG_EXITING
| ERTS_PSFLG_SUSPENDED)) == ERTS_PSFLG_ACTIVE) {
- /* No sys tasks if we got exclusively higher prio user work to do */
+ /*
+ * No sys tasks if we got exclusively higher prio user work
+ * to do; ignoring dirty work...
+ */
st = NULL;
switch (ERTS_PSFLGS_GET_USR_PRIO(state)) {
case PRIORITY_MAX:
diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl
index a8bcfac84d..8b3e85e9f0 100644
--- a/erts/emulator/test/process_SUITE.erl
+++ b/erts/emulator/test/process_SUITE.erl
@@ -59,7 +59,8 @@
system_task_blast/1,
system_task_on_suspended/1,
gc_request_when_gc_disabled/1,
- gc_request_blast_when_gc_disabled/1]).
+ gc_request_blast_when_gc_disabled/1,
+ otp_16436/1]).
-export([prio_server/2, prio_client/2, init/1, handle_event/2]).
-export([init_per_testcase/2, end_per_testcase/2]).
@@ -105,7 +106,8 @@ groups() ->
{system_task, [],
[no_priority_inversion, no_priority_inversion2,
system_task_blast, system_task_on_suspended,
- gc_request_when_gc_disabled, gc_request_blast_when_gc_disabled]}].
+ gc_request_when_gc_disabled, gc_request_blast_when_gc_disabled,
+ otp_16436]}].
init_per_suite(Config) ->
A0 = case application:start(sasl) of
@@ -2600,6 +2602,15 @@ gc_request_blast_when_gc_disabled(Config) when is_list(Config) ->
receive {'DOWN', M, process, P, _Reason} -> ok end,
ok.
+otp_16436(Config) when is_list(Config) ->
+ P = spawn_opt(fun () ->
+ erts_debug:dirty_io(wait, 1000)
+ end,
+ [{priority,high},link]),
+ erlang:check_process_code(P, non_existing),
+ unlink(P),
+ exit(P, kill),
+ ok.
%% Internal functions