tests: add tests for waitqueue helpers.

Signed-off-by: Imran Khan <imran.f.khan@oracle.com>
This commit is contained in:
Imran Khan 2023-10-16 02:54:43 +11:00 committed by Omar Sandoval
parent fb87916331
commit 79a1ea2a33
2 changed files with 64 additions and 0 deletions

View File

@ -0,0 +1,24 @@
# Copyright (c) 2023, Oracle and/or its affiliates.
# SPDX-License-Identifier: LGPL-2.1-or-later
from drgn.helpers.linux.wait import waitqueue_active, waitqueue_for_each_task
from tests.linux_kernel import LinuxKernelTestCase, skip_unless_have_test_kmod
@skip_unless_have_test_kmod
class TestWaitqueue(LinuxKernelTestCase):
@classmethod
def setUpClass(cls):
cls.waitq = cls.prog["drgn_test_waitq"].address_of_()
cls.empty_waitq = cls.prog["drgn_test_empty_waitq"].address_of_()
def test_waitqueue_active(self):
self.assertTrue(waitqueue_active(self.waitq))
self.assertFalse(waitqueue_active(self.empty_waitq))
def test_waitqueue_for_each_task(self):
self.assertEqual(list(waitqueue_for_each_task(self.empty_waitq)), [])
self.assertEqual(
list(waitqueue_for_each_task(self.waitq)),
[self.prog["drgn_test_waitq_kthread"]],
)

View File

@ -32,6 +32,7 @@
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/wait.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)
#define HAVE_XARRAY 1 #define HAVE_XARRAY 1
#include <linux/xarray.h> #include <linux/xarray.h>
@ -1035,6 +1036,40 @@ static void drgn_test_idr_exit(void)
idr_destroy(&drgn_test_idr_sparse); idr_destroy(&drgn_test_idr_sparse);
} }
// wait-queue
static struct task_struct *drgn_test_waitq_kthread;
static wait_queue_head_t drgn_test_waitq;
static wait_queue_head_t drgn_test_empty_waitq;
static int drgn_test_waitq_kthread_fn(void *arg)
{
wait_event_interruptible(drgn_test_waitq, kthread_should_stop());
return 0;
}
static int drgn_test_waitq_init(void)
{
init_waitqueue_head(&drgn_test_waitq);
init_waitqueue_head(&drgn_test_empty_waitq);
drgn_test_waitq_kthread = kthread_create(drgn_test_waitq_kthread_fn,
NULL,
"drgn_test_waitq_kthread");
if (!drgn_test_waitq_kthread)
return -1;
wake_up_process(drgn_test_waitq_kthread);
return 0;
}
static void drgn_test_waitq_exit(void)
{
if (drgn_test_waitq_kthread) {
kthread_stop(drgn_test_waitq_kthread);
drgn_test_waitq_kthread = NULL;
}
}
// Dummy function symbol. // Dummy function symbol.
int drgn_test_function(int x) int drgn_test_function(int x)
{ {
@ -1051,6 +1086,7 @@ static void drgn_test_exit(void)
drgn_test_stack_trace_exit(); drgn_test_stack_trace_exit();
drgn_test_radix_tree_exit(); drgn_test_radix_tree_exit();
drgn_test_xarray_exit(); drgn_test_xarray_exit();
drgn_test_waitq_exit();
drgn_test_idr_exit(); drgn_test_idr_exit();
} }
@ -1083,6 +1119,10 @@ static int __init drgn_test_init(void)
if (ret) if (ret)
goto out; goto out;
ret = drgn_test_xarray_init(); ret = drgn_test_xarray_init();
if (ret)
goto out;
ret = drgn_test_waitq_init();
if (ret) if (ret)
goto out; goto out;
ret = drgn_test_idr_init(); ret = drgn_test_idr_init();