2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-25 19:47:42 +00:00

209 Commits

Author SHA1 Message Date
Witold Kręcicki
23bd04d2f1 Make isc_task_pause/isc_task_unpause thread safe.
isc_task_pause/unpause were inherently thread-unsafe - a task
could be paused only once by one thread, if the task was running
while we paused it it led to races. Fix it by making sure that
the task will pause if requested to, and by using a 'pause reference
counter' to count task pause requests - a task will be unpaused
iff all threads unpause it.

Don't remove from queue when pausing task - we lock the queue lock
(expensive), while it's unlikely that the task will be running -
and we'll remove it anyway in dispatcher
2020-02-18 09:22:04 +00:00
Ondřej Surý
5777c44ad0 Reformat using the new rules 2020-02-14 09:31:05 +01:00
Evan Hunt
e851ed0bb5 apply the modified style 2020-02-13 15:05:06 -08:00
Ondřej Surý
056e133c4c Use clang-tidy to add curly braces around one-line statements
The command used to reformat the files in this commit was:

./util/run-clang-tidy \
	-clang-tidy-binary clang-tidy-11
	-clang-apply-replacements-binary clang-apply-replacements-11 \
	-checks=-*,readability-braces-around-statements \
	-j 9 \
	-fix \
	-format \
	-style=file \
	-quiet
clang-format -i --style=format $(git ls-files '*.c' '*.h')
uncrustify -c .uncrustify.cfg --replace --no-backup $(git ls-files '*.c' '*.h')
clang-format -i --style=format $(git ls-files '*.c' '*.h')
2020-02-13 22:07:21 +01:00
Ondřej Surý
f50b1e0685 Use clang-format to reformat the source files 2020-02-12 15:04:17 +01:00
Ondřej Surý
bc1d4c9cb4 Clear the pointer to destroyed object early using the semantic patch
Also disable the semantic patch as the code needs tweaks here and there because
some destroy functions might not destroy the object and return early if the
object is still in use.
2020-02-09 18:00:17 -08:00
Witold Kręcicki
e1c4a69197 Fix a race in taskmgr between worker and task pausing/unpausing.
To reproduce the race - create a task, send two events to it, first one
must take some time. Then, from the outside, pause(), unpause() and detach()
the task.
When the long-running event is processed by the task it is in
task_state_running state. When we called pause() the state changed to
task_state_paused, on unpause we checked that there are events in the task
queue, changed the state to task_state_ready and enqueued the task on the
workers readyq. We then detach the task.
The dispatch() is done with processing the event, it processes the second
event in the queue, and then shuts down the task and frees it (as it's not
referenced anymore). Dispatcher then takes the, already freed, task from
the queue where it was wrongly put, causing an use-after free and,
subsequently, either an assertion failure or a segmentation fault.
The probability of this happening is very slim, yet it might happen under a
very high load, more probably on a recursive resolver than on an
authoritative.
The fix introduces a new 'task_state_pausing' state - to which tasks
are moved if they're being paused while still running. They are moved
to task_state_paused state when dispatcher is done with them, and
if we unpause a task in paused state it's moved back to task_state_running
and not requeued.
2020-01-21 10:06:19 +01:00
Ondřej Surý
fbf9856f43 Add isc_refcount_destroy() as appropriate 2020-01-14 13:12:13 +01:00
Ondřej Surý
5746172da3 Convert task flags to C11 atomics 2019-12-13 07:10:25 +01:00
Witold Kręcicki
5ce4b04b50 If a task is running and we call isc_task_pause it can
be implicitly unpaused when we switch from 'running' to
'idle' state. Fix it by not switching to 'idle' when paused.
2019-11-13 12:32:17 +00:00
Evan Hunt
59c64fa4bd add isc_task_pause() and isc_task_unpause() functions
This allows a task to be temporary disabled so that objects won't be
processed simultaneously by libuv events and isc_task events. When a
task is paused, currently running events may complete, but no further
event will added to the run queue will be executed until the task is
unpaused.
2019-11-07 11:55:37 -08:00
Evan Hunt
36ee430327 optionally associate a netmgr with a task manager when creating
When a task manager is created, we can now specify an `isc_nm`
object to associate with it; thereafter when the task manager is
placed into exclusive mode, the network manager will be paused.
2019-11-07 11:55:37 -08:00
Witold Kręcicki
70397f9d92 netmgr: libuv-based network manager
This is a replacement for the existing isc_socket and isc_socketmgr
implementation. It uses libuv for asynchronous network communication;
"networker" objects will be distributed across worker threads reading
incoming packets and sending them for processing.

UDP listener sockets automatically create an array of "child" sockets
so each worker can listen separately.

TCP sockets are shared amongst worker threads.

A TCPDNS socket is a wrapper around a TCP socket, which handles the
the two-byte length field at the beginning of DNS messages over TCP.

(Other wrapper socket types can be implemented in the future to handle
DNS over TLS, DNS over HTTPS, etc.)
2019-11-07 11:55:37 -08:00
Ondřej Surý
c662969da1 lib/isc/task.c: Fix invalid order of DbC checks that could cause dereference before NULL check 2019-10-03 09:04:27 +02:00
Ondřej Surý
50e109d659 isc_event_allocate() cannot fail, remove the fail handling blocks
isc_event_allocate() calls isc_mem_get() to allocate the event structure.  As
isc_mem_get() cannot fail softly (e.g. it never returns NULL), the
isc_event_allocate() cannot return NULL, hence we remove the (ret == NULL)
handling blocks using the semantic patch from the previous commit.
2019-08-30 08:55:34 +02:00
Ondřej Surý
46919579bb Make isc_thread_join() assert internally on failure
Previously isc_thread_join() would return ISC_R_UNEXPECTED on a failure to
create new thread.  All such occurences were caught and wrapped into assert
function at higher level.  The function was simplified to assert directly in the
isc_thread_join() function and all caller level assertions were removed.
2019-07-31 11:56:58 +02:00
Ondřej Surý
d6a60f2905 Make isc_thread_create() assert internally on failure
Previously isc_thread_create() would return ISC_R_UNEXPECTED on a failure to
create new thread.  All such occurences were caught and wrapped into assert
function at higher level.  The function was simplified to assert directly in the
isc_thread_create() function and all caller level assertions were removed.
2019-07-31 11:56:58 +02:00
Ondřej Surý
ae83801e2b Remove blocks checking whether isc_mem_get() failed using the coccinelle 2019-07-23 15:32:35 -04:00
Witold Kręcicki
e56cc07f50 Fix a few broken atomics initializations 2019-07-09 16:11:14 +02:00
Ondřej Surý
c0511688b5 lib/isc/task.c: use isc_refcount_t 2019-07-09 16:11:14 +02:00
Witold Kręcicki
5aeb99786e Properly initialize all atomic variables 2019-07-09 16:09:36 +02:00
Witold Kręcicki
b56948743a lib/isc/task: use isc_refcount_t 2019-07-09 16:09:36 +02:00
Ondřej Surý
e3e6888946 Make the usage of json-c objects opaque to the caller
The json-c have previously leaked into the global namespace leading
to forced -I<include_path> for every compilation unit using isc/xml.h
header.  This MR fixes the usage making the caller object opaque.
2019-06-25 12:04:20 +02:00
Ondřej Surý
0771dd3be8 Make the usage of libxml2 opaque to the caller
The libxml2 have previously leaked into the global namespace leading
to forced -I<include_path> for every compilation unit using isc/xml.h
header.  This MR fixes the usage making the caller object opaque.
2019-06-25 12:01:32 +02:00
Michał Kępień
ce796ac1f4 Address GCC 9.1 -O3 compilation warnings
Compiling with -O3 triggers the following warnings with GCC 9.1:

    task.c: In function ‘isc_taskmgr_create’:
    task.c:1384:43: warning: ‘%04u’ directive output may be truncated writing between 4 and 10 bytes into a region of size 6 [-Wformat-truncation=]
     1384 |   snprintf(name, sizeof(name), "isc-worker%04u", i);
          |                                           ^~~~
    task.c:1384:32: note: directive argument in the range [0, 4294967294]
     1384 |   snprintf(name, sizeof(name), "isc-worker%04u", i);
          |                                ^~~~~~~~~~~~~~~~
    task.c:1384:3: note: ‘snprintf’ output between 15 and 21 bytes into a destination of size 16
     1384 |   snprintf(name, sizeof(name), "isc-worker%04u", i);
          |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    private_test.c: In function ‘private_nsec3_totext_test’:
    private_test.c:110:9: warning: array subscript 4 is outside array bounds of ‘uint32_t[1]’ {aka ‘unsigned int[1]’} [-Warray-bounds]
      110 |  while (*sp == '\0' && slen > 0) {
          |         ^~~
    private_test.c:103:11: note: while referencing ‘salt’
      103 |  uint32_t salt;
          |           ^~~~

Prevent these warnings from being triggered by increasing the size of
the relevant array (task.c) and reordering conditions (private_test.c).
2019-06-11 10:18:23 +02:00
Ondřej Surý
4d2d3b49ce Cleanup the way we detect json-c library to use only pkg-config 2019-05-29 15:08:52 +02:00
Ondřej Surý
eb8c9bdd55 Make lib/isc/app.c opaque and thread-safe
This work cleans up the API which includes couple of things:

1. Make the isc_appctx_t type fully opaque

2. Protect all access to the isc_app_t members via stdatomics

3. sigwait() is part of POSIX.1, remove dead non-sigwait code

4. Remove unused code: isc_appctx_set{taskmgr,sockmgr,timermgr}
2019-05-20 18:13:02 +02:00
Ondřej Surý
78d0cb0a7d Use coccinelle to remove explicit '#include <config.h>' from the source files 2019-03-08 15:15:05 +01:00
Ondřej Surý
d3e0604354 Properly use atomic_compare_exchange instead of load/store 2019-01-30 13:48:58 +01:00
Witold Kręcicki
a003908af4 Fix a race in access to manager->tasks in taskmgr
Make taskmgr->mode and boolean state flags (exclusive, paused, exiting) atomic.
2019-01-29 03:32:29 -05:00
Ondřej Surý
e2cdf066ea Remove message catalogs 2019-01-09 23:44:26 +01:00
Witold Kręcicki
d5793ecca2 - isc_task_create_bound - create a task bound to specific task queue
If we know that we'll have a task pool doing specific thing it's better
  to use this knowledge and bind tasks to task queues, this behaves better
  than randomly choosing the task queue.

- use bound resolver tasks - we have a pool of tasks doing resolutions,
  we can spread the load evenly using isc_task_create_bound

- quantum set universally to 25
2018-11-23 04:34:02 -05:00
Witold Kręcicki
929ea7c2c4 - Make isc_mutex_destroy return void
- Make isc_mutexblock_init/destroy return void
- Minor cleanups
2018-11-22 11:52:08 +00:00
Ondřej Surý
2f3eee5a4f isc_mutex_init returns 'void' 2018-11-22 11:51:49 +00:00
Ondřej Surý
73a8999d1c isc_condition_init returns 'void' 2018-11-22 11:51:49 +00:00
Evan Hunt
1f0cd6606e style: one-line statement braces, line length, etc 2018-11-15 08:21:40 +00:00
Evan Hunt
3e52987229 convert task_test 2018-11-14 20:17:04 -08:00
Ondřej Surý
b2b43fd235 Turn (int & flag) into (int & flag) != 0 when implicitly typed to bool 2018-11-08 12:21:53 +07:00
Witold Kręcicki
460c8038c1 Use a single wake_all_queues() function to wake all queues 2018-11-06 08:19:50 +00:00
Witold Kręcicki
b3827319e0 Switch from privileged to un-privileged mode under lock 2018-11-06 08:19:50 +00:00
Witold Kręcicki
f166cabcae Document isc_task_sendto properly, make sure that cpu we're sending to is always sane 2018-11-06 08:19:50 +00:00
Witold Kręcicki
025c74adee Use proper memory ordering for tasks_running/tasks_ready 2018-11-06 08:19:50 +00:00
Witold Kręcicki
8fb5bc783f Comment about taskmgr exclusive mode, fix a REQUIRE. 2018-11-06 08:19:50 +00:00
Witold Kręcicki
913856911a Saner exclusive task handling in taskmgr 2018-11-06 08:19:50 +00:00
Witold Kręcicki
17d46fd48b Formatting 2018-11-06 08:19:50 +00:00
Witold Kręcicki
c80e25e482 Get rid of isc_taskmgr_setmode, we only use it to set privileged mode 2018-11-06 08:19:50 +00:00
Witold Kręcicki
64020dd7bc Make sure all priority tasks are done before entering normal execution 2018-11-06 08:19:50 +00:00
Witold Kręcicki
669a694d3b Post shutting down tasks always to manager 0 2018-11-06 08:19:50 +00:00
Witold Kręcicki
c416389d32 Separate structure for each thread/queue; 2-phase-locking for exclusive tasks 2018-11-06 08:19:50 +00:00
Witold Kręcicki
818d63a3a1 Always restart dispatchers on empty readyq 2018-11-06 08:19:50 +00:00