lib/kunit/bug.c

Source file repositories/reference/linux-study-clean/lib/kunit/bug.c

File Facts

System
Linux kernel
Corpus path
lib/kunit/bug.c
Extension
.c
Size
2930 bytes
Lines
121
Domain
Kernel Services
Bucket
lib
Inferred role
Kernel Services: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.

Dependency Surface

Detected Declarations

Annotated Snippet

struct kunit_suppressed_warning {
	struct list_head node;
	struct task_struct *task;
	struct kunit *test;
	atomic_t counter;
};

static LIST_HEAD(suppressed_warnings);
static DEFINE_SPINLOCK(suppressed_warnings_lock);

static void kunit_suppress_warning_remove(struct kunit_suppressed_warning *w)
{
	unsigned long flags;

	spin_lock_irqsave(&suppressed_warnings_lock, flags);
	list_del_rcu(&w->node);
	spin_unlock_irqrestore(&suppressed_warnings_lock, flags);
	put_task_struct(w->task);
}

KUNIT_DEFINE_ACTION_WRAPPER(kunit_suppress_warning_cleanup,
			    kunit_suppress_warning_remove,
			    struct kunit_suppressed_warning *);

bool kunit_has_active_suppress_warning(void)
{
	return __kunit_is_suppressed_warning_impl(false);
}
EXPORT_SYMBOL_GPL(kunit_has_active_suppress_warning);

struct kunit_suppressed_warning *
kunit_start_suppress_warning(struct kunit *test)
{
	struct kunit_suppressed_warning *w;
	unsigned long flags;
	int ret;

	if (kunit_has_active_suppress_warning()) {
		KUNIT_FAIL(test, "Another suppression block is already active");
		return NULL;
	}

	w = kunit_kzalloc(test, sizeof(*w), GFP_KERNEL);
	if (!w) {
		KUNIT_FAIL(test, "Failed to allocate suppression handle.");
		return NULL;
	}

	w->task = get_task_struct(current);
	w->test = test;

	spin_lock_irqsave(&suppressed_warnings_lock, flags);
	list_add_rcu(&w->node, &suppressed_warnings);
	spin_unlock_irqrestore(&suppressed_warnings_lock, flags);

	ret = kunit_add_action_or_reset(test,
					kunit_suppress_warning_cleanup, w);
	if (ret) {
		KUNIT_FAIL(test, "Failed to add suppression cleanup action.");
		return NULL;
	}

	return w;
}
EXPORT_SYMBOL_GPL(kunit_start_suppress_warning);

void kunit_end_suppress_warning(struct kunit *test,
				struct kunit_suppressed_warning *w)
{
	if (!w)
		return;
	kunit_release_action(test, kunit_suppress_warning_cleanup, w);
}
EXPORT_SYMBOL_GPL(kunit_end_suppress_warning);

void __kunit_suppress_auto_cleanup(struct kunit_suppressed_warning **wp)
{
	if (*wp)
		kunit_end_suppress_warning((*wp)->test, *wp);
}
EXPORT_SYMBOL_GPL(__kunit_suppress_auto_cleanup);

int kunit_suppressed_warning_count(struct kunit_suppressed_warning *w)
{
	return w ? atomic_read(&w->counter) : 0;
}
EXPORT_SYMBOL_GPL(kunit_suppressed_warning_count);

bool __kunit_is_suppressed_warning_impl(bool count)
{

Annotation

Implementation Notes