brintos

brintos / linux-shallow public Read only

0
0
Text · 2.2 KiB · d4a077d Raw
94 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright 2023 Red Hat4 */5 6#include "thread-registry.h"7 8#include <asm/current.h>9#include <linux/rculist.h>10 11#include "permassert.h"12 13/*14 * We need to be careful when using other facilities that may use thread registry functions in15 * their normal operation. For example, we do not want to invoke the logger while holding a lock.16 */17 18void vdo_initialize_thread_registry(struct thread_registry *registry)19{20	INIT_LIST_HEAD(&registry->links);21	spin_lock_init(&registry->lock);22}23 24/* Register the current thread and associate it with a data pointer. */25void vdo_register_thread(struct thread_registry *registry,26			 struct registered_thread *new_thread, const void *pointer)27{28	struct registered_thread *thread;29	bool found_it = false;30 31	INIT_LIST_HEAD(&new_thread->links);32	new_thread->pointer = pointer;33	new_thread->task = current;34 35	spin_lock(&registry->lock);36	list_for_each_entry(thread, &registry->links, links) {37		if (thread->task == current) {38			/* There should be no existing entry. */39			list_del_rcu(&thread->links);40			found_it = true;41			break;42		}43	}44	list_add_tail_rcu(&new_thread->links, &registry->links);45	spin_unlock(&registry->lock);46 47	VDO_ASSERT_LOG_ONLY(!found_it, "new thread not already in registry");48	if (found_it) {49		/* Ensure no RCU iterators see it before re-initializing. */50		synchronize_rcu();51		INIT_LIST_HEAD(&thread->links);52	}53}54 55void vdo_unregister_thread(struct thread_registry *registry)56{57	struct registered_thread *thread;58	bool found_it = false;59 60	spin_lock(&registry->lock);61	list_for_each_entry(thread, &registry->links, links) {62		if (thread->task == current) {63			list_del_rcu(&thread->links);64			found_it = true;65			break;66		}67	}68	spin_unlock(&registry->lock);69 70	VDO_ASSERT_LOG_ONLY(found_it, "thread found in registry");71	if (found_it) {72		/* Ensure no RCU iterators see it before re-initializing. */73		synchronize_rcu();74		INIT_LIST_HEAD(&thread->links);75	}76}77 78const void *vdo_lookup_thread(struct thread_registry *registry)79{80	struct registered_thread *thread;81	const void *result = NULL;82 83	rcu_read_lock();84	list_for_each_entry_rcu(thread, &registry->links, links) {85		if (thread->task == current) {86			result = thread->pointer;87			break;88		}89	}90	rcu_read_unlock();91 92	return result;93}94