summaryrefslogtreecommitdiff
path: root/sysdep
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2023-04-24 10:39:13 +0200
committerMaria Matejka <mq@ucw.cz>2023-04-24 10:39:13 +0200
commitfa8848aca3f0473412f3ae6288d71dee8458bcfa (patch)
tree20aa1c64f866079684f4923f857021baff4d2b53 /sysdep
parent942d3cbcdd548a73ecc1915a97e297e9bf0bb5e6 (diff)
parent22f54eaee6c6dbe12ad7bb0ee1da09e3e026b970 (diff)
Merge branch 'mq-resource-locking' into thread-next
Diffstat (limited to 'sysdep')
-rw-r--r--sysdep/bsd/krt-sock.c4
-rw-r--r--sysdep/unix/io-loop.c99
-rw-r--r--sysdep/unix/io.c2
-rw-r--r--sysdep/unix/krt.c2
4 files changed, 74 insertions, 33 deletions
diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c
index 094268b7..6bf756ff 100644
--- a/sysdep/bsd/krt-sock.c
+++ b/sysdep/bsd/krt-sock.c
@@ -1118,7 +1118,7 @@ krt_sock_close_shared(void)
if (!krt_sock_count)
{
- rfree(krt_sock);
+ sk_close(krt_sock);
krt_sock = NULL;
}
}
@@ -1181,7 +1181,7 @@ krt_sys_shutdown(struct krt_proto *p)
{
krt_table_cf[(KRT_CF->sys.table_id)/32][!!(p->af == AF_INET6)] &= ~(1 << ((KRT_CF->sys.table_id)%32));
- rfree(p->sys.sk);
+ sk_close(p->sys.sk);
p->sys.sk = NULL;
krt_buffer_release(&p->p);
diff --git a/sysdep/unix/io-loop.c b/sysdep/unix/io-loop.c
index efb408e0..8e95a698 100644
--- a/sysdep/unix/io-loop.c
+++ b/sysdep/unix/io-loop.c
@@ -31,7 +31,7 @@
#define THREAD_STACK_SIZE 65536 /* To be lowered in near future */
-static struct birdloop *birdloop_new_internal(pool *pp, uint order, const char *name, int request_pickup, struct birdloop_pickup_group *group);
+static struct birdloop *birdloop_new_no_pickup(pool *pp, uint order, const char *name, ...);
/*
* Nanosecond time for accounting purposes
@@ -87,6 +87,12 @@ birdloop_time_loop(struct birdloop *loop)
return &loop->time;
}
+pool *
+birdloop_pool(struct birdloop *loop)
+{
+ return loop->pool;
+}
+
_Bool
birdloop_inside(struct birdloop *loop)
{
@@ -497,12 +503,14 @@ sockets_fire(struct birdloop *loop)
*/
DEFINE_DOMAIN(resource);
+static void bird_thread_start_event(void *_data);
struct birdloop_pickup_group {
DOMAIN(resource) domain;
list loops;
list threads;
btime max_latency;
+ event start_threads;
} pickup_groups[2] = {
{
/* all zeroes */
@@ -510,6 +518,8 @@ struct birdloop_pickup_group {
{
/* FIXME: make this dynamic, now it copies the loop_max_latency value from proto/bfd/config.Y */
.max_latency = 10 MS,
+ .start_threads.hook = bird_thread_start_event,
+ .start_threads.data = &pickup_groups[1],
},
};
@@ -624,13 +634,11 @@ bird_thread_main(void *arg)
rcu_thread_start(&thr->rcu);
synchronize_rcu();
- tmp_init(thr->pool);
- init_list(&thr->loops);
-
- thr->meta = birdloop_new_internal(thr->pool, DOMAIN_ORDER(meta), "Thread Meta", 0, thr->group);
- thr->meta->thread = thr;
birdloop_enter(thr->meta);
+ tmp_init(thr->pool, birdloop_domain(thr->meta));
+ init_list(&thr->loops);
+
thr->sock_changed = 1;
struct pfd pfd;
@@ -746,22 +754,27 @@ bird_thread_cleanup(void *_thr)
pthread_attr_destroy(&thr->thread_attr);
/* Free all remaining memory */
- rfree(thr->pool);
+ rp_free(thr->pool);
}
static struct bird_thread *
bird_thread_start(struct birdloop_pickup_group *group)
{
ASSERT_DIE(birdloop_inside(&main_birdloop));
- ASSERT_DIE(DOMAIN_IS_LOCKED(resource, group->domain));
- pool *p = rp_new(&root_pool, "Thread");
+ struct birdloop *meta = birdloop_new_no_pickup(&root_pool, DOMAIN_ORDER(meta), "Thread Meta");
+ pool *p = birdloop_pool(meta);
+
+ birdloop_enter(meta);
+ LOCK_DOMAIN(resource, group->domain);
struct bird_thread *thr = mb_allocz(p, sizeof(*thr));
thr->pool = p;
thr->cleanup_event = (event) { .hook = bird_thread_cleanup, .data = thr, };
thr->group = group;
thr->max_latency_ns = (group->max_latency ?: 5 S) TO_NS;
+ thr->meta = meta;
+ thr->meta->thread = thr;
wakeup_init(thr);
ev_init_list(&thr->priority_events, NULL, "Thread direct event list");
@@ -784,9 +797,18 @@ bird_thread_start(struct birdloop_pickup_group *group)
if (e = pthread_create(&thr->thread_id, &thr->thread_attr, bird_thread_main, thr))
die("pthread_create() failed: %M", e);
+ UNLOCK_DOMAIN(resource, group->domain);
+ birdloop_leave(meta);
return thr;
}
+static void
+bird_thread_start_event(void *_data)
+{
+ struct birdloop_pickup_group *group = _data;
+ bird_thread_start(group);
+}
+
static struct birdloop *thread_dropper;
static event *thread_dropper_event;
static uint thread_dropper_goal;
@@ -839,7 +861,7 @@ bird_thread_shutdown(void * _ UNUSED)
/* Stop the meta loop */
birdloop_leave(thr->meta);
domain_free(thr->meta->time.domain);
- rfree(thr->meta->pool);
+ rp_free(thr->meta->pool);
/* Local pages not needed anymore */
flush_local_pages();
@@ -874,18 +896,17 @@ bird_thread_commit(struct config *new, struct config *old UNUSED)
int dif = list_length(&group->threads) - (thread_dropper_goal = new->thread_count);
_Bool thread_dropper_running = !!thread_dropper;
+ UNLOCK_DOMAIN(resource, group->domain);
+
if (dif < 0)
{
bird_thread_start(group);
- UNLOCK_DOMAIN(resource, group->domain);
continue;
}
- UNLOCK_DOMAIN(resource, group->domain);
-
if ((dif > 0) && !thread_dropper_running)
{
- struct birdloop *tdl = birdloop_new(&root_pool, DOMAIN_ORDER(control), "Thread dropper", group->max_latency);
+ struct birdloop *tdl = birdloop_new(&root_pool, DOMAIN_ORDER(control), group->max_latency, "Thread dropper");
event *tde = ev_new_init(tdl->pool, bird_thread_shutdown, NULL);
LOCK_DOMAIN(resource, group->domain);
@@ -990,7 +1011,7 @@ bird_thread_show(void *data)
cli_write_trigger(tsd->cli);
DOMAIN_FREE(control, tsd->lock);
- rfree(tsd->pool);
+ rp_free(tsd->pool);
the_bird_unlock();
}
@@ -1000,12 +1021,13 @@ bird_thread_show(void *data)
void
cmd_show_threads(int show_loops)
{
- pool *p = rp_new(&root_pool, "Show Threads");
+ DOMAIN(control) lock = DOMAIN_NEW(control, "Show Threads");
+ pool *p = rp_new(&root_pool, lock.control, "Show Threads");
struct bird_thread_show_data *tsd = mb_allocz(p, sizeof(struct bird_thread_show_data));
- tsd->lock = DOMAIN_NEW(control, "Show Threads");
tsd->cli = this_cli;
tsd->pool = p;
+ tsd->lock = lock;
tsd->show_loops = show_loops;
this_cli->cont = bird_thread_show_cli_cont;
@@ -1106,8 +1128,10 @@ birdloop_stop_internal(struct birdloop *loop)
/* Request local socket reload */
this_thread->sock_changed++;
- /* Tail-call the stopped hook */
- loop->stopped(loop->stop_data);
+ /* Call the stopped hook from the main loop */
+ loop->event.hook = loop->stopped;
+ loop->event.data = loop->stop_data;
+ ev_send_loop(&main_birdloop, &loop->event);
}
static void
@@ -1178,11 +1202,12 @@ birdloop_run_timer(timer *tm)
}
static struct birdloop *
-birdloop_new_internal(pool *pp, uint order, const char *name, int request_pickup, struct birdloop_pickup_group *group)
+birdloop_vnew_internal(pool *pp, uint order, struct birdloop_pickup_group *group, const char *name, va_list args)
{
struct domain_generic *dg = domain_new(name, order);
+ DG_LOCK(dg);
- pool *p = rp_new(pp, name);
+ pool *p = rp_vnewf(pp, dg, name, args);
struct birdloop *loop = mb_allocz(p, sizeof(struct birdloop));
loop->pool = p;
@@ -1191,7 +1216,7 @@ birdloop_new_internal(pool *pp, uint order, const char *name, int request_pickup
atomic_store_explicit(&loop->thread_transition, 0, memory_order_relaxed);
- birdloop_enter(loop);
+ birdloop_enter_locked(loop);
ev_init_list(&loop->event_list, loop, name);
timers_init(&loop->time, p);
@@ -1200,13 +1225,12 @@ birdloop_new_internal(pool *pp, uint order, const char *name, int request_pickup
loop->event = (event) { .hook = birdloop_run, .data = loop, };
loop->timer = (timer) { .hook = birdloop_run_timer, .data = loop, };
- if (request_pickup)
+ if (group)
{
LOCK_DOMAIN(resource, group->domain);
add_tail(&group->loops, &loop->n);
if (EMPTY_LIST(group->threads))
- bird_thread_start(group);
-
+ ev_send(&global_event_list, &group->start_threads);
wakeup_do_kick(SKIP_BACK(struct bird_thread, n, HEAD(group->threads)));
UNLOCK_DOMAIN(resource, group->domain);
}
@@ -1218,10 +1242,24 @@ birdloop_new_internal(pool *pp, uint order, const char *name, int request_pickup
return loop;
}
+static struct birdloop *
+birdloop_new_no_pickup(pool *pp, uint order, const char *name, ...)
+{
+ va_list args;
+ va_start(args, name);
+ struct birdloop *loop = birdloop_vnew_internal(pp, order, NULL, name, args);
+ va_end(args);
+ return loop;
+}
+
struct birdloop *
-birdloop_new(pool *pp, uint order, const char *name, btime max_latency)
+birdloop_new(pool *pp, uint order, btime max_latency, const char *name, ...)
{
- return birdloop_new_internal(pp, order, name, 1, max_latency ? &pickup_groups[1] : &pickup_groups[0]);
+ va_list args;
+ va_start(args, name);
+ struct birdloop *loop = birdloop_vnew_internal(pp, order, max_latency ? &pickup_groups[1] : &pickup_groups[0], name, args);
+ va_end(args);
+ return loop;
}
static void
@@ -1257,8 +1295,11 @@ birdloop_free(struct birdloop *loop)
{
ASSERT_DIE(loop->thread == NULL);
- domain_free(loop->time.domain);
- rfree(loop->pool);
+ struct domain_generic *dg = loop->time.domain;
+ DG_LOCK(dg);
+ rp_free(loop->pool);
+ DG_UNLOCK(dg);
+ domain_free(dg);
}
static void
diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c
index 88d187a4..40a6f114 100644
--- a/sysdep/unix/io.c
+++ b/sysdep/unix/io.c
@@ -1081,7 +1081,7 @@ sk_passive_connected(sock *s, int type)
/* FIXME: handle it better in rfree() */
close(t->fd);
t->fd = -1;
- rfree(t);
+ sk_close(t);
return 1;
}
diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c
index 9e6ddb45..6e94b0b6 100644
--- a/sysdep/unix/krt.c
+++ b/sysdep/unix/krt.c
@@ -74,7 +74,7 @@ static list krt_proto_list;
void
krt_io_init(void)
{
- krt_pool = rp_new(&root_pool, "Kernel Syncer");
+ krt_pool = rp_new(&root_pool, the_bird_domain.the_bird, "Kernel Syncer");
krt_filter_lp = lp_new_default(krt_pool);
init_list(&krt_proto_list);
krt_sys_io_init();