1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright 2023 Red Hat
6 #include "thread-registry.h"
8 #include <asm/current.h>
9 #include <linux/rculist.h>
11 #include "permassert.h"
14 * We need to be careful when using other facilities that may use thread registry functions in
15 * their normal operation. For example, we do not want to invoke the logger while holding a lock.
18 void vdo_initialize_thread_registry(struct thread_registry
*registry
)
20 INIT_LIST_HEAD(®istry
->links
);
21 spin_lock_init(®istry
->lock
);
24 /* Register the current thread and associate it with a data pointer. */
25 void vdo_register_thread(struct thread_registry
*registry
,
26 struct registered_thread
*new_thread
, const void *pointer
)
28 struct registered_thread
*thread
;
29 bool found_it
= false;
31 INIT_LIST_HEAD(&new_thread
->links
);
32 new_thread
->pointer
= pointer
;
33 new_thread
->task
= current
;
35 spin_lock(®istry
->lock
);
36 list_for_each_entry(thread
, ®istry
->links
, links
) {
37 if (thread
->task
== current
) {
38 /* There should be no existing entry. */
39 list_del_rcu(&thread
->links
);
44 list_add_tail_rcu(&new_thread
->links
, ®istry
->links
);
45 spin_unlock(®istry
->lock
);
47 VDO_ASSERT_LOG_ONLY(!found_it
, "new thread not already in registry");
49 /* Ensure no RCU iterators see it before re-initializing. */
51 INIT_LIST_HEAD(&thread
->links
);
55 void vdo_unregister_thread(struct thread_registry
*registry
)
57 struct registered_thread
*thread
;
58 bool found_it
= false;
60 spin_lock(®istry
->lock
);
61 list_for_each_entry(thread
, ®istry
->links
, links
) {
62 if (thread
->task
== current
) {
63 list_del_rcu(&thread
->links
);
68 spin_unlock(®istry
->lock
);
70 VDO_ASSERT_LOG_ONLY(found_it
, "thread found in registry");
72 /* Ensure no RCU iterators see it before re-initializing. */
74 INIT_LIST_HEAD(&thread
->links
);
78 const void *vdo_lookup_thread(struct thread_registry
*registry
)
80 struct registered_thread
*thread
;
81 const void *result
= NULL
;
84 list_for_each_entry_rcu(thread
, ®istry
->links
, links
) {
85 if (thread
->task
== current
) {
86 result
= thread
->pointer
;