diff options
author | Rickard Green <rickard@erlang.org> | 2020-01-29 14:30:28 +0100 |
---|---|---|
committer | Rickard Green <rickard@erlang.org> | 2020-01-31 14:54:16 +0100 |
commit | 258e0e7955f99e49f76bb3a66ab2275cc27e45fd (patch) | |
tree | 345b922ae828375174bba8fe9d6cabe7fbae8c7b | |
parent | db6059a9217767a6e42e93cec05089c0ec977d20 (diff) | |
download | erlang-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.c | 8 | ||||
-rw-r--r-- | erts/emulator/test/process_SUITE.erl | 15 |
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 |