More cleanup.

- Removed all references to kzt and replaced with splat
- Moved portions of include files which do not need to be
  available to all source files in to local.h files in 
  proper source subdirs.



git-svn-id: https://outreach.scidac.gov/svn/spl/trunk@14 7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c
This commit is contained in:
behlendo 2008-02-27 23:42:31 +00:00
parent 70eadc1958
commit 7c50328b40
16 changed files with 1123 additions and 1122 deletions

View File

@ -3,3 +3,4 @@ INCLUDES = -I$(top_srcdir)/include
sbin_PROGRAMS = splat
splat_SOURCES = splat.c
splat_LDFLAGS = $(top_builddir)/lib/libcommon.la
EXTRA_DIST = splat.h

View File

@ -28,11 +28,13 @@ static const struct option longOpts[] = {
{ 0, 0, 0, 0 }
};
#define VERSION_SIZE 64
static List subsystems; /* Subsystem/tests */
static int kztctl_fd; /* Control file descriptor */
static char kzt_version[KZT_VERSION_SIZE]; /* Kernel version string */
static char *kzt_buffer = NULL; /* Scratch space area */
static int kzt_buffer_size = 0; /* Scratch space size */
static int splatctl_fd; /* Control file descriptor */
static char splat_version[VERSION_SIZE]; /* Kernel version string */
static char *splat_buffer = NULL; /* Scratch space area */
static int splat_buffer_size = 0; /* Scratch space size */
static void test_list(List, int);
@ -42,7 +44,7 @@ static void test_fini(test_t *);
static int usage(void) {
fprintf(stderr, "usage: kzt [hvla] [-t <subsystem:<tests>>]\n");
fprintf(stderr, "usage: splat [hvla] [-t <subsystem:<tests>>]\n");
fprintf(stderr,
" --help -h This help\n"
" --verbose -v Increase verbosity\n"
@ -53,13 +55,13 @@ static int usage(void) {
" --nocolor -c Do not colorize output\n");
fprintf(stderr, "\n"
"Examples:\n"
" kzt -t kmem:all # Runs all kmem tests\n"
" kzt -t taskq:0x201 # Run taskq test 0x201\n");
" splat -t kmem:all # Runs all kmem tests\n"
" splat -t taskq:0x201 # Run taskq test 0x201\n");
return 0;
}
static subsystem_t *subsystem_init(kzt_user_t *desc)
static subsystem_t *subsystem_init(splat_user_t *desc)
{
subsystem_t *sub;
@ -86,25 +88,25 @@ static void subsystem_fini(subsystem_t *sub)
static int subsystem_setup(void)
{
kzt_cfg_t *cfg;
splat_cfg_t *cfg;
int i, rc, size, cfg_size;
subsystem_t *sub;
kzt_user_t *desc;
splat_user_t *desc;
/* Aquire the number of registered subsystems */
cfg_size = sizeof(*cfg);
cfg = (kzt_cfg_t *)malloc(cfg_size);
cfg = (splat_cfg_t *)malloc(cfg_size);
if (cfg == NULL)
return -ENOMEM;
memset(cfg, 0, cfg_size);
cfg->cfg_magic = KZT_CFG_MAGIC;
cfg->cfg_cmd = KZT_CFG_SUBSYSTEM_COUNT;
cfg->cfg_magic = SPLAT_CFG_MAGIC;
cfg->cfg_cmd = SPLAT_CFG_SUBSYSTEM_COUNT;
rc = ioctl(kztctl_fd, KZT_CFG, cfg);
rc = ioctl(splatctl_fd, SPLAT_CFG, cfg);
if (rc) {
fprintf(stderr, "Ioctl() error %lu / %d: %d\n",
(unsigned long) KZT_CFG, cfg->cfg_cmd, errno);
(unsigned long) SPLAT_CFG, cfg->cfg_cmd, errno);
free(cfg);
return rc;
}
@ -114,20 +116,20 @@ static int subsystem_setup(void)
/* Based on the newly aquired number of subsystems allocate enough
* memory to get the descriptive information for them all. */
cfg_size = sizeof(*cfg) + size * sizeof(kzt_user_t);
cfg = (kzt_cfg_t *)malloc(cfg_size);
cfg_size = sizeof(*cfg) + size * sizeof(splat_user_t);
cfg = (splat_cfg_t *)malloc(cfg_size);
if (cfg == NULL)
return -ENOMEM;
memset(cfg, 0, cfg_size);
cfg->cfg_magic = KZT_CFG_MAGIC;
cfg->cfg_cmd = KZT_CFG_SUBSYSTEM_LIST;
cfg->cfg_data.kzt_subsystems.size = size;
cfg->cfg_magic = SPLAT_CFG_MAGIC;
cfg->cfg_cmd = SPLAT_CFG_SUBSYSTEM_LIST;
cfg->cfg_data.splat_subsystems.size = size;
rc = ioctl(kztctl_fd, KZT_CFG, cfg);
rc = ioctl(splatctl_fd, SPLAT_CFG, cfg);
if (rc) {
fprintf(stderr, "Ioctl() error %lu / %d: %d\n",
(unsigned long) KZT_CFG, cfg->cfg_cmd, errno);
(unsigned long) SPLAT_CFG, cfg->cfg_cmd, errno);
free(cfg);
return rc;
}
@ -135,7 +137,7 @@ static int subsystem_setup(void)
/* Add the new subsystems in to the global list */
size = cfg->cfg_rc1;
for (i = 0; i < size; i++) {
desc = &(cfg->cfg_data.kzt_subsystems.descs[i]);
desc = &(cfg->cfg_data.splat_subsystems.descs[i]);
sub = subsystem_init(desc);
if (sub == NULL) {
@ -175,9 +177,9 @@ static void subsystem_list(List l, int indent)
subsystem_t *sub;
fprintf(stdout,
"------------------------------- "
"Available KZT Tests "
"-------------------------------\n");
"------------------------------ "
"Available SPLAT Tests "
"------------------------------\n");
i = list_iterator_create(l);
@ -185,7 +187,7 @@ static void subsystem_list(List l, int indent)
fprintf(stdout, "%*s0x%0*x %-*s ---- %s ----\n",
indent, "",
4, sub->sub_desc.id,
KZT_NAME_SIZE + 7, sub->sub_desc.name,
SPLAT_NAME_SIZE + 7, sub->sub_desc.name,
sub->sub_desc.desc);
test_list(sub->sub_tests, indent + 7);
}
@ -193,7 +195,7 @@ static void subsystem_list(List l, int indent)
list_iterator_destroy(i);
}
static test_t *test_init(subsystem_t *sub, kzt_user_t *desc)
static test_t *test_init(subsystem_t *sub, splat_user_t *desc)
{
test_t *test;
@ -215,25 +217,25 @@ static void test_fini(test_t *test)
static int test_setup(subsystem_t *sub)
{
kzt_cfg_t *cfg;
splat_cfg_t *cfg;
int i, rc, size;
test_t *test;
kzt_user_t *desc;
splat_user_t *desc;
/* Aquire the number of registered tests for the give subsystem */
cfg = (kzt_cfg_t *)malloc(sizeof(*cfg));
cfg = (splat_cfg_t *)malloc(sizeof(*cfg));
if (cfg == NULL)
return -ENOMEM;
memset(cfg, 0, sizeof(*cfg));
cfg->cfg_magic = KZT_CFG_MAGIC;
cfg->cfg_cmd = KZT_CFG_TEST_COUNT;
cfg->cfg_magic = SPLAT_CFG_MAGIC;
cfg->cfg_cmd = SPLAT_CFG_TEST_COUNT;
cfg->cfg_arg1 = sub->sub_desc.id; /* Subsystem of interest */
rc = ioctl(kztctl_fd, KZT_CFG, cfg);
rc = ioctl(splatctl_fd, SPLAT_CFG, cfg);
if (rc) {
fprintf(stderr, "Ioctl() error %lu / %d: %d\n",
(unsigned long) KZT_CFG, cfg->cfg_cmd, errno);
(unsigned long) SPLAT_CFG, cfg->cfg_cmd, errno);
free(cfg);
return rc;
}
@ -243,20 +245,20 @@ static int test_setup(subsystem_t *sub)
/* Based on the newly aquired number of tests allocate enough
* memory to get the descriptive information for them all. */
cfg = (kzt_cfg_t *)malloc(sizeof(*cfg) + size * sizeof(kzt_user_t));
cfg = (splat_cfg_t *)malloc(sizeof(*cfg) + size * sizeof(splat_user_t));
if (cfg == NULL)
return -ENOMEM;
memset(cfg, 0, sizeof(*cfg) + size * sizeof(kzt_user_t));
cfg->cfg_magic = KZT_CFG_MAGIC;
cfg->cfg_cmd = KZT_CFG_TEST_LIST;
memset(cfg, 0, sizeof(*cfg) + size * sizeof(splat_user_t));
cfg->cfg_magic = SPLAT_CFG_MAGIC;
cfg->cfg_cmd = SPLAT_CFG_TEST_LIST;
cfg->cfg_arg1 = sub->sub_desc.id; /* Subsystem of interest */
cfg->cfg_data.kzt_tests.size = size;
cfg->cfg_data.splat_tests.size = size;
rc = ioctl(kztctl_fd, KZT_CFG, cfg);
rc = ioctl(splatctl_fd, SPLAT_CFG, cfg);
if (rc) {
fprintf(stderr, "Ioctl() error %lu / %d: %d\n",
(unsigned long) KZT_CFG, cfg->cfg_cmd, errno);
(unsigned long) SPLAT_CFG, cfg->cfg_cmd, errno);
free(cfg);
return rc;
}
@ -264,7 +266,7 @@ static int test_setup(subsystem_t *sub)
/* Add the new tests in to the relevant subsystems */
size = cfg->cfg_rc1;
for (i = 0; i < size; i++) {
desc = &(cfg->cfg_data.kzt_tests.descs[i]);
desc = &(cfg->cfg_data.splat_tests.descs[i]);
test = test_init(sub, desc);
if (test == NULL) {
@ -314,8 +316,8 @@ static void test_list(List l, int indent)
fprintf(stdout, "%*s0x%0*x %-*s %-*s\n",
indent, "",
04, test->test_desc.id,
KZT_NAME_SIZE, test->test_desc.name,
KZT_DESC_SIZE, test->test_desc.desc);
SPLAT_NAME_SIZE, test->test_desc.name,
SPLAT_DESC_SIZE, test->test_desc.desc);
list_iterator_destroy(i);
}
@ -338,7 +340,7 @@ static test_t *test_find(char *sub_str, char *test_str)
while ((sub = list_next(si))) {
if (strncmp(sub->sub_desc.name, sub_str, KZT_NAME_SIZE) &&
if (strncmp(sub->sub_desc.name, sub_str, SPLAT_NAME_SIZE) &&
sub->sub_desc.id != sub_num)
continue;
@ -347,7 +349,7 @@ static test_t *test_find(char *sub_str, char *test_str)
while ((test = list_next(ti))) {
if (!strncmp(test->test_desc.name, test_str,
KZT_NAME_SIZE) || test->test_desc.id == test_num) {
SPLAT_NAME_SIZE) || test->test_desc.id == test_num) {
list_iterator_destroy(ti);
list_iterator_destroy(si);
return test;
@ -405,27 +407,27 @@ static int test_add_all(cmd_args_t *args)
static int test_run(cmd_args_t *args, test_t *test)
{
subsystem_t *sub = test->test_sub;
kzt_cmd_t *cmd;
splat_cmd_t *cmd;
int rc, cmd_size;
dev_clear();
cmd_size = sizeof(*cmd);
cmd = (kzt_cmd_t *)malloc(cmd_size);
cmd = (splat_cmd_t *)malloc(cmd_size);
if (cmd == NULL)
return -ENOMEM;
memset(cmd, 0, cmd_size);
cmd->cmd_magic = KZT_CMD_MAGIC;
cmd->cmd_magic = SPLAT_CMD_MAGIC;
cmd->cmd_subsystem = sub->sub_desc.id;
cmd->cmd_test = test->test_desc.id;
cmd->cmd_data_size = 0; /* Unused feature */
fprintf(stdout, "%*s:%-*s ",
KZT_NAME_SIZE, sub->sub_desc.name,
KZT_NAME_SIZE, test->test_desc.name);
SPLAT_NAME_SIZE, sub->sub_desc.name,
SPLAT_NAME_SIZE, test->test_desc.name);
fflush(stdout);
rc = ioctl(kztctl_fd, KZT_CMD, cmd);
rc = ioctl(splatctl_fd, SPLAT_CMD, cmd);
if (args->args_do_color) {
fprintf(stdout, "%s %s\n", rc ?
COLOR_RED "Fail" COLOR_RESET :
@ -440,10 +442,10 @@ static int test_run(cmd_args_t *args, test_t *test)
free(cmd);
if (args->args_verbose) {
if ((rc = read(kztctl_fd, kzt_buffer, kzt_buffer_size - 1)) < 0) {
if ((rc = read(splatctl_fd, splat_buffer, splat_buffer_size - 1)) < 0) {
fprintf(stdout, "Error reading results: %d\n", rc);
} else {
fprintf(stdout, "\n%s\n", kzt_buffer);
fprintf(stdout, "\n%s\n", splat_buffer);
fflush(stdout);
}
}
@ -458,9 +460,9 @@ static int tests_run(cmd_args_t *args)
int rc;
fprintf(stdout,
"------------------------------- "
"Running KZT Tests "
"-------------------------------\n");
"------------------------------ "
"Running SPLAT Tests "
"------------------------------\n");
i = list_iterator_create(args->args_tests);
@ -656,20 +658,20 @@ args_init(int argc, char **argv)
static int
dev_clear(void)
{
kzt_cfg_t cfg;
splat_cfg_t cfg;
int rc;
memset(&cfg, 0, sizeof(cfg));
cfg.cfg_magic = KZT_CFG_MAGIC;
cfg.cfg_cmd = KZT_CFG_BUFFER_CLEAR;
cfg.cfg_magic = SPLAT_CFG_MAGIC;
cfg.cfg_cmd = SPLAT_CFG_BUFFER_CLEAR;
cfg.cfg_arg1 = 0;
rc = ioctl(kztctl_fd, KZT_CFG, &cfg);
rc = ioctl(splatctl_fd, SPLAT_CFG, &cfg);
if (rc)
fprintf(stderr, "Ioctl() error %lu / %d: %d\n",
(unsigned long) KZT_CFG, cfg.cfg_cmd, errno);
(unsigned long) SPLAT_CFG, cfg.cfg_cmd, errno);
lseek(kztctl_fd, 0, SEEK_SET);
lseek(splatctl_fd, 0, SEEK_SET);
return rc;
}
@ -677,18 +679,18 @@ dev_clear(void)
static int
dev_size(int size)
{
kzt_cfg_t cfg;
splat_cfg_t cfg;
int rc;
memset(&cfg, 0, sizeof(cfg));
cfg.cfg_magic = KZT_CFG_MAGIC;
cfg.cfg_cmd = KZT_CFG_BUFFER_SIZE;
cfg.cfg_magic = SPLAT_CFG_MAGIC;
cfg.cfg_cmd = SPLAT_CFG_BUFFER_SIZE;
cfg.cfg_arg1 = size;
rc = ioctl(kztctl_fd, KZT_CFG, &cfg);
rc = ioctl(splatctl_fd, SPLAT_CFG, &cfg);
if (rc) {
fprintf(stderr, "Ioctl() error %lu / %d: %d\n",
(unsigned long) KZT_CFG, cfg.cfg_cmd, errno);
(unsigned long) SPLAT_CFG, cfg.cfg_cmd, errno);
return rc;
}
@ -698,13 +700,13 @@ dev_size(int size)
static void
dev_fini(void)
{
if (kzt_buffer)
free(kzt_buffer);
if (splat_buffer)
free(splat_buffer);
if (kztctl_fd != -1) {
if (close(kztctl_fd) == -1) {
if (splatctl_fd != -1) {
if (close(splatctl_fd) == -1) {
fprintf(stderr, "Unable to close %s: %d\n",
KZT_DEV, errno);
SPLAT_DEV, errno);
}
}
}
@ -716,17 +718,17 @@ dev_init(void)
subsystem_t *sub;
int rc;
kztctl_fd = open(KZT_DEV, O_RDONLY);
if (kztctl_fd == -1) {
splatctl_fd = open(SPLAT_DEV, O_RDONLY);
if (splatctl_fd == -1) {
fprintf(stderr, "Unable to open %s: %d\n"
"Is the kzt module loaded?\n", KZT_DEV, errno);
"Is the splat module loaded?\n", SPLAT_DEV, errno);
rc = errno;
goto error;
}
/* Determine kernel module version string */
memset(kzt_version, 0, KZT_VERSION_SIZE);
if ((rc = read(kztctl_fd, kzt_version, KZT_VERSION_SIZE - 1)) == -1)
memset(splat_version, 0, VERSION_SIZE);
if ((rc = read(splatctl_fd, splat_version, VERSION_SIZE - 1)) == -1)
goto error;
if ((rc = dev_clear()))
@ -735,14 +737,14 @@ dev_init(void)
if ((rc = dev_size(0)) < 0)
goto error;
kzt_buffer_size = rc;
kzt_buffer = (char *)malloc(kzt_buffer_size);
if (kzt_buffer == NULL) {
splat_buffer_size = rc;
splat_buffer = (char *)malloc(splat_buffer_size);
if (splat_buffer == NULL) {
rc = -ENOMEM;
goto error;
}
memset(kzt_buffer, 0, kzt_buffer_size);
memset(splat_buffer, 0, splat_buffer_size);
/* Determine available subsystems */
if ((rc = subsystem_setup()) != 0)
@ -762,10 +764,10 @@ dev_init(void)
return 0;
error:
if (kztctl_fd != -1) {
if (close(kztctl_fd) == -1) {
if (splatctl_fd != -1) {
if (close(splatctl_fd) == -1) {
fprintf(stderr, "Unable to close %s: %d\n",
KZT_DEV, errno);
SPLAT_DEV, errno);
}
}
@ -814,7 +816,7 @@ main(int argc, char **argv)
/* Generic kernel version string */
if (args->args_verbose)
fprintf(stdout, "%s", kzt_version);
fprintf(stdout, "%s", splat_version);
/* Print the available test list and exit */
if (args->args_do_list) {

View File

@ -4,7 +4,7 @@
#include "list.h"
#include "splat-ctl.h"
#define DEV_NAME "/dev/kztctl"
#define DEV_NAME "/dev/splatctl"
#define COLOR_BLACK "\033[0;30m"
#define COLOR_DK_GRAY "\033[1;30m"
#define COLOR_BLUE "\033[0;34m"
@ -24,12 +24,12 @@
#define COLOR_RESET "\033[0m"
typedef struct subsystem {
kzt_user_t sub_desc; /* Subsystem description */
splat_user_t sub_desc; /* Subsystem description */
List sub_tests; /* Assocated subsystem tests list */
} subsystem_t;
typedef struct test {
kzt_user_t test_desc; /* Test description */
splat_user_t test_desc; /* Test description */
subsystem_t *test_sub; /* Parent subsystem */
} test_t;

View File

@ -1,5 +1,5 @@
EXTRA_DIST = spl.h
EXTRA_DIST += splat.h splat-ctl.h
EXTRA_DIST += splat-ctl.h
EXTRA_DIST += linux-condvar.h linux-kmem.h linux-random.h linux-thread.h
EXTRA_DIST += linux-types.h linux-cred.h linux-kstat.h linux-rwlock.h
EXTRA_DIST += linux-time.h linux-callb.h linux-generic.h linux-mutex.h

View File

@ -1,59 +1,25 @@
#ifndef _SPLAT_CTL_H
#define _SPLAT_CTL_H
#ifdef __KERNEL__
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/elf.h>
#include <linux/limits.h>
#include <linux/version.h>
#include <linux/vmalloc.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/list.h>
#include <asm/ioctls.h>
#include <asm/uaccess.h>
#include <stdarg.h>
/* Contains shared definitions which both the userspace
* and kernelspace portions of splat must agree on.
*/
#include <linux-generic.h>
#include <linux-types.h>
#include <linux-kmem.h>
#include <linux-mutex.h>
#include <linux-condvar.h>
#include <linux-random.h>
#include <linux-thread.h>
#include <linux-taskq.h>
#include <linux-rwlock.h>
#include <linux-timer.h>
#include <linux-time.h>
#include <linux-cred.h>
#include <linux-kstat.h>
#include <linux-callb.h>
#define SPLAT_MAJOR 229 /* XXX - Arbitrary */
#define SPLAT_MINORS 1
#define SPLAT_DEV "/dev/splatctl"
#endif /* __KERNEL__ */
#define SPLAT_NAME_SIZE 12
#define SPLAT_DESC_SIZE 60
#define KZT_VERSION "v1.0"
#define KZT_VERSION_SIZE 64
#define KZT_MAJOR 229 /* XXX - Arbitrary */
#define KZT_MINORS 1
#define KZT_DEV "/dev/kztctl"
#define KZT_NAME_SIZE 12
#define KZT_DESC_SIZE 60
typedef struct kzt_user {
char name[KZT_NAME_SIZE]; /* short name */
char desc[KZT_DESC_SIZE]; /* short description */
typedef struct splat_user {
char name[SPLAT_NAME_SIZE]; /* short name */
char desc[SPLAT_DESC_SIZE]; /* short description */
int id; /* unique numeric id */
} kzt_user_t;
} splat_user_t;
#define KZT_CFG_MAGIC 0x15263748U
typedef struct kzt_cfg {
#define SPLAT_CFG_MAGIC 0x15263748U
typedef struct splat_cfg {
unsigned int cfg_magic; /* Unique magic */
int cfg_cmd; /* Config command */
int cfg_arg1; /* Config command arg 1 */
@ -61,198 +27,41 @@ typedef struct kzt_cfg {
union {
struct {
int size;
kzt_user_t descs[0];
} kzt_subsystems;
splat_user_t descs[0];
} splat_subsystems;
struct {
int size;
kzt_user_t descs[0];
} kzt_tests;
splat_user_t descs[0];
} splat_tests;
} cfg_data;
} kzt_cfg_t;
} splat_cfg_t;
#define KZT_CMD_MAGIC 0x9daebfc0U
typedef struct kzt_cmd {
#define SPLAT_CMD_MAGIC 0x9daebfc0U
typedef struct splat_cmd {
unsigned int cmd_magic; /* Unique magic */
int cmd_subsystem; /* Target subsystem */
int cmd_test; /* Subsystem test */
int cmd_data_size; /* Extra opaque data */
char cmd_data_str[0]; /* Opaque data region */
} kzt_cmd_t;
} splat_cmd_t;
/* Valid ioctls */
#define KZT_CFG _IOWR('f', 101, long)
#define KZT_CMD _IOWR('f', 102, long)
#define SPLAT_CFG _IOWR('f', 101, long)
#define SPLAT_CMD _IOWR('f', 102, long)
/* Valid configuration commands */
#define KZT_CFG_BUFFER_CLEAR 0x001 /* Clear text buffer */
#define KZT_CFG_BUFFER_SIZE 0x002 /* Resize text buffer */
#define KZT_CFG_SUBSYSTEM_COUNT 0x101 /* Number of subsystem */
#define KZT_CFG_SUBSYSTEM_LIST 0x102 /* List of N subsystems */
#define KZT_CFG_TEST_COUNT 0x201 /* Number of tests */
#define KZT_CFG_TEST_LIST 0x202 /* List of N tests */
#define SPLAT_CFG_BUFFER_CLEAR 0x001 /* Clear text buffer */
#define SPLAT_CFG_BUFFER_SIZE 0x002 /* Resize text buffer */
#define SPLAT_CFG_SUBSYSTEM_COUNT 0x101 /* Number of subsystem */
#define SPLAT_CFG_SUBSYSTEM_LIST 0x102 /* List of N subsystems */
#define SPLAT_CFG_TEST_COUNT 0x201 /* Number of tests */
#define SPLAT_CFG_TEST_LIST 0x202 /* List of N tests */
/* Valid subsystem and test commands defined in each subsystem, we do
* need to be careful to avoid colisions. That alone may argue to define
* them all here, for now we just define the global error codes.
*/
#define KZT_SUBSYSTEM_UNKNOWN 0xF00
#define KZT_TEST_UNKNOWN 0xFFF
#ifdef __KERNEL__
#define KZT_SUBSYSTEM_INIT(type) \
({ kzt_subsystem_t *_sub_; \
\
_sub_ = (kzt_subsystem_t *)kzt_##type##_init(); \
if (_sub_ == NULL) { \
printk(KERN_ERR "Error initializing: " #type "\n"); \
} else { \
spin_lock(&kzt_module_lock); \
list_add_tail(&(_sub_->subsystem_list), \
&kzt_module_list); \
spin_unlock(&kzt_module_lock); \
} \
})
#define KZT_SUBSYSTEM_FINI(type) \
({ kzt_subsystem_t *_sub_, *_tmp_; \
int _id_, _flag_ = 0; \
\
_id_ = kzt_##type##_id(); \
spin_lock(&kzt_module_lock); \
list_for_each_entry_safe(_sub_, _tmp_, &kzt_module_list, \
subsystem_list) { \
if (_sub_->desc.id == _id_) { \
list_del_init(&(_sub_->subsystem_list)); \
spin_unlock(&kzt_module_lock); \
kzt_##type##_fini(_sub_); \
spin_lock(&kzt_module_lock); \
_flag_ = 1; \
} \
} \
spin_unlock(&kzt_module_lock); \
\
if (!_flag_) \
printk(KERN_ERR "Error finalizing: " #type "\n"); \
})
#define KZT_TEST_INIT(sub, n, d, tid, func) \
({ kzt_test_t *_test_; \
\
_test_ = (kzt_test_t *)kmalloc(sizeof(*_test_), GFP_KERNEL); \
if (_test_ == NULL) { \
printk(KERN_ERR "Error initializing: " n "/" #tid" \n");\
} else { \
memset(_test_, 0, sizeof(*_test_)); \
strncpy(_test_->desc.name, n, KZT_NAME_SIZE); \
strncpy(_test_->desc.desc, d, KZT_DESC_SIZE); \
_test_->desc.id = tid; \
_test_->test = func; \
INIT_LIST_HEAD(&(_test_->test_list)); \
spin_lock(&((sub)->test_lock)); \
list_add_tail(&(_test_->test_list),&((sub)->test_list));\
spin_unlock(&((sub)->test_lock)); \
} \
})
#define KZT_TEST_FINI(sub, tid) \
({ kzt_test_t *_test_, *_tmp_; \
int _flag_ = 0; \
\
spin_lock(&((sub)->test_lock)); \
list_for_each_entry_safe(_test_, _tmp_, \
&((sub)->test_list), test_list) { \
if (_test_->desc.id == tid) { \
list_del_init(&(_test_->test_list)); \
_flag_ = 1; \
} \
} \
spin_unlock(&((sub)->test_lock)); \
\
if (!_flag_) \
printk(KERN_ERR "Error finalizing: " #tid "\n"); \
})
typedef int (*kzt_test_func_t)(struct file *, void *);
typedef struct kzt_test {
struct list_head test_list;
kzt_user_t desc;
kzt_test_func_t test;
} kzt_test_t;
typedef struct kzt_subsystem {
struct list_head subsystem_list;/* List had to chain entries */
kzt_user_t desc;
spinlock_t test_lock;
struct list_head test_list;
} kzt_subsystem_t;
#define KZT_INFO_BUFFER_SIZE 65536
#define KZT_INFO_BUFFER_REDZONE 256
typedef struct kzt_info {
spinlock_t info_lock;
int info_size;
char *info_buffer;
char *info_head; /* Internal kernel use only */
} kzt_info_t;
#define sym2str(sym) (char *)(#sym)
#define kzt_print(file, format, args...) \
({ kzt_info_t *_info_ = (kzt_info_t *)file->private_data; \
int _rc_; \
\
ASSERT(_info_); \
ASSERT(_info_->info_buffer); \
\
spin_lock(&_info_->info_lock); \
\
/* Don't allow the kernel to start a write in the red zone */ \
if ((int)(_info_->info_head - _info_->info_buffer) > \
(KZT_INFO_BUFFER_SIZE -KZT_INFO_BUFFER_REDZONE)) { \
_rc_ = -EOVERFLOW; \
} else { \
_rc_ = sprintf(_info_->info_head, format, args); \
if (_rc_ >= 0) \
_info_->info_head += _rc_; \
} \
\
spin_unlock(&_info_->info_lock); \
_rc_; \
})
#define kzt_vprint(file, test, format, args...) \
kzt_print(file, "%*s: " format, KZT_NAME_SIZE, test, args)
kzt_subsystem_t * kzt_condvar_init(void);
kzt_subsystem_t * kzt_kmem_init(void);
kzt_subsystem_t * kzt_mutex_init(void);
kzt_subsystem_t * kzt_krng_init(void);
kzt_subsystem_t * kzt_rwlock_init(void);
kzt_subsystem_t * kzt_taskq_init(void);
kzt_subsystem_t * kzt_thread_init(void);
kzt_subsystem_t * kzt_time_init(void);
void kzt_condvar_fini(kzt_subsystem_t *);
void kzt_kmem_fini(kzt_subsystem_t *);
void kzt_mutex_fini(kzt_subsystem_t *);
void kzt_krng_fini(kzt_subsystem_t *);
void kzt_rwlock_fini(kzt_subsystem_t *);
void kzt_taskq_fini(kzt_subsystem_t *);
void kzt_thread_fini(kzt_subsystem_t *);
void kzt_time_fini(kzt_subsystem_t *);
int kzt_condvar_id(void);
int kzt_kmem_id(void);
int kzt_mutex_id(void);
int kzt_krng_id(void);
int kzt_rwlock_id(void);
int kzt_taskq_id(void);
int kzt_thread_id(void);
int kzt_time_id(void);
#endif /* __KERNEL__ */
#define SPLAT_SUBSYSTEM_UNKNOWN 0xF00
#define SPLAT_TEST_UNKNOWN 0xFFF
#endif /* _SPLAT_CTL_H */

View File

@ -4,7 +4,9 @@ MODULES := splat
DISTFILES = Makefile.in \
splat-kmem.c splat-random.c splat-taskq.c \
splat-time.c splat-condvar.c splat-mutex.c \
splat-rwlock.c splat-thread.c splat-ctl.c
splat-rwlock.c splat-thread.c \
splat-ctl.c splat-internal.h
CPPFLAGS += @KERNELCPPFLAGS@
# Solaris porting layer aggressive tests

View File

@ -1,32 +1,32 @@
#include <splat-ctl.h>
#include "splat-internal.h"
#define KZT_SUBSYSTEM_CONDVAR 0x0500
#define KZT_CONDVAR_NAME "condvar"
#define KZT_CONDVAR_DESC "Kernel Condition Variable Tests"
#define SPLAT_SUBSYSTEM_CONDVAR 0x0500
#define SPLAT_CONDVAR_NAME "condvar"
#define SPLAT_CONDVAR_DESC "Kernel Condition Variable Tests"
#define KZT_CONDVAR_TEST1_ID 0x0501
#define KZT_CONDVAR_TEST1_NAME "signal1"
#define KZT_CONDVAR_TEST1_DESC "Wake a single thread, cv_wait()/cv_signal()"
#define SPLAT_CONDVAR_TEST1_ID 0x0501
#define SPLAT_CONDVAR_TEST1_NAME "signal1"
#define SPLAT_CONDVAR_TEST1_DESC "Wake a single thread, cv_wait()/cv_signal()"
#define KZT_CONDVAR_TEST2_ID 0x0502
#define KZT_CONDVAR_TEST2_NAME "broadcast1"
#define KZT_CONDVAR_TEST2_DESC "Wake all threads, cv_wait()/cv_broadcast()"
#define SPLAT_CONDVAR_TEST2_ID 0x0502
#define SPLAT_CONDVAR_TEST2_NAME "broadcast1"
#define SPLAT_CONDVAR_TEST2_DESC "Wake all threads, cv_wait()/cv_broadcast()"
#define KZT_CONDVAR_TEST3_ID 0x0503
#define KZT_CONDVAR_TEST3_NAME "signal2"
#define KZT_CONDVAR_TEST3_DESC "Wake a single thread, cv_wait_timeout()/cv_signal()"
#define SPLAT_CONDVAR_TEST3_ID 0x0503
#define SPLAT_CONDVAR_TEST3_NAME "signal2"
#define SPLAT_CONDVAR_TEST3_DESC "Wake a single thread, cv_wait_timeout()/cv_signal()"
#define KZT_CONDVAR_TEST4_ID 0x0504
#define KZT_CONDVAR_TEST4_NAME "broadcast2"
#define KZT_CONDVAR_TEST4_DESC "Wake all threads, cv_wait_timeout()/cv_broadcast()"
#define SPLAT_CONDVAR_TEST4_ID 0x0504
#define SPLAT_CONDVAR_TEST4_NAME "broadcast2"
#define SPLAT_CONDVAR_TEST4_DESC "Wake all threads, cv_wait_timeout()/cv_broadcast()"
#define KZT_CONDVAR_TEST5_ID 0x0505
#define KZT_CONDVAR_TEST5_NAME "timeout"
#define KZT_CONDVAR_TEST5_DESC "Timeout thread, cv_wait_timeout()"
#define SPLAT_CONDVAR_TEST5_ID 0x0505
#define SPLAT_CONDVAR_TEST5_NAME "timeout"
#define SPLAT_CONDVAR_TEST5_DESC "Timeout thread, cv_wait_timeout()"
#define KZT_CONDVAR_TEST_MAGIC 0x115599DDUL
#define KZT_CONDVAR_TEST_NAME "condvar_test"
#define KZT_CONDVAR_TEST_COUNT 8
#define SPLAT_CONDVAR_TEST_MAGIC 0x115599DDUL
#define SPLAT_CONDVAR_TEST_NAME "condvar_test"
#define SPLAT_CONDVAR_TEST_COUNT 8
typedef struct condvar_priv {
unsigned long cv_magic;
@ -43,22 +43,22 @@ typedef struct condvar_thr {
} condvar_thr_t;
int
kzt_condvar_test12_thread(void *arg)
splat_condvar_test12_thread(void *arg)
{
condvar_thr_t *ct = (condvar_thr_t *)arg;
condvar_priv_t *cv = ct->ct_cvp;
char name[16];
ASSERT(cv->cv_magic == KZT_CONDVAR_TEST_MAGIC);
snprintf(name, sizeof(name), "%s%d", KZT_CONDVAR_TEST_NAME, ct->ct_id);
ASSERT(cv->cv_magic == SPLAT_CONDVAR_TEST_MAGIC);
snprintf(name, sizeof(name),"%s%d",SPLAT_CONDVAR_TEST_NAME,ct->ct_id);
daemonize(name);
mutex_enter(&cv->cv_mtx);
kzt_vprint(cv->cv_file, ct->ct_name,
splat_vprint(cv->cv_file, ct->ct_name,
"%s thread sleeping with %d waiters\n",
name, atomic_read(&cv->cv_condvar.cv_waiters));
cv_wait(&cv->cv_condvar, &cv->cv_mtx);
kzt_vprint(cv->cv_file, ct->ct_name,
splat_vprint(cv->cv_file, ct->ct_name,
"%s thread woken %d waiters remain\n",
name, atomic_read(&cv->cv_condvar.cv_waiters));
mutex_exit(&cv->cv_mtx);
@ -67,27 +67,27 @@ kzt_condvar_test12_thread(void *arg)
}
static int
kzt_condvar_test1(struct file *file, void *arg)
splat_condvar_test1(struct file *file, void *arg)
{
int i, count = 0, rc = 0;
long pids[KZT_CONDVAR_TEST_COUNT];
condvar_thr_t ct[KZT_CONDVAR_TEST_COUNT];
long pids[SPLAT_CONDVAR_TEST_COUNT];
condvar_thr_t ct[SPLAT_CONDVAR_TEST_COUNT];
condvar_priv_t cv;
cv.cv_magic = KZT_CONDVAR_TEST_MAGIC;
cv.cv_magic = SPLAT_CONDVAR_TEST_MAGIC;
cv.cv_file = file;
mutex_init(&cv.cv_mtx, KZT_CONDVAR_TEST_NAME, MUTEX_DEFAULT, NULL);
cv_init(&cv.cv_condvar, KZT_CONDVAR_TEST_NAME, CV_DEFAULT, NULL);
mutex_init(&cv.cv_mtx, SPLAT_CONDVAR_TEST_NAME, MUTEX_DEFAULT, NULL);
cv_init(&cv.cv_condvar, SPLAT_CONDVAR_TEST_NAME, CV_DEFAULT, NULL);
/* Create some threads, the exact number isn't important just as
* long as we know how many we managed to create and should expect. */
for (i = 0; i < KZT_CONDVAR_TEST_COUNT; i++) {
for (i = 0; i < SPLAT_CONDVAR_TEST_COUNT; i++) {
ct[i].ct_cvp = &cv;
ct[i].ct_id = i;
ct[i].ct_name = KZT_CONDVAR_TEST1_NAME;
ct[i].ct_name = SPLAT_CONDVAR_TEST1_NAME;
ct[i].ct_rc = 0;
pids[i] = kernel_thread(kzt_condvar_test12_thread, &ct[i], 0);
pids[i] = kernel_thread(splat_condvar_test12_thread, &ct[i], 0);
if (pids[i] >= 0)
count++;
}
@ -107,7 +107,7 @@ kzt_condvar_test1(struct file *file, void *arg)
if (atomic_read(&cv.cv_condvar.cv_waiters) == (count - i))
continue;
kzt_vprint(file, KZT_CONDVAR_TEST1_NAME, "Attempted to "
splat_vprint(file, SPLAT_CONDVAR_TEST1_NAME, "Attempted to "
"wake %d thread but work %d threads woke\n",
1, count - atomic_read(&cv.cv_condvar.cv_waiters));
rc = -EINVAL;
@ -115,7 +115,7 @@ kzt_condvar_test1(struct file *file, void *arg)
}
if (!rc)
kzt_vprint(file, KZT_CONDVAR_TEST1_NAME, "Correctly woke "
splat_vprint(file, SPLAT_CONDVAR_TEST1_NAME, "Correctly woke "
"%d sleeping threads %d at a time\n", count, 1);
/* Wait until that last nutex is dropped */
@ -131,27 +131,27 @@ kzt_condvar_test1(struct file *file, void *arg)
}
static int
kzt_condvar_test2(struct file *file, void *arg)
splat_condvar_test2(struct file *file, void *arg)
{
int i, count = 0, rc = 0;
long pids[KZT_CONDVAR_TEST_COUNT];
condvar_thr_t ct[KZT_CONDVAR_TEST_COUNT];
long pids[SPLAT_CONDVAR_TEST_COUNT];
condvar_thr_t ct[SPLAT_CONDVAR_TEST_COUNT];
condvar_priv_t cv;
cv.cv_magic = KZT_CONDVAR_TEST_MAGIC;
cv.cv_magic = SPLAT_CONDVAR_TEST_MAGIC;
cv.cv_file = file;
mutex_init(&cv.cv_mtx, KZT_CONDVAR_TEST_NAME, MUTEX_DEFAULT, NULL);
cv_init(&cv.cv_condvar, KZT_CONDVAR_TEST_NAME, CV_DEFAULT, NULL);
mutex_init(&cv.cv_mtx, SPLAT_CONDVAR_TEST_NAME, MUTEX_DEFAULT, NULL);
cv_init(&cv.cv_condvar, SPLAT_CONDVAR_TEST_NAME, CV_DEFAULT, NULL);
/* Create some threads, the exact number isn't important just as
* long as we know how many we managed to create and should expect. */
for (i = 0; i < KZT_CONDVAR_TEST_COUNT; i++) {
for (i = 0; i < SPLAT_CONDVAR_TEST_COUNT; i++) {
ct[i].ct_cvp = &cv;
ct[i].ct_id = i;
ct[i].ct_name = KZT_CONDVAR_TEST2_NAME;
ct[i].ct_name = SPLAT_CONDVAR_TEST2_NAME;
ct[i].ct_rc = 0;
pids[i] = kernel_thread(kzt_condvar_test12_thread, &ct[i], 0);
pids[i] = kernel_thread(splat_condvar_test12_thread, &ct[i], 0);
if (pids[i] > 0)
count++;
}
@ -167,7 +167,7 @@ kzt_condvar_test2(struct file *file, void *arg)
while ((atomic_read(&cv.cv_condvar.cv_waiters) > 0) || mutex_owner(&cv.cv_mtx))
schedule();
kzt_vprint(file, KZT_CONDVAR_TEST2_NAME, "Correctly woke all "
splat_vprint(file, SPLAT_CONDVAR_TEST2_NAME, "Correctly woke all "
"%d sleeping threads at once\n", count);
/* Wake everything for the failure case */
@ -178,19 +178,19 @@ kzt_condvar_test2(struct file *file, void *arg)
}
int
kzt_condvar_test34_thread(void *arg)
splat_condvar_test34_thread(void *arg)
{
condvar_thr_t *ct = (condvar_thr_t *)arg;
condvar_priv_t *cv = ct->ct_cvp;
char name[16];
clock_t rc;
ASSERT(cv->cv_magic == KZT_CONDVAR_TEST_MAGIC);
snprintf(name, sizeof(name), "%s%d", KZT_CONDVAR_TEST_NAME, ct->ct_id);
ASSERT(cv->cv_magic == SPLAT_CONDVAR_TEST_MAGIC);
snprintf(name, sizeof(name), "%s%d", SPLAT_CONDVAR_TEST_NAME, ct->ct_id);
daemonize(name);
mutex_enter(&cv->cv_mtx);
kzt_vprint(cv->cv_file, ct->ct_name,
splat_vprint(cv->cv_file, ct->ct_name,
"%s thread sleeping with %d waiters\n",
name, atomic_read(&cv->cv_condvar.cv_waiters));
@ -199,10 +199,10 @@ kzt_condvar_test34_thread(void *arg)
rc = cv_timedwait(&cv->cv_condvar, &cv->cv_mtx, lbolt + HZ * 3);
if (rc == -1) {
ct->ct_rc = -ETIMEDOUT;
kzt_vprint(cv->cv_file, ct->ct_name, "%s thread timed out, "
splat_vprint(cv->cv_file, ct->ct_name, "%s thread timed out, "
"should have been woken\n", name);
} else {
kzt_vprint(cv->cv_file, ct->ct_name,
splat_vprint(cv->cv_file, ct->ct_name,
"%s thread woken %d waiters remain\n",
name, atomic_read(&cv->cv_condvar.cv_waiters));
}
@ -213,27 +213,27 @@ kzt_condvar_test34_thread(void *arg)
}
static int
kzt_condvar_test3(struct file *file, void *arg)
splat_condvar_test3(struct file *file, void *arg)
{
int i, count = 0, rc = 0;
long pids[KZT_CONDVAR_TEST_COUNT];
condvar_thr_t ct[KZT_CONDVAR_TEST_COUNT];
long pids[SPLAT_CONDVAR_TEST_COUNT];
condvar_thr_t ct[SPLAT_CONDVAR_TEST_COUNT];
condvar_priv_t cv;
cv.cv_magic = KZT_CONDVAR_TEST_MAGIC;
cv.cv_magic = SPLAT_CONDVAR_TEST_MAGIC;
cv.cv_file = file;
mutex_init(&cv.cv_mtx, KZT_CONDVAR_TEST_NAME, MUTEX_DEFAULT, NULL);
cv_init(&cv.cv_condvar, KZT_CONDVAR_TEST_NAME, CV_DEFAULT, NULL);
mutex_init(&cv.cv_mtx, SPLAT_CONDVAR_TEST_NAME, MUTEX_DEFAULT, NULL);
cv_init(&cv.cv_condvar, SPLAT_CONDVAR_TEST_NAME, CV_DEFAULT, NULL);
/* Create some threads, the exact number isn't important just as
* long as we know how many we managed to create and should expect. */
for (i = 0; i < KZT_CONDVAR_TEST_COUNT; i++) {
for (i = 0; i < SPLAT_CONDVAR_TEST_COUNT; i++) {
ct[i].ct_cvp = &cv;
ct[i].ct_id = i;
ct[i].ct_name = KZT_CONDVAR_TEST3_NAME;
ct[i].ct_name = SPLAT_CONDVAR_TEST3_NAME;
ct[i].ct_rc = 0;
pids[i] = kernel_thread(kzt_condvar_test34_thread, &ct[i], 0);
pids[i] = kernel_thread(splat_condvar_test34_thread, &ct[i], 0);
if (pids[i] >= 0)
count++;
}
@ -253,7 +253,7 @@ kzt_condvar_test3(struct file *file, void *arg)
if (atomic_read(&cv.cv_condvar.cv_waiters) == (count - i))
continue;
kzt_vprint(file, KZT_CONDVAR_TEST3_NAME, "Attempted to "
splat_vprint(file, SPLAT_CONDVAR_TEST3_NAME, "Attempted to "
"wake %d thread but work %d threads woke\n",
1, count - atomic_read(&cv.cv_condvar.cv_waiters));
rc = -EINVAL;
@ -266,7 +266,7 @@ kzt_condvar_test3(struct file *file, void *arg)
rc = ct[i].ct_rc;
if (!rc)
kzt_vprint(file, KZT_CONDVAR_TEST3_NAME, "Correctly woke "
splat_vprint(file, SPLAT_CONDVAR_TEST3_NAME, "Correctly woke "
"%d sleeping threads %d at a time\n", count, 1);
/* Wait until that last nutex is dropped */
@ -282,27 +282,27 @@ kzt_condvar_test3(struct file *file, void *arg)
}
static int
kzt_condvar_test4(struct file *file, void *arg)
splat_condvar_test4(struct file *file, void *arg)
{
int i, count = 0, rc = 0;
long pids[KZT_CONDVAR_TEST_COUNT];
condvar_thr_t ct[KZT_CONDVAR_TEST_COUNT];
long pids[SPLAT_CONDVAR_TEST_COUNT];
condvar_thr_t ct[SPLAT_CONDVAR_TEST_COUNT];
condvar_priv_t cv;
cv.cv_magic = KZT_CONDVAR_TEST_MAGIC;
cv.cv_magic = SPLAT_CONDVAR_TEST_MAGIC;
cv.cv_file = file;
mutex_init(&cv.cv_mtx, KZT_CONDVAR_TEST_NAME, MUTEX_DEFAULT, NULL);
cv_init(&cv.cv_condvar, KZT_CONDVAR_TEST_NAME, CV_DEFAULT, NULL);
mutex_init(&cv.cv_mtx, SPLAT_CONDVAR_TEST_NAME, MUTEX_DEFAULT, NULL);
cv_init(&cv.cv_condvar, SPLAT_CONDVAR_TEST_NAME, CV_DEFAULT, NULL);
/* Create some threads, the exact number isn't important just as
* long as we know how many we managed to create and should expect. */
for (i = 0; i < KZT_CONDVAR_TEST_COUNT; i++) {
for (i = 0; i < SPLAT_CONDVAR_TEST_COUNT; i++) {
ct[i].ct_cvp = &cv;
ct[i].ct_id = i;
ct[i].ct_name = KZT_CONDVAR_TEST3_NAME;
ct[i].ct_name = SPLAT_CONDVAR_TEST3_NAME;
ct[i].ct_rc = 0;
pids[i] = kernel_thread(kzt_condvar_test34_thread, &ct[i], 0);
pids[i] = kernel_thread(splat_condvar_test34_thread, &ct[i], 0);
if (pids[i] >= 0)
count++;
}
@ -322,7 +322,7 @@ kzt_condvar_test4(struct file *file, void *arg)
if (atomic_read(&cv.cv_condvar.cv_waiters) == (count - i))
continue;
kzt_vprint(file, KZT_CONDVAR_TEST3_NAME, "Attempted to "
splat_vprint(file, SPLAT_CONDVAR_TEST3_NAME, "Attempted to "
"wake %d thread but work %d threads woke\n",
1, count - atomic_read(&cv.cv_condvar.cv_waiters));
rc = -EINVAL;
@ -335,7 +335,7 @@ kzt_condvar_test4(struct file *file, void *arg)
rc = ct[i].ct_rc;
if (!rc)
kzt_vprint(file, KZT_CONDVAR_TEST3_NAME, "Correctly woke "
splat_vprint(file, SPLAT_CONDVAR_TEST3_NAME, "Correctly woke "
"%d sleeping threads %d at a time\n", count, 1);
/* Wait until that last nutex is dropped */
@ -351,7 +351,7 @@ kzt_condvar_test4(struct file *file, void *arg)
}
static int
kzt_condvar_test5(struct file *file, void *arg)
splat_condvar_test5(struct file *file, void *arg)
{
kcondvar_t condvar;
kmutex_t mtx;
@ -360,10 +360,10 @@ kzt_condvar_test5(struct file *file, void *arg)
int32_t remain_delta;
int rc = 0;
mutex_init(&mtx, KZT_CONDVAR_TEST_NAME, MUTEX_DEFAULT, NULL);
cv_init(&condvar, KZT_CONDVAR_TEST_NAME, CV_DEFAULT, NULL);
mutex_init(&mtx, SPLAT_CONDVAR_TEST_NAME, MUTEX_DEFAULT, NULL);
cv_init(&condvar, SPLAT_CONDVAR_TEST_NAME, CV_DEFAULT, NULL);
kzt_vprint(file, KZT_CONDVAR_TEST5_NAME, "Thread going to sleep for "
splat_vprint(file, SPLAT_CONDVAR_TEST5_NAME, "Thread going to sleep for "
"%d second and expecting to be woken by timeout\n", 1);
/* Allow a 1 second timeout, plenty long to validate correctness. */
@ -378,19 +378,19 @@ kzt_condvar_test5(struct file *file, void *arg)
if (time_left == -1) {
if (time_delta >= HZ) {
kzt_vprint(file, KZT_CONDVAR_TEST5_NAME,
splat_vprint(file, SPLAT_CONDVAR_TEST5_NAME,
"Thread correctly timed out and was asleep "
"for %d.%d seconds (%d second min)\n",
(int)whole_delta, remain_delta, 1);
} else {
kzt_vprint(file, KZT_CONDVAR_TEST5_NAME,
splat_vprint(file, SPLAT_CONDVAR_TEST5_NAME,
"Thread correctly timed out but was only "
"asleep for %d.%d seconds (%d second "
"min)\n", (int)whole_delta, remain_delta, 1);
rc = -ETIMEDOUT;
}
} else {
kzt_vprint(file, KZT_CONDVAR_TEST5_NAME,
splat_vprint(file, SPLAT_CONDVAR_TEST5_NAME,
"Thread exited after only %d.%d seconds, it "
"did not hit the %d second timeout\n",
(int)whole_delta, remain_delta, 1);
@ -403,51 +403,51 @@ kzt_condvar_test5(struct file *file, void *arg)
return rc;
}
kzt_subsystem_t *
kzt_condvar_init(void)
splat_subsystem_t *
splat_condvar_init(void)
{
kzt_subsystem_t *sub;
splat_subsystem_t *sub;
sub = kmalloc(sizeof(*sub), GFP_KERNEL);
if (sub == NULL)
return NULL;
memset(sub, 0, sizeof(*sub));
strncpy(sub->desc.name, KZT_CONDVAR_NAME, KZT_NAME_SIZE);
strncpy(sub->desc.desc, KZT_CONDVAR_DESC, KZT_DESC_SIZE);
strncpy(sub->desc.name, SPLAT_CONDVAR_NAME, SPLAT_NAME_SIZE);
strncpy(sub->desc.desc, SPLAT_CONDVAR_DESC, SPLAT_DESC_SIZE);
INIT_LIST_HEAD(&sub->subsystem_list);
INIT_LIST_HEAD(&sub->test_list);
spin_lock_init(&sub->test_lock);
sub->desc.id = KZT_SUBSYSTEM_CONDVAR;
sub->desc.id = SPLAT_SUBSYSTEM_CONDVAR;
KZT_TEST_INIT(sub, KZT_CONDVAR_TEST1_NAME, KZT_CONDVAR_TEST1_DESC,
KZT_CONDVAR_TEST1_ID, kzt_condvar_test1);
KZT_TEST_INIT(sub, KZT_CONDVAR_TEST2_NAME, KZT_CONDVAR_TEST2_DESC,
KZT_CONDVAR_TEST2_ID, kzt_condvar_test2);
KZT_TEST_INIT(sub, KZT_CONDVAR_TEST3_NAME, KZT_CONDVAR_TEST3_DESC,
KZT_CONDVAR_TEST3_ID, kzt_condvar_test3);
KZT_TEST_INIT(sub, KZT_CONDVAR_TEST4_NAME, KZT_CONDVAR_TEST4_DESC,
KZT_CONDVAR_TEST4_ID, kzt_condvar_test4);
KZT_TEST_INIT(sub, KZT_CONDVAR_TEST5_NAME, KZT_CONDVAR_TEST5_DESC,
KZT_CONDVAR_TEST5_ID, kzt_condvar_test5);
SPLAT_TEST_INIT(sub, SPLAT_CONDVAR_TEST1_NAME, SPLAT_CONDVAR_TEST1_DESC,
SPLAT_CONDVAR_TEST1_ID, splat_condvar_test1);
SPLAT_TEST_INIT(sub, SPLAT_CONDVAR_TEST2_NAME, SPLAT_CONDVAR_TEST2_DESC,
SPLAT_CONDVAR_TEST2_ID, splat_condvar_test2);
SPLAT_TEST_INIT(sub, SPLAT_CONDVAR_TEST3_NAME, SPLAT_CONDVAR_TEST3_DESC,
SPLAT_CONDVAR_TEST3_ID, splat_condvar_test3);
SPLAT_TEST_INIT(sub, SPLAT_CONDVAR_TEST4_NAME, SPLAT_CONDVAR_TEST4_DESC,
SPLAT_CONDVAR_TEST4_ID, splat_condvar_test4);
SPLAT_TEST_INIT(sub, SPLAT_CONDVAR_TEST5_NAME, SPLAT_CONDVAR_TEST5_DESC,
SPLAT_CONDVAR_TEST5_ID, splat_condvar_test5);
return sub;
}
void
kzt_condvar_fini(kzt_subsystem_t *sub)
splat_condvar_fini(splat_subsystem_t *sub)
{
ASSERT(sub);
KZT_TEST_FINI(sub, KZT_CONDVAR_TEST5_ID);
KZT_TEST_FINI(sub, KZT_CONDVAR_TEST4_ID);
KZT_TEST_FINI(sub, KZT_CONDVAR_TEST3_ID);
KZT_TEST_FINI(sub, KZT_CONDVAR_TEST2_ID);
KZT_TEST_FINI(sub, KZT_CONDVAR_TEST1_ID);
SPLAT_TEST_FINI(sub, SPLAT_CONDVAR_TEST5_ID);
SPLAT_TEST_FINI(sub, SPLAT_CONDVAR_TEST4_ID);
SPLAT_TEST_FINI(sub, SPLAT_CONDVAR_TEST3_ID);
SPLAT_TEST_FINI(sub, SPLAT_CONDVAR_TEST2_ID);
SPLAT_TEST_FINI(sub, SPLAT_CONDVAR_TEST1_ID);
kfree(sub);
}
int
kzt_condvar_id(void) {
return KZT_SUBSYSTEM_CONDVAR;
splat_condvar_id(void) {
return SPLAT_SUBSYSTEM_CONDVAR;
}

View File

@ -1,25 +1,23 @@
/*
* My intent is the create a loadable kzt (kernel ZFS test) module
* which can be used as an access point to run in kernel ZFS regression
* tests. Why do we need this when we have ztest? Well ztest.c only
* excersises the ZFS code proper, it cannot be used to validate the
* linux kernel shim primatives. This also provides a nice hook for
* any other in kernel regression tests we wish to run such as direct
* in-kernel tests against the DMU.
* My intent is to create a loadable 'splat' (solaris porting layer
* aggressive test) module which can be used as an access point to
* run in kernel Solaris ABI regression tests. This provides a
* nice mechanism to validate the shim primates are working properly.
*
* The basic design is the kzt module is that it is constructed of
* various kzt_* source files each of which contains regression tests.
* For example the kzt_linux_kmem.c file contains tests for validating
* kmem correctness. When the kzt module is loaded kzt_*_init()
* will be called for each subsystems tests, similarly kzt_*_fini() is
* called when the kzt module is removed. Each test can then be
* The basic design is the splat module is that it is constructed of
* various splat_* source files each of which contains regression tests.
* For example the splat_linux_kmem.c file contains tests for validating
* kmem correctness. When the splat module is loaded splat_*_init()
* will be called for each subsystems tests, similarly splat_*_fini() is
* called when the splat module is removed. Each test can then be
* run by making an ioctl() call from a userspace control application
* to pick the subsystem and test which should be run.
*
* Author: Brian Behlendorf
*/
#include <splat-ctl.h>
#include "splat-internal.h"
#include <config.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
#include <linux/devfs_fs_kernel.h>
@ -29,29 +27,29 @@
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
static struct class_simple *kzt_class;
static struct class_simple *splat_class;
#else
static struct class *kzt_class;
static struct class *splat_class;
#endif
static struct list_head kzt_module_list;
static spinlock_t kzt_module_lock;
static struct list_head splat_module_list;
static spinlock_t splat_module_lock;
static int
kzt_open(struct inode *inode, struct file *file)
splat_open(struct inode *inode, struct file *file)
{
unsigned int minor = iminor(inode);
kzt_info_t *info;
splat_info_t *info;
if (minor >= KZT_MINORS)
if (minor >= SPLAT_MINORS)
return -ENXIO;
info = (kzt_info_t *)kmalloc(sizeof(*info), GFP_KERNEL);
info = (splat_info_t *)kmalloc(sizeof(*info), GFP_KERNEL);
if (info == NULL)
return -ENOMEM;
spin_lock_init(&info->info_lock);
info->info_size = KZT_INFO_BUFFER_SIZE;
info->info_buffer = (char *)vmalloc(KZT_INFO_BUFFER_SIZE);
info->info_size = SPLAT_INFO_BUFFER_SIZE;
info->info_buffer = (char *)vmalloc(SPLAT_INFO_BUFFER_SIZE);
if (info->info_buffer == NULL) {
kfree(info);
return -ENOMEM;
@ -60,18 +58,16 @@ kzt_open(struct inode *inode, struct file *file)
info->info_head = info->info_buffer;
file->private_data = (void *)info;
kzt_print(file, "Kernel ZFS Tests %s\n", KZT_VERSION);
return 0;
}
static int
kzt_release(struct inode *inode, struct file *file)
splat_release(struct inode *inode, struct file *file)
{
unsigned int minor = iminor(inode);
kzt_info_t *info = (kzt_info_t *)file->private_data;
splat_info_t *info = (splat_info_t *)file->private_data;
if (minor >= KZT_MINORS)
if (minor >= SPLAT_MINORS)
return -ENXIO;
ASSERT(info);
@ -84,9 +80,9 @@ kzt_release(struct inode *inode, struct file *file)
}
static int
kzt_buffer_clear(struct file *file, kzt_cfg_t *kcfg, unsigned long arg)
splat_buffer_clear(struct file *file, splat_cfg_t *kcfg, unsigned long arg)
{
kzt_info_t *info = (kzt_info_t *)file->private_data;
splat_info_t *info = (splat_info_t *)file->private_data;
ASSERT(info);
ASSERT(info->info_buffer);
@ -100,9 +96,9 @@ kzt_buffer_clear(struct file *file, kzt_cfg_t *kcfg, unsigned long arg)
}
static int
kzt_buffer_size(struct file *file, kzt_cfg_t *kcfg, unsigned long arg)
splat_buffer_size(struct file *file, splat_cfg_t *kcfg, unsigned long arg)
{
kzt_info_t *info = (kzt_info_t *)file->private_data;
splat_info_t *info = (splat_info_t *)file->private_data;
char *buf;
int min, size, rc = 0;
@ -131,7 +127,7 @@ kzt_buffer_size(struct file *file, kzt_cfg_t *kcfg, unsigned long arg)
kcfg->cfg_rc1 = info->info_size;
if (copy_to_user((struct kzt_cfg_t __user *)arg, kcfg, sizeof(*kcfg)))
if (copy_to_user((struct splat_cfg_t __user *)arg, kcfg, sizeof(*kcfg)))
rc = -EFAULT;
out:
spin_unlock(&info->info_lock);
@ -140,46 +136,46 @@ out:
}
static kzt_subsystem_t *
kzt_subsystem_find(int id) {
kzt_subsystem_t *sub;
static splat_subsystem_t *
splat_subsystem_find(int id) {
splat_subsystem_t *sub;
spin_lock(&kzt_module_lock);
list_for_each_entry(sub, &kzt_module_list, subsystem_list) {
spin_lock(&splat_module_lock);
list_for_each_entry(sub, &splat_module_list, subsystem_list) {
if (id == sub->desc.id) {
spin_unlock(&kzt_module_lock);
spin_unlock(&splat_module_lock);
return sub;
}
}
spin_unlock(&kzt_module_lock);
spin_unlock(&splat_module_lock);
return NULL;
}
static int
kzt_subsystem_count(kzt_cfg_t *kcfg, unsigned long arg)
splat_subsystem_count(splat_cfg_t *kcfg, unsigned long arg)
{
kzt_subsystem_t *sub;
splat_subsystem_t *sub;
int i = 0;
spin_lock(&kzt_module_lock);
list_for_each_entry(sub, &kzt_module_list, subsystem_list)
spin_lock(&splat_module_lock);
list_for_each_entry(sub, &splat_module_list, subsystem_list)
i++;
spin_unlock(&kzt_module_lock);
spin_unlock(&splat_module_lock);
kcfg->cfg_rc1 = i;
if (copy_to_user((struct kzt_cfg_t __user *)arg, kcfg, sizeof(*kcfg)))
if (copy_to_user((struct splat_cfg_t __user *)arg, kcfg, sizeof(*kcfg)))
return -EFAULT;
return 0;
}
static int
kzt_subsystem_list(kzt_cfg_t *kcfg, unsigned long arg)
splat_subsystem_list(splat_cfg_t *kcfg, unsigned long arg)
{
kzt_subsystem_t *sub;
kzt_cfg_t *tmp;
splat_subsystem_t *sub;
splat_cfg_t *tmp;
int size, i = 0;
/* Structure will be sized large enough for N subsystem entries
@ -188,8 +184,8 @@ kzt_subsystem_list(kzt_cfg_t *kcfg, unsigned long arg)
* cfg_rc1. If the caller does not provide enough entries
* for all subsystems we will truncate the list to avoid overrun.
*/
size = sizeof(*tmp) + kcfg->cfg_data.kzt_subsystems.size *
sizeof(kzt_user_t);
size = sizeof(*tmp) + kcfg->cfg_data.splat_subsystems.size *
sizeof(splat_user_t);
tmp = kmalloc(size, GFP_KERNEL);
if (tmp == NULL)
return -ENOMEM;
@ -198,22 +194,22 @@ kzt_subsystem_list(kzt_cfg_t *kcfg, unsigned long arg)
memset(tmp, 0, size);
memcpy(tmp, kcfg, sizeof(*kcfg));
spin_lock(&kzt_module_lock);
list_for_each_entry(sub, &kzt_module_list, subsystem_list) {
strncpy(tmp->cfg_data.kzt_subsystems.descs[i].name,
sub->desc.name, KZT_NAME_SIZE);
strncpy(tmp->cfg_data.kzt_subsystems.descs[i].desc,
sub->desc.desc, KZT_DESC_SIZE);
tmp->cfg_data.kzt_subsystems.descs[i].id = sub->desc.id;
spin_lock(&splat_module_lock);
list_for_each_entry(sub, &splat_module_list, subsystem_list) {
strncpy(tmp->cfg_data.splat_subsystems.descs[i].name,
sub->desc.name, SPLAT_NAME_SIZE);
strncpy(tmp->cfg_data.splat_subsystems.descs[i].desc,
sub->desc.desc, SPLAT_DESC_SIZE);
tmp->cfg_data.splat_subsystems.descs[i].id = sub->desc.id;
/* Truncate list if we are about to overrun alloc'ed memory */
if ((i++) == kcfg->cfg_data.kzt_subsystems.size)
if ((i++) == kcfg->cfg_data.splat_subsystems.size)
break;
}
spin_unlock(&kzt_module_lock);
spin_unlock(&splat_module_lock);
tmp->cfg_rc1 = i;
if (copy_to_user((struct kzt_cfg_t __user *)arg, tmp, size)) {
if (copy_to_user((struct splat_cfg_t __user *)arg, tmp, size)) {
kfree(tmp);
return -EFAULT;
}
@ -223,14 +219,14 @@ kzt_subsystem_list(kzt_cfg_t *kcfg, unsigned long arg)
}
static int
kzt_test_count(kzt_cfg_t *kcfg, unsigned long arg)
splat_test_count(splat_cfg_t *kcfg, unsigned long arg)
{
kzt_subsystem_t *sub;
kzt_test_t *test;
splat_subsystem_t *sub;
splat_test_t *test;
int i = 0;
/* Subsystem ID passed as arg1 */
sub = kzt_subsystem_find(kcfg->cfg_arg1);
sub = splat_subsystem_find(kcfg->cfg_arg1);
if (sub == NULL)
return -EINVAL;
@ -241,22 +237,22 @@ kzt_test_count(kzt_cfg_t *kcfg, unsigned long arg)
spin_unlock(&(sub->test_lock));
kcfg->cfg_rc1 = i;
if (copy_to_user((struct kzt_cfg_t __user *)arg, kcfg, sizeof(*kcfg)))
if (copy_to_user((struct splat_cfg_t __user *)arg, kcfg, sizeof(*kcfg)))
return -EFAULT;
return 0;
}
static int
kzt_test_list(kzt_cfg_t *kcfg, unsigned long arg)
splat_test_list(splat_cfg_t *kcfg, unsigned long arg)
{
kzt_subsystem_t *sub;
kzt_test_t *test;
kzt_cfg_t *tmp;
splat_subsystem_t *sub;
splat_test_t *test;
splat_cfg_t *tmp;
int size, i = 0;
/* Subsystem ID passed as arg1 */
sub = kzt_subsystem_find(kcfg->cfg_arg1);
sub = splat_subsystem_find(kcfg->cfg_arg1);
if (sub == NULL)
return -EINVAL;
@ -266,7 +262,7 @@ kzt_test_list(kzt_cfg_t *kcfg, unsigned long arg)
* cfg_rc1. If the caller does not provide enough entries
* for all tests we will truncate the list to avoid overrun.
*/
size = sizeof(*tmp)+kcfg->cfg_data.kzt_tests.size*sizeof(kzt_user_t);
size = sizeof(*tmp)+kcfg->cfg_data.splat_tests.size*sizeof(splat_user_t);
tmp = kmalloc(size, GFP_KERNEL);
if (tmp == NULL)
return -ENOMEM;
@ -277,20 +273,20 @@ kzt_test_list(kzt_cfg_t *kcfg, unsigned long arg)
spin_lock(&(sub->test_lock));
list_for_each_entry(test, &(sub->test_list), test_list) {
strncpy(tmp->cfg_data.kzt_tests.descs[i].name,
test->desc.name, KZT_NAME_SIZE);
strncpy(tmp->cfg_data.kzt_tests.descs[i].desc,
test->desc.desc, KZT_DESC_SIZE);
tmp->cfg_data.kzt_tests.descs[i].id = test->desc.id;
strncpy(tmp->cfg_data.splat_tests.descs[i].name,
test->desc.name, SPLAT_NAME_SIZE);
strncpy(tmp->cfg_data.splat_tests.descs[i].desc,
test->desc.desc, SPLAT_DESC_SIZE);
tmp->cfg_data.splat_tests.descs[i].id = test->desc.id;
/* Truncate list if we are about to overrun alloc'ed memory */
if ((i++) == kcfg->cfg_data.kzt_tests.size)
if ((i++) == kcfg->cfg_data.splat_tests.size)
break;
}
spin_unlock(&(sub->test_lock));
tmp->cfg_rc1 = i;
if (copy_to_user((struct kzt_cfg_t __user *)arg, tmp, size)) {
if (copy_to_user((struct splat_cfg_t __user *)arg, tmp, size)) {
kfree(tmp);
return -EFAULT;
}
@ -300,9 +296,9 @@ kzt_test_list(kzt_cfg_t *kcfg, unsigned long arg)
}
static int
kzt_validate(struct file *file, kzt_subsystem_t *sub, int cmd, void *arg)
splat_validate(struct file *file, splat_subsystem_t *sub, int cmd, void *arg)
{
kzt_test_t *test;
splat_test_t *test;
spin_lock(&(sub->test_lock));
list_for_each_entry(test, &(sub->test_list), test_list) {
@ -317,61 +313,61 @@ kzt_validate(struct file *file, kzt_subsystem_t *sub, int cmd, void *arg)
}
static int
kzt_ioctl_cfg(struct file *file, unsigned long arg)
splat_ioctl_cfg(struct file *file, unsigned long arg)
{
kzt_cfg_t kcfg;
splat_cfg_t kcfg;
int rc = 0;
if (copy_from_user(&kcfg, (kzt_cfg_t *)arg, sizeof(kcfg)))
if (copy_from_user(&kcfg, (splat_cfg_t *)arg, sizeof(kcfg)))
return -EFAULT;
if (kcfg.cfg_magic != KZT_CFG_MAGIC) {
kzt_print(file, "Bad config magic 0x%x != 0x%x\n",
kcfg.cfg_magic, KZT_CFG_MAGIC);
if (kcfg.cfg_magic != SPLAT_CFG_MAGIC) {
splat_print(file, "Bad config magic 0x%x != 0x%x\n",
kcfg.cfg_magic, SPLAT_CFG_MAGIC);
return -EINVAL;
}
switch (kcfg.cfg_cmd) {
case KZT_CFG_BUFFER_CLEAR:
case SPLAT_CFG_BUFFER_CLEAR:
/* cfg_arg1 - Unused
* cfg_rc1 - Unused
*/
rc = kzt_buffer_clear(file, &kcfg, arg);
rc = splat_buffer_clear(file, &kcfg, arg);
break;
case KZT_CFG_BUFFER_SIZE:
case SPLAT_CFG_BUFFER_SIZE:
/* cfg_arg1 - 0 - query size; >0 resize
* cfg_rc1 - Set to current buffer size
*/
rc = kzt_buffer_size(file, &kcfg, arg);
rc = splat_buffer_size(file, &kcfg, arg);
break;
case KZT_CFG_SUBSYSTEM_COUNT:
case SPLAT_CFG_SUBSYSTEM_COUNT:
/* cfg_arg1 - Unused
* cfg_rc1 - Set to number of subsystems
*/
rc = kzt_subsystem_count(&kcfg, arg);
rc = splat_subsystem_count(&kcfg, arg);
break;
case KZT_CFG_SUBSYSTEM_LIST:
case SPLAT_CFG_SUBSYSTEM_LIST:
/* cfg_arg1 - Unused
* cfg_rc1 - Set to number of subsystems
* cfg_data.kzt_subsystems - Populated with subsystems
* cfg_data.splat_subsystems - Populated with subsystems
*/
rc = kzt_subsystem_list(&kcfg, arg);
rc = splat_subsystem_list(&kcfg, arg);
break;
case KZT_CFG_TEST_COUNT:
case SPLAT_CFG_TEST_COUNT:
/* cfg_arg1 - Set to a target subsystem
* cfg_rc1 - Set to number of tests
*/
rc = kzt_test_count(&kcfg, arg);
rc = splat_test_count(&kcfg, arg);
break;
case KZT_CFG_TEST_LIST:
case SPLAT_CFG_TEST_LIST:
/* cfg_arg1 - Set to a target subsystem
* cfg_rc1 - Set to number of tests
* cfg_data.kzt_subsystems - Populated with tests
* cfg_data.splat_subsystems - Populated with tests
*/
rc = kzt_test_list(&kcfg, arg);
rc = splat_test_list(&kcfg, arg);
break;
default:
kzt_print(file, "Bad config command %d\n", kcfg.cfg_cmd);
splat_print(file, "Bad config command %d\n", kcfg.cfg_cmd);
rc = -EINVAL;
break;
}
@ -380,19 +376,19 @@ kzt_ioctl_cfg(struct file *file, unsigned long arg)
}
static int
kzt_ioctl_cmd(struct file *file, unsigned long arg)
splat_ioctl_cmd(struct file *file, unsigned long arg)
{
kzt_subsystem_t *sub;
kzt_cmd_t kcmd;
splat_subsystem_t *sub;
splat_cmd_t kcmd;
int rc = -EINVAL;
void *data = NULL;
if (copy_from_user(&kcmd, (kzt_cfg_t *)arg, sizeof(kcmd)))
if (copy_from_user(&kcmd, (splat_cfg_t *)arg, sizeof(kcmd)))
return -EFAULT;
if (kcmd.cmd_magic != KZT_CMD_MAGIC) {
kzt_print(file, "Bad command magic 0x%x != 0x%x\n",
kcmd.cmd_magic, KZT_CFG_MAGIC);
if (kcmd.cmd_magic != SPLAT_CMD_MAGIC) {
splat_print(file, "Bad command magic 0x%x != 0x%x\n",
kcmd.cmd_magic, SPLAT_CFG_MAGIC);
return -EINVAL;
}
@ -402,16 +398,16 @@ kzt_ioctl_cmd(struct file *file, unsigned long arg)
if (data == NULL)
return -ENOMEM;
if (copy_from_user(data, (void *)(arg + offsetof(kzt_cmd_t,
if (copy_from_user(data, (void *)(arg + offsetof(splat_cmd_t,
cmd_data_str)), kcmd.cmd_data_size)) {
kfree(data);
return -EFAULT;
}
}
sub = kzt_subsystem_find(kcmd.cmd_subsystem);
sub = splat_subsystem_find(kcmd.cmd_subsystem);
if (sub != NULL)
rc = kzt_validate(file, sub, kcmd.cmd_test, data);
rc = splat_validate(file, sub, kcmd.cmd_test, data);
else
rc = -EINVAL;
@ -422,7 +418,7 @@ kzt_ioctl_cmd(struct file *file, unsigned long arg)
}
static int
kzt_ioctl(struct inode *inode, struct file *file,
splat_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
unsigned int minor = iminor(file->f_dentry->d_inode);
@ -432,18 +428,18 @@ kzt_ioctl(struct inode *inode, struct file *file,
if ((cmd & 0xffffff00) == ((int)'T') << 8)
return -ENOTTY;
if (minor >= KZT_MINORS)
if (minor >= SPLAT_MINORS)
return -ENXIO;
switch (cmd) {
case KZT_CFG:
rc = kzt_ioctl_cfg(file, arg);
case SPLAT_CFG:
rc = splat_ioctl_cfg(file, arg);
break;
case KZT_CMD:
rc = kzt_ioctl_cmd(file, arg);
case SPLAT_CMD:
rc = splat_ioctl_cmd(file, arg);
break;
default:
kzt_print(file, "Bad ioctl command %d\n", cmd);
splat_print(file, "Bad ioctl command %d\n", cmd);
rc = -EINVAL;
break;
}
@ -455,14 +451,14 @@ kzt_ioctl(struct inode *inode, struct file *file,
* user space since its principle use is to pass test status info
* back to the user space, but I don't see any reason to prevent it.
*/
static ssize_t kzt_write(struct file *file, const char __user *buf,
static ssize_t splat_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
unsigned int minor = iminor(file->f_dentry->d_inode);
kzt_info_t *info = (kzt_info_t *)file->private_data;
splat_info_t *info = (splat_info_t *)file->private_data;
int rc = 0;
if (minor >= KZT_MINORS)
if (minor >= SPLAT_MINORS)
return -ENXIO;
ASSERT(info);
@ -492,14 +488,14 @@ out:
return rc;
}
static ssize_t kzt_read(struct file *file, char __user *buf,
static ssize_t splat_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
unsigned int minor = iminor(file->f_dentry->d_inode);
kzt_info_t *info = (kzt_info_t *)file->private_data;
splat_info_t *info = (splat_info_t *)file->private_data;
int rc = 0;
if (minor >= KZT_MINORS)
if (minor >= SPLAT_MINORS)
return -ENXIO;
ASSERT(info);
@ -527,13 +523,13 @@ out:
return rc;
}
static loff_t kzt_seek(struct file *file, loff_t offset, int origin)
static loff_t splat_seek(struct file *file, loff_t offset, int origin)
{
unsigned int minor = iminor(file->f_dentry->d_inode);
kzt_info_t *info = (kzt_info_t *)file->private_data;
splat_info_t *info = (splat_info_t *)file->private_data;
int rc = -EINVAL;
if (minor >= KZT_MINORS)
if (minor >= SPLAT_MINORS)
return -ENXIO;
ASSERT(info);
@ -563,115 +559,116 @@ static loff_t kzt_seek(struct file *file, loff_t offset, int origin)
return rc;
}
static struct file_operations kzt_fops = {
static struct file_operations splat_fops = {
.owner = THIS_MODULE,
.open = kzt_open,
.release = kzt_release,
.ioctl = kzt_ioctl,
.read = kzt_read,
.write = kzt_write,
.llseek = kzt_seek,
.open = splat_open,
.release = splat_release,
.ioctl = splat_ioctl,
.read = splat_read,
.write = splat_write,
.llseek = splat_seek,
};
static struct cdev kzt_cdev = {
static struct cdev splat_cdev = {
.owner = THIS_MODULE,
.kobj = { .name = "kztctl", },
.kobj = { .name = "splatctl", },
};
static int __init
kzt_init(void)
splat_init(void)
{
dev_t dev;
int rc;
spin_lock_init(&kzt_module_lock);
INIT_LIST_HEAD(&kzt_module_list);
spin_lock_init(&splat_module_lock);
INIT_LIST_HEAD(&splat_module_list);
KZT_SUBSYSTEM_INIT(kmem);
KZT_SUBSYSTEM_INIT(taskq);
KZT_SUBSYSTEM_INIT(krng);
KZT_SUBSYSTEM_INIT(mutex);
KZT_SUBSYSTEM_INIT(condvar);
KZT_SUBSYSTEM_INIT(thread);
KZT_SUBSYSTEM_INIT(rwlock);
KZT_SUBSYSTEM_INIT(time);
SPLAT_SUBSYSTEM_INIT(kmem);
SPLAT_SUBSYSTEM_INIT(taskq);
SPLAT_SUBSYSTEM_INIT(krng);
SPLAT_SUBSYSTEM_INIT(mutex);
SPLAT_SUBSYSTEM_INIT(condvar);
SPLAT_SUBSYSTEM_INIT(thread);
SPLAT_SUBSYSTEM_INIT(rwlock);
SPLAT_SUBSYSTEM_INIT(time);
dev = MKDEV(KZT_MAJOR, 0);
if ((rc = register_chrdev_region(dev, KZT_MINORS, "kztctl")))
dev = MKDEV(SPLAT_MAJOR, 0);
if ((rc = register_chrdev_region(dev, SPLAT_MINORS, "splatctl")))
goto error;
/* Support for registering a character driver */
cdev_init(&kzt_cdev, &kzt_fops);
if ((rc = cdev_add(&kzt_cdev, dev, KZT_MINORS))) {
printk(KERN_ERR "kzt: Error adding cdev, %d\n", rc);
kobject_put(&kzt_cdev.kobj);
unregister_chrdev_region(dev, KZT_MINORS);
cdev_init(&splat_cdev, &splat_fops);
if ((rc = cdev_add(&splat_cdev, dev, SPLAT_MINORS))) {
printk(KERN_ERR "splat: Error adding cdev, %d\n", rc);
kobject_put(&splat_cdev.kobj);
unregister_chrdev_region(dev, SPLAT_MINORS);
goto error;
}
/* Support for udev make driver info available in sysfs */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
kzt_class = class_simple_create(THIS_MODULE, "kzt");
splat_class = class_simple_create(THIS_MODULE, "splat");
#else
kzt_class = class_create(THIS_MODULE, "kzt");
splat_class = class_create(THIS_MODULE, "splat");
#endif
if (IS_ERR(kzt_class)) {
rc = PTR_ERR(kzt_class);
printk(KERN_ERR "kzt: Error creating kzt class, %d\n", rc);
cdev_del(&kzt_cdev);
unregister_chrdev_region(dev, KZT_MINORS);
if (IS_ERR(splat_class)) {
rc = PTR_ERR(splat_class);
printk(KERN_ERR "splat: Error creating splat class, %d\n", rc);
cdev_del(&splat_cdev);
unregister_chrdev_region(dev, SPLAT_MINORS);
goto error;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
class_simple_device_add(kzt_class, MKDEV(KZT_MAJOR, 0),
NULL, "kztctl");
class_simple_device_add(splat_class, MKDEV(SPLAT_MAJOR, 0),
NULL, "splatctl");
#else
class_device_create(kzt_class, NULL, MKDEV(KZT_MAJOR, 0),
NULL, "kztctl");
class_device_create(splat_class, NULL, MKDEV(SPLAT_MAJOR, 0),
NULL, "splatctl");
#endif
printk(KERN_INFO "kzt: Kernel ZFS Tests %s Loaded\n", KZT_VERSION);
printk(KERN_INFO "splat: Loaded Solaris Porting Layer "
"Aggressive Tests v%s\n", VERSION);
return 0;
error:
printk(KERN_ERR "kzt: Error registering kzt device, %d\n", rc);
printk(KERN_ERR "splat: Error registering splat device, %d\n", rc);
return rc;
}
static void
kzt_fini(void)
splat_fini(void)
{
dev_t dev = MKDEV(KZT_MAJOR, 0);
dev_t dev = MKDEV(SPLAT_MAJOR, 0);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
class_simple_device_remove(dev);
class_simple_destroy(kzt_class);
devfs_remove("kzt/kztctl");
devfs_remove("kzt");
class_simple_destroy(splat_class);
devfs_remove("splat/splatctl");
devfs_remove("splat");
#else
class_device_destroy(kzt_class, dev);
class_destroy(kzt_class);
class_device_destroy(splat_class, dev);
class_destroy(splat_class);
#endif
cdev_del(&kzt_cdev);
unregister_chrdev_region(dev, KZT_MINORS);
cdev_del(&splat_cdev);
unregister_chrdev_region(dev, SPLAT_MINORS);
KZT_SUBSYSTEM_FINI(time);
KZT_SUBSYSTEM_FINI(rwlock);
KZT_SUBSYSTEM_FINI(thread);
KZT_SUBSYSTEM_FINI(condvar);
KZT_SUBSYSTEM_FINI(mutex);
KZT_SUBSYSTEM_FINI(krng);
KZT_SUBSYSTEM_FINI(taskq);
KZT_SUBSYSTEM_FINI(kmem);
SPLAT_SUBSYSTEM_FINI(time);
SPLAT_SUBSYSTEM_FINI(rwlock);
SPLAT_SUBSYSTEM_FINI(thread);
SPLAT_SUBSYSTEM_FINI(condvar);
SPLAT_SUBSYSTEM_FINI(mutex);
SPLAT_SUBSYSTEM_FINI(krng);
SPLAT_SUBSYSTEM_FINI(taskq);
SPLAT_SUBSYSTEM_FINI(kmem);
ASSERT(list_empty(&kzt_module_list));
printk(KERN_INFO "kzt: Kernel ZFS Tests %s Unloaded\n", KZT_VERSION);
ASSERT(list_empty(&splat_module_list));
printk(KERN_INFO "splat: Unloaded Solaris Porting Layer "
"Aggressive Tests v%s\n", VERSION);
}
module_init(kzt_init);
module_exit(kzt_fini);
module_init(splat_init);
module_exit(splat_fini);
MODULE_AUTHOR("Lawrence Livermore National Labs");
MODULE_DESCRIPTION("Kernel ZFS Test");
MODULE_DESCRIPTION("Solaris Porting Layer Aggresive Tests");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,191 @@
#ifndef _SPLAT_INTERNAL_H
#define _SPLAT_INTERNAL_H
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/elf.h>
#include <linux/limits.h>
#include <linux/version.h>
#include <linux/vmalloc.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/list.h>
#include <asm/ioctls.h>
#include <asm/uaccess.h>
#include <stdarg.h>
#include <linux-generic.h>
#include <linux-types.h>
#include <linux-kmem.h>
#include <linux-mutex.h>
#include <linux-condvar.h>
#include <linux-random.h>
#include <linux-thread.h>
#include <linux-taskq.h>
#include <linux-rwlock.h>
#include <linux-timer.h>
#include <linux-time.h>
#include <linux-cred.h>
#include <linux-kstat.h>
#include <linux-callb.h>
#include <splat-ctl.h>
#define SPLAT_SUBSYSTEM_INIT(type) \
({ splat_subsystem_t *_sub_; \
\
_sub_ = (splat_subsystem_t *)splat_##type##_init(); \
if (_sub_ == NULL) { \
printk(KERN_ERR "Error initializing: " #type "\n"); \
} else { \
spin_lock(&splat_module_lock); \
list_add_tail(&(_sub_->subsystem_list), \
&splat_module_list); \
spin_unlock(&splat_module_lock); \
} \
})
#define SPLAT_SUBSYSTEM_FINI(type) \
({ splat_subsystem_t *_sub_, *_tmp_; \
int _id_, _flag_ = 0; \
\
_id_ = splat_##type##_id(); \
spin_lock(&splat_module_lock); \
list_for_each_entry_safe(_sub_, _tmp_, &splat_module_list, \
subsystem_list) { \
if (_sub_->desc.id == _id_) { \
list_del_init(&(_sub_->subsystem_list)); \
spin_unlock(&splat_module_lock); \
splat_##type##_fini(_sub_); \
spin_lock(&splat_module_lock); \
_flag_ = 1; \
} \
} \
spin_unlock(&splat_module_lock); \
\
if (!_flag_) \
printk(KERN_ERR "Error finalizing: " #type "\n"); \
})
#define SPLAT_TEST_INIT(sub, n, d, tid, func) \
({ splat_test_t *_test_; \
\
_test_ = (splat_test_t *)kmalloc(sizeof(*_test_), GFP_KERNEL); \
if (_test_ == NULL) { \
printk(KERN_ERR "Error initializing: " n "/" #tid" \n");\
} else { \
memset(_test_, 0, sizeof(*_test_)); \
strncpy(_test_->desc.name, n, SPLAT_NAME_SIZE); \
strncpy(_test_->desc.desc, d, SPLAT_DESC_SIZE); \
_test_->desc.id = tid; \
_test_->test = func; \
INIT_LIST_HEAD(&(_test_->test_list)); \
spin_lock(&((sub)->test_lock)); \
list_add_tail(&(_test_->test_list),&((sub)->test_list));\
spin_unlock(&((sub)->test_lock)); \
} \
})
#define SPLAT_TEST_FINI(sub, tid) \
({ splat_test_t *_test_, *_tmp_; \
int _flag_ = 0; \
\
spin_lock(&((sub)->test_lock)); \
list_for_each_entry_safe(_test_, _tmp_, \
&((sub)->test_list), test_list) { \
if (_test_->desc.id == tid) { \
list_del_init(&(_test_->test_list)); \
_flag_ = 1; \
} \
} \
spin_unlock(&((sub)->test_lock)); \
\
if (!_flag_) \
printk(KERN_ERR "Error finalizing: " #tid "\n"); \
})
typedef int (*splat_test_func_t)(struct file *, void *);
typedef struct splat_test {
struct list_head test_list;
splat_user_t desc;
splat_test_func_t test;
} splat_test_t;
typedef struct splat_subsystem {
struct list_head subsystem_list;/* List had to chain entries */
splat_user_t desc;
spinlock_t test_lock;
struct list_head test_list;
} splat_subsystem_t;
#define SPLAT_INFO_BUFFER_SIZE 65536
#define SPLAT_INFO_BUFFER_REDZONE 256
typedef struct splat_info {
spinlock_t info_lock;
int info_size;
char *info_buffer;
char *info_head; /* Internal kernel use only */
} splat_info_t;
#define sym2str(sym) (char *)(#sym)
#define splat_print(file, format, args...) \
({ splat_info_t *_info_ = (splat_info_t *)file->private_data; \
int _rc_; \
\
ASSERT(_info_); \
ASSERT(_info_->info_buffer); \
\
spin_lock(&_info_->info_lock); \
\
/* Don't allow the kernel to start a write in the red zone */ \
if ((int)(_info_->info_head - _info_->info_buffer) > \
(SPLAT_INFO_BUFFER_SIZE - SPLAT_INFO_BUFFER_REDZONE)) { \
_rc_ = -EOVERFLOW; \
} else { \
_rc_ = sprintf(_info_->info_head, format, args); \
if (_rc_ >= 0) \
_info_->info_head += _rc_; \
} \
\
spin_unlock(&_info_->info_lock); \
_rc_; \
})
#define splat_vprint(file, test, format, args...) \
splat_print(file, "%*s: " format, SPLAT_NAME_SIZE, test, args)
splat_subsystem_t * splat_condvar_init(void);
splat_subsystem_t * splat_kmem_init(void);
splat_subsystem_t * splat_mutex_init(void);
splat_subsystem_t * splat_krng_init(void);
splat_subsystem_t * splat_rwlock_init(void);
splat_subsystem_t * splat_taskq_init(void);
splat_subsystem_t * splat_thread_init(void);
splat_subsystem_t * splat_time_init(void);
void splat_condvar_fini(splat_subsystem_t *);
void splat_kmem_fini(splat_subsystem_t *);
void splat_mutex_fini(splat_subsystem_t *);
void splat_krng_fini(splat_subsystem_t *);
void splat_rwlock_fini(splat_subsystem_t *);
void splat_taskq_fini(splat_subsystem_t *);
void splat_thread_fini(splat_subsystem_t *);
void splat_time_fini(splat_subsystem_t *);
int splat_condvar_id(void);
int splat_kmem_id(void);
int splat_mutex_id(void);
int splat_krng_id(void);
int splat_rwlock_id(void);
int splat_taskq_id(void);
int splat_thread_id(void);
int splat_time_id(void);
#endif /* _SPLAT_INTERNAL_H */

View File

@ -1,51 +1,51 @@
#include <splat-ctl.h>
#include "splat-internal.h"
#define KZT_SUBSYSTEM_KMEM 0x0100
#define KZT_KMEM_NAME "kmem"
#define KZT_KMEM_DESC "Kernel Malloc/Slab Tests"
#define SPLAT_SUBSYSTEM_KMEM 0x0100
#define SPLAT_KMEM_NAME "kmem"
#define SPLAT_KMEM_DESC "Kernel Malloc/Slab Tests"
#define KZT_KMEM_TEST1_ID 0x0101
#define KZT_KMEM_TEST1_NAME "kmem_alloc"
#define KZT_KMEM_TEST1_DESC "Memory allocation test (kmem_alloc)"
#define SPLAT_KMEM_TEST1_ID 0x0101
#define SPLAT_KMEM_TEST1_NAME "kmem_alloc"
#define SPLAT_KMEM_TEST1_DESC "Memory allocation test (kmem_alloc)"
#define KZT_KMEM_TEST2_ID 0x0102
#define KZT_KMEM_TEST2_NAME "kmem_zalloc"
#define KZT_KMEM_TEST2_DESC "Memory allocation test (kmem_zalloc)"
#define SPLAT_KMEM_TEST2_ID 0x0102
#define SPLAT_KMEM_TEST2_NAME "kmem_zalloc"
#define SPLAT_KMEM_TEST2_DESC "Memory allocation test (kmem_zalloc)"
#define KZT_KMEM_TEST3_ID 0x0103
#define KZT_KMEM_TEST3_NAME "slab_alloc"
#define KZT_KMEM_TEST3_DESC "Slab constructor/destructor test"
#define SPLAT_KMEM_TEST3_ID 0x0103
#define SPLAT_KMEM_TEST3_NAME "slab_alloc"
#define SPLAT_KMEM_TEST3_DESC "Slab constructor/destructor test"
#define KZT_KMEM_TEST4_ID 0x0104
#define KZT_KMEM_TEST4_NAME "slab_reap"
#define KZT_KMEM_TEST4_DESC "Slab reaping test"
#define SPLAT_KMEM_TEST4_ID 0x0104
#define SPLAT_KMEM_TEST4_NAME "slab_reap"
#define SPLAT_KMEM_TEST4_DESC "Slab reaping test"
#define KZT_KMEM_ALLOC_COUNT 10
#define SPLAT_KMEM_ALLOC_COUNT 10
/* XXX - This test may fail under tight memory conditions */
static int
kzt_kmem_test1(struct file *file, void *arg)
splat_kmem_test1(struct file *file, void *arg)
{
void *ptr[KZT_KMEM_ALLOC_COUNT];
void *ptr[SPLAT_KMEM_ALLOC_COUNT];
int size = PAGE_SIZE;
int i, count, rc = 0;
while ((!rc) && (size < (PAGE_SIZE * 16))) {
count = 0;
for (i = 0; i < KZT_KMEM_ALLOC_COUNT; i++) {
for (i = 0; i < SPLAT_KMEM_ALLOC_COUNT; i++) {
ptr[i] = kmem_alloc(size, KM_SLEEP);
if (ptr[i])
count++;
}
for (i = 0; i < KZT_KMEM_ALLOC_COUNT; i++)
for (i = 0; i < SPLAT_KMEM_ALLOC_COUNT; i++)
if (ptr[i])
kmem_free(ptr[i], size);
kzt_vprint(file, KZT_KMEM_TEST1_NAME,
splat_vprint(file, SPLAT_KMEM_TEST1_NAME,
"%d byte allocations, %d/%d successful\n",
size, count, KZT_KMEM_ALLOC_COUNT);
if (count != KZT_KMEM_ALLOC_COUNT)
size, count, SPLAT_KMEM_ALLOC_COUNT);
if (count != SPLAT_KMEM_ALLOC_COUNT)
rc = -ENOMEM;
size *= 2;
@ -55,26 +55,26 @@ kzt_kmem_test1(struct file *file, void *arg)
}
static int
kzt_kmem_test2(struct file *file, void *arg)
splat_kmem_test2(struct file *file, void *arg)
{
void *ptr[KZT_KMEM_ALLOC_COUNT];
void *ptr[SPLAT_KMEM_ALLOC_COUNT];
int size = PAGE_SIZE;
int i, j, count, rc = 0;
while ((!rc) && (size < (PAGE_SIZE * 16))) {
count = 0;
for (i = 0; i < KZT_KMEM_ALLOC_COUNT; i++) {
for (i = 0; i < SPLAT_KMEM_ALLOC_COUNT; i++) {
ptr[i] = kmem_zalloc(size, KM_SLEEP);
if (ptr[i])
count++;
}
/* Ensure buffer has been zero filled */
for (i = 0; i < KZT_KMEM_ALLOC_COUNT; i++) {
for (i = 0; i < SPLAT_KMEM_ALLOC_COUNT; i++) {
for (j = 0; j < size; j++) {
if (((char *)ptr[i])[j] != '\0') {
kzt_vprint(file, KZT_KMEM_TEST2_NAME,
splat_vprint(file, SPLAT_KMEM_TEST2_NAME,
"%d-byte allocation was "
"not zeroed\n", size);
rc = -EFAULT;
@ -82,14 +82,14 @@ kzt_kmem_test2(struct file *file, void *arg)
}
}
for (i = 0; i < KZT_KMEM_ALLOC_COUNT; i++)
for (i = 0; i < SPLAT_KMEM_ALLOC_COUNT; i++)
if (ptr[i])
kmem_free(ptr[i], size);
kzt_vprint(file, KZT_KMEM_TEST2_NAME,
splat_vprint(file, SPLAT_KMEM_TEST2_NAME,
"%d byte allocations, %d/%d successful\n",
size, count, KZT_KMEM_ALLOC_COUNT);
if (count != KZT_KMEM_ALLOC_COUNT)
size, count, SPLAT_KMEM_ALLOC_COUNT);
if (count != SPLAT_KMEM_ALLOC_COUNT)
rc = -ENOMEM;
size *= 2;
@ -98,14 +98,14 @@ kzt_kmem_test2(struct file *file, void *arg)
return rc;
}
#define KZT_KMEM_TEST_MAGIC 0x004488CCUL
#define KZT_KMEM_CACHE_NAME "kmem_test"
#define KZT_KMEM_CACHE_SIZE 256
#define KZT_KMEM_OBJ_COUNT 128
#define KZT_KMEM_OBJ_RECLAIM 64
#define SPLAT_KMEM_TEST_MAGIC 0x004488CCUL
#define SPLAT_KMEM_CACHE_NAME "kmem_test"
#define SPLAT_KMEM_CACHE_SIZE 256
#define SPLAT_KMEM_OBJ_COUNT 128
#define SPLAT_KMEM_OBJ_RECLAIM 64
typedef struct kmem_cache_data {
char kcd_buf[KZT_KMEM_CACHE_SIZE];
char kcd_buf[SPLAT_KMEM_CACHE_SIZE];
unsigned long kcd_magic;
int kcd_flag;
} kmem_cache_data_t;
@ -114,19 +114,19 @@ typedef struct kmem_cache_priv {
unsigned long kcp_magic;
struct file *kcp_file;
kmem_cache_t *kcp_cache;
kmem_cache_data_t *kcp_kcd[KZT_KMEM_OBJ_COUNT];
kmem_cache_data_t *kcp_kcd[SPLAT_KMEM_OBJ_COUNT];
int kcp_count;
int kcp_rc;
} kmem_cache_priv_t;
static int
kzt_kmem_test34_constructor(void *ptr, void *priv, int flags)
splat_kmem_test34_constructor(void *ptr, void *priv, int flags)
{
kmem_cache_data_t *kcd = (kmem_cache_data_t *)ptr;
kmem_cache_priv_t *kcp = (kmem_cache_priv_t *)priv;
if (kcd) {
memset(kcd->kcd_buf, 0xaa, KZT_KMEM_CACHE_SIZE);
memset(kcd->kcd_buf, 0xaa, SPLAT_KMEM_CACHE_SIZE);
kcd->kcd_flag = 1;
if (kcp) {
@ -139,13 +139,13 @@ kzt_kmem_test34_constructor(void *ptr, void *priv, int flags)
}
static void
kzt_kmem_test34_destructor(void *ptr, void *priv)
splat_kmem_test34_destructor(void *ptr, void *priv)
{
kmem_cache_data_t *kcd = (kmem_cache_data_t *)ptr;
kmem_cache_priv_t *kcp = (kmem_cache_priv_t *)priv;
if (kcd) {
memset(kcd->kcd_buf, 0xbb, KZT_KMEM_CACHE_SIZE);
memset(kcd->kcd_buf, 0xbb, SPLAT_KMEM_CACHE_SIZE);
kcd->kcd_flag = 0;
if (kcp)
@ -156,49 +156,49 @@ kzt_kmem_test34_destructor(void *ptr, void *priv)
}
static int
kzt_kmem_test3(struct file *file, void *arg)
splat_kmem_test3(struct file *file, void *arg)
{
kmem_cache_t *cache = NULL;
kmem_cache_data_t *kcd = NULL;
kmem_cache_priv_t kcp;
int rc = 0, max;
kcp.kcp_magic = KZT_KMEM_TEST_MAGIC;
kcp.kcp_magic = SPLAT_KMEM_TEST_MAGIC;
kcp.kcp_file = file;
kcp.kcp_count = 0;
kcp.kcp_rc = 0;
cache = kmem_cache_create(KZT_KMEM_CACHE_NAME, sizeof(*kcd), 0,
kzt_kmem_test34_constructor,
kzt_kmem_test34_destructor,
cache = kmem_cache_create(SPLAT_KMEM_CACHE_NAME, sizeof(*kcd), 0,
splat_kmem_test34_constructor,
splat_kmem_test34_destructor,
NULL, &kcp, NULL, 0);
if (!cache) {
kzt_vprint(file, KZT_KMEM_TEST3_NAME,
"Unable to create '%s'\n", KZT_KMEM_CACHE_NAME);
splat_vprint(file, SPLAT_KMEM_TEST3_NAME,
"Unable to create '%s'\n", SPLAT_KMEM_CACHE_NAME);
return -ENOMEM;
}
kcd = kmem_cache_alloc(cache, 0);
if (!kcd) {
kzt_vprint(file, KZT_KMEM_TEST3_NAME,
splat_vprint(file, SPLAT_KMEM_TEST3_NAME,
"Unable to allocate from '%s'\n",
KZT_KMEM_CACHE_NAME);
SPLAT_KMEM_CACHE_NAME);
rc = -EINVAL;
goto out_free;
}
if (!kcd->kcd_flag) {
kzt_vprint(file, KZT_KMEM_TEST3_NAME,
splat_vprint(file, SPLAT_KMEM_TEST3_NAME,
"Failed to run contructor for '%s'\n",
KZT_KMEM_CACHE_NAME);
SPLAT_KMEM_CACHE_NAME);
rc = -EINVAL;
goto out_free;
}
if (kcd->kcd_magic != kcp.kcp_magic) {
kzt_vprint(file, KZT_KMEM_TEST3_NAME,
splat_vprint(file, SPLAT_KMEM_TEST3_NAME,
"Failed to pass private data to constructor "
"for '%s'\n", KZT_KMEM_CACHE_NAME);
"for '%s'\n", SPLAT_KMEM_CACHE_NAME);
rc = -EINVAL;
goto out_free;
}
@ -213,15 +213,15 @@ kzt_kmem_test3(struct file *file, void *arg)
* run and we can verify one was called for every object */
kmem_cache_destroy(cache);
if (kcp.kcp_count) {
kzt_vprint(file, KZT_KMEM_TEST3_NAME,
splat_vprint(file, SPLAT_KMEM_TEST3_NAME,
"Failed to run destructor on all slab objects "
"for '%s'\n", KZT_KMEM_CACHE_NAME);
"for '%s'\n", SPLAT_KMEM_CACHE_NAME);
rc = -EINVAL;
}
kzt_vprint(file, KZT_KMEM_TEST3_NAME,
splat_vprint(file, SPLAT_KMEM_TEST3_NAME,
"%d allocated/destroyed objects for '%s'\n",
max, KZT_KMEM_CACHE_NAME);
max, SPLAT_KMEM_CACHE_NAME);
return rc;
@ -234,15 +234,15 @@ out_free:
}
static void
kzt_kmem_test4_reclaim(void *priv)
splat_kmem_test4_reclaim(void *priv)
{
kmem_cache_priv_t *kcp = (kmem_cache_priv_t *)priv;
int i;
kzt_vprint(kcp->kcp_file, KZT_KMEM_TEST4_NAME,
splat_vprint(kcp->kcp_file, SPLAT_KMEM_TEST4_NAME,
"Reaping %d objects from '%s'\n",
KZT_KMEM_OBJ_RECLAIM, KZT_KMEM_CACHE_NAME);
for (i = 0; i < KZT_KMEM_OBJ_RECLAIM; i++) {
SPLAT_KMEM_OBJ_RECLAIM, SPLAT_KMEM_CACHE_NAME);
for (i = 0; i < SPLAT_KMEM_OBJ_RECLAIM; i++) {
if (kcp->kcp_kcd[i]) {
kmem_cache_free(kcp->kcp_cache, kcp->kcp_kcd[i]);
kcp->kcp_kcd[i] = NULL;
@ -253,37 +253,37 @@ kzt_kmem_test4_reclaim(void *priv)
}
static int
kzt_kmem_test4(struct file *file, void *arg)
splat_kmem_test4(struct file *file, void *arg)
{
kmem_cache_t *cache;
kmem_cache_priv_t kcp;
int i, rc = 0, max, reclaim_percent, target_percent;
kcp.kcp_magic = KZT_KMEM_TEST_MAGIC;
kcp.kcp_magic = SPLAT_KMEM_TEST_MAGIC;
kcp.kcp_file = file;
kcp.kcp_count = 0;
kcp.kcp_rc = 0;
cache = kmem_cache_create(KZT_KMEM_CACHE_NAME,
cache = kmem_cache_create(SPLAT_KMEM_CACHE_NAME,
sizeof(kmem_cache_data_t), 0,
kzt_kmem_test34_constructor,
kzt_kmem_test34_destructor,
kzt_kmem_test4_reclaim, &kcp, NULL, 0);
splat_kmem_test34_constructor,
splat_kmem_test34_destructor,
splat_kmem_test4_reclaim, &kcp, NULL, 0);
if (!cache) {
kzt_vprint(file, KZT_KMEM_TEST4_NAME,
"Unable to create '%s'\n", KZT_KMEM_CACHE_NAME);
splat_vprint(file, SPLAT_KMEM_TEST4_NAME,
"Unable to create '%s'\n", SPLAT_KMEM_CACHE_NAME);
return -ENOMEM;
}
kcp.kcp_cache = cache;
for (i = 0; i < KZT_KMEM_OBJ_COUNT; i++) {
for (i = 0; i < SPLAT_KMEM_OBJ_COUNT; i++) {
/* All allocations need not succeed */
kcp.kcp_kcd[i] = kmem_cache_alloc(cache, 0);
if (!kcp.kcp_kcd[i]) {
kzt_vprint(file, KZT_KMEM_TEST4_NAME,
splat_vprint(file, SPLAT_KMEM_TEST4_NAME,
"Unable to allocate from '%s'\n",
KZT_KMEM_CACHE_NAME);
SPLAT_KMEM_CACHE_NAME);
}
}
@ -296,19 +296,19 @@ kzt_kmem_test4(struct file *file, void *arg)
kmem_cache_reap_now(cache);
reclaim_percent = ((kcp.kcp_count * 100) / max);
target_percent = (((KZT_KMEM_OBJ_COUNT - KZT_KMEM_OBJ_RECLAIM) * 100) /
KZT_KMEM_OBJ_COUNT);
kzt_vprint(file, KZT_KMEM_TEST4_NAME,
target_percent = (((SPLAT_KMEM_OBJ_COUNT - SPLAT_KMEM_OBJ_RECLAIM) * 100) /
SPLAT_KMEM_OBJ_COUNT);
splat_vprint(file, SPLAT_KMEM_TEST4_NAME,
"%d%% (%d/%d) of previous size, target of "
"%d%%-%d%% for '%s'\n", reclaim_percent, kcp.kcp_count,
max, target_percent - 10, target_percent + 10,
KZT_KMEM_CACHE_NAME);
SPLAT_KMEM_CACHE_NAME);
if ((reclaim_percent < target_percent - 10) ||
(reclaim_percent > target_percent + 10))
rc = -EINVAL;
/* Cleanup our mess */
for (i = 0; i < KZT_KMEM_OBJ_COUNT; i++)
for (i = 0; i < SPLAT_KMEM_OBJ_COUNT; i++)
if (kcp.kcp_kcd[i])
kmem_cache_free(cache, kcp.kcp_kcd[i]);
@ -317,48 +317,48 @@ kzt_kmem_test4(struct file *file, void *arg)
return rc;
}
kzt_subsystem_t *
kzt_kmem_init(void)
splat_subsystem_t *
splat_kmem_init(void)
{
kzt_subsystem_t *sub;
splat_subsystem_t *sub;
sub = kmalloc(sizeof(*sub), GFP_KERNEL);
if (sub == NULL)
return NULL;
memset(sub, 0, sizeof(*sub));
strncpy(sub->desc.name, KZT_KMEM_NAME, KZT_NAME_SIZE);
strncpy(sub->desc.desc, KZT_KMEM_DESC, KZT_DESC_SIZE);
strncpy(sub->desc.name, SPLAT_KMEM_NAME, SPLAT_NAME_SIZE);
strncpy(sub->desc.desc, SPLAT_KMEM_DESC, SPLAT_DESC_SIZE);
INIT_LIST_HEAD(&sub->subsystem_list);
INIT_LIST_HEAD(&sub->test_list);
spin_lock_init(&sub->test_lock);
sub->desc.id = KZT_SUBSYSTEM_KMEM;
sub->desc.id = SPLAT_SUBSYSTEM_KMEM;
KZT_TEST_INIT(sub, KZT_KMEM_TEST1_NAME, KZT_KMEM_TEST1_DESC,
KZT_KMEM_TEST1_ID, kzt_kmem_test1);
KZT_TEST_INIT(sub, KZT_KMEM_TEST2_NAME, KZT_KMEM_TEST2_DESC,
KZT_KMEM_TEST2_ID, kzt_kmem_test2);
KZT_TEST_INIT(sub, KZT_KMEM_TEST3_NAME, KZT_KMEM_TEST3_DESC,
KZT_KMEM_TEST3_ID, kzt_kmem_test3);
KZT_TEST_INIT(sub, KZT_KMEM_TEST4_NAME, KZT_KMEM_TEST4_DESC,
KZT_KMEM_TEST4_ID, kzt_kmem_test4);
SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST1_NAME, SPLAT_KMEM_TEST1_DESC,
SPLAT_KMEM_TEST1_ID, splat_kmem_test1);
SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST2_NAME, SPLAT_KMEM_TEST2_DESC,
SPLAT_KMEM_TEST2_ID, splat_kmem_test2);
SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST3_NAME, SPLAT_KMEM_TEST3_DESC,
SPLAT_KMEM_TEST3_ID, splat_kmem_test3);
SPLAT_TEST_INIT(sub, SPLAT_KMEM_TEST4_NAME, SPLAT_KMEM_TEST4_DESC,
SPLAT_KMEM_TEST4_ID, splat_kmem_test4);
return sub;
}
void
kzt_kmem_fini(kzt_subsystem_t *sub)
splat_kmem_fini(splat_subsystem_t *sub)
{
ASSERT(sub);
KZT_TEST_FINI(sub, KZT_KMEM_TEST4_ID);
KZT_TEST_FINI(sub, KZT_KMEM_TEST3_ID);
KZT_TEST_FINI(sub, KZT_KMEM_TEST2_ID);
KZT_TEST_FINI(sub, KZT_KMEM_TEST1_ID);
SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST4_ID);
SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST3_ID);
SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST2_ID);
SPLAT_TEST_FINI(sub, SPLAT_KMEM_TEST1_ID);
kfree(sub);
}
int
kzt_kmem_id(void) {
return KZT_SUBSYSTEM_KMEM;
splat_kmem_id(void) {
return SPLAT_SUBSYSTEM_KMEM;
}

View File

@ -1,45 +1,45 @@
#include <splat-ctl.h>
#include "splat-internal.h"
#define KZT_SUBSYSTEM_MUTEX 0x0400
#define KZT_MUTEX_NAME "mutex"
#define KZT_MUTEX_DESC "Kernel Mutex Tests"
#define SPLAT_SUBSYSTEM_MUTEX 0x0400
#define SPLAT_MUTEX_NAME "mutex"
#define SPLAT_MUTEX_DESC "Kernel Mutex Tests"
#define KZT_MUTEX_TEST1_ID 0x0401
#define KZT_MUTEX_TEST1_NAME "tryenter"
#define KZT_MUTEX_TEST1_DESC "Validate mutex_tryenter() correctness"
#define SPLAT_MUTEX_TEST1_ID 0x0401
#define SPLAT_MUTEX_TEST1_NAME "tryenter"
#define SPLAT_MUTEX_TEST1_DESC "Validate mutex_tryenter() correctness"
#define KZT_MUTEX_TEST2_ID 0x0402
#define KZT_MUTEX_TEST2_NAME "race"
#define KZT_MUTEX_TEST2_DESC "Many threads entering/exiting the mutex"
#define SPLAT_MUTEX_TEST2_ID 0x0402
#define SPLAT_MUTEX_TEST2_NAME "race"
#define SPLAT_MUTEX_TEST2_DESC "Many threads entering/exiting the mutex"
#define KZT_MUTEX_TEST3_ID 0x0403
#define KZT_MUTEX_TEST3_NAME "owned"
#define KZT_MUTEX_TEST3_DESC "Validate mutex_owned() correctness"
#define SPLAT_MUTEX_TEST3_ID 0x0403
#define SPLAT_MUTEX_TEST3_NAME "owned"
#define SPLAT_MUTEX_TEST3_DESC "Validate mutex_owned() correctness"
#define KZT_MUTEX_TEST4_ID 0x0404
#define KZT_MUTEX_TEST4_NAME "owner"
#define KZT_MUTEX_TEST4_DESC "Validate mutex_owner() correctness"
#define SPLAT_MUTEX_TEST4_ID 0x0404
#define SPLAT_MUTEX_TEST4_NAME "owner"
#define SPLAT_MUTEX_TEST4_DESC "Validate mutex_owner() correctness"
#define KZT_MUTEX_TEST_MAGIC 0x115599DDUL
#define KZT_MUTEX_TEST_NAME "mutex_test"
#define KZT_MUTEX_TEST_WORKQ "mutex_wq"
#define KZT_MUTEX_TEST_COUNT 128
#define SPLAT_MUTEX_TEST_MAGIC 0x115599DDUL
#define SPLAT_MUTEX_TEST_NAME "mutex_test"
#define SPLAT_MUTEX_TEST_WORKQ "mutex_wq"
#define SPLAT_MUTEX_TEST_COUNT 128
typedef struct mutex_priv {
unsigned long mp_magic;
struct file *mp_file;
struct work_struct mp_work[KZT_MUTEX_TEST_COUNT];
struct work_struct mp_work[SPLAT_MUTEX_TEST_COUNT];
kmutex_t mp_mtx;
int mp_rc;
} mutex_priv_t;
static void
kzt_mutex_test1_work(void *priv)
splat_mutex_test1_work(void *priv)
{
mutex_priv_t *mp = (mutex_priv_t *)priv;
ASSERT(mp->mp_magic == KZT_MUTEX_TEST_MAGIC);
ASSERT(mp->mp_magic == SPLAT_MUTEX_TEST_MAGIC);
mp->mp_rc = 0;
if (!mutex_tryenter(&mp->mp_mtx))
@ -47,7 +47,7 @@ kzt_mutex_test1_work(void *priv)
}
static int
kzt_mutex_test1(struct file *file, void *arg)
splat_mutex_test1(struct file *file, void *arg)
{
struct workqueue_struct *wq;
struct work_struct work;
@ -58,18 +58,18 @@ kzt_mutex_test1(struct file *file, void *arg)
if (mp == NULL)
return -ENOMEM;
wq = create_singlethread_workqueue(KZT_MUTEX_TEST_WORKQ);
wq = create_singlethread_workqueue(SPLAT_MUTEX_TEST_WORKQ);
if (wq == NULL) {
rc = -ENOMEM;
goto out2;
}
mutex_init(&(mp->mp_mtx), KZT_MUTEX_TEST_NAME, MUTEX_DEFAULT, NULL);
mutex_init(&(mp->mp_mtx), SPLAT_MUTEX_TEST_NAME, MUTEX_DEFAULT, NULL);
mutex_enter(&(mp->mp_mtx));
mp->mp_magic = KZT_MUTEX_TEST_MAGIC;
mp->mp_magic = SPLAT_MUTEX_TEST_MAGIC;
mp->mp_file = file;
INIT_WORK(&work, kzt_mutex_test1_work, mp);
INIT_WORK(&work, splat_mutex_test1_work, mp);
/* Schedule a work item which will try and aquire the mutex via
* mutex_tryenter() while its held. This should fail and the work
@ -89,7 +89,7 @@ kzt_mutex_test1(struct file *file, void *arg)
goto out;
}
kzt_vprint(file, KZT_MUTEX_TEST1_NAME, "%s",
splat_vprint(file, SPLAT_MUTEX_TEST1_NAME, "%s",
"mutex_trylock() correctly failed when mutex held\n");
/* Schedule a work item which will try and aquire the mutex via
@ -108,7 +108,7 @@ kzt_mutex_test1(struct file *file, void *arg)
goto out;
}
kzt_vprint(file, KZT_MUTEX_TEST1_NAME, "%s",
splat_vprint(file, SPLAT_MUTEX_TEST1_NAME, "%s",
"mutex_trylock() correctly succeeded when mutex unheld\n");
out:
mutex_destroy(&(mp->mp_mtx));
@ -120,12 +120,12 @@ out2:
}
static void
kzt_mutex_test2_work(void *priv)
splat_mutex_test2_work(void *priv)
{
mutex_priv_t *mp = (mutex_priv_t *)priv;
int rc;
ASSERT(mp->mp_magic == KZT_MUTEX_TEST_MAGIC);
ASSERT(mp->mp_magic == SPLAT_MUTEX_TEST_MAGIC);
/* Read the value before sleeping and write it after we wake up to
* maximize the chance of a race if mutexs are not working properly */
@ -138,7 +138,7 @@ kzt_mutex_test2_work(void *priv)
}
static int
kzt_mutex_test2(struct file *file, void *arg)
splat_mutex_test2(struct file *file, void *arg)
{
struct workqueue_struct *wq;
mutex_priv_t *mp;
@ -149,15 +149,15 @@ kzt_mutex_test2(struct file *file, void *arg)
return -ENOMEM;
/* Create a thread per CPU items on queue will race */
wq = create_workqueue(KZT_MUTEX_TEST_WORKQ);
wq = create_workqueue(SPLAT_MUTEX_TEST_WORKQ);
if (wq == NULL) {
rc = -ENOMEM;
goto out;
}
mutex_init(&(mp->mp_mtx), KZT_MUTEX_TEST_NAME, MUTEX_DEFAULT, NULL);
mutex_init(&(mp->mp_mtx), SPLAT_MUTEX_TEST_NAME, MUTEX_DEFAULT, NULL);
mp->mp_magic = KZT_MUTEX_TEST_MAGIC;
mp->mp_magic = SPLAT_MUTEX_TEST_MAGIC;
mp->mp_file = file;
mp->mp_rc = 0;
@ -167,11 +167,11 @@ kzt_mutex_test2(struct file *file, void *arg)
* mutex is instrumented such that if any two processors are in the
* critical region at the same time the system will panic. If the
* mutex is implemented right this will never happy, that's a pass. */
for (i = 0; i < KZT_MUTEX_TEST_COUNT; i++) {
INIT_WORK(&(mp->mp_work[i]), kzt_mutex_test2_work, mp);
for (i = 0; i < SPLAT_MUTEX_TEST_COUNT; i++) {
INIT_WORK(&(mp->mp_work[i]), splat_mutex_test2_work, mp);
if (!queue_work(wq, &(mp->mp_work[i]))) {
kzt_vprint(file, KZT_MUTEX_TEST2_NAME,
splat_vprint(file, SPLAT_MUTEX_TEST2_NAME,
"Failed to queue work id %d\n", i);
rc = -EINVAL;
}
@ -179,14 +179,14 @@ kzt_mutex_test2(struct file *file, void *arg)
flush_workqueue(wq);
if (mp->mp_rc == KZT_MUTEX_TEST_COUNT) {
kzt_vprint(file, KZT_MUTEX_TEST2_NAME, "%d racing threads "
if (mp->mp_rc == SPLAT_MUTEX_TEST_COUNT) {
splat_vprint(file, SPLAT_MUTEX_TEST2_NAME, "%d racing threads "
"correctly entered/exited the mutex %d times\n",
num_online_cpus(), mp->mp_rc);
} else {
kzt_vprint(file, KZT_MUTEX_TEST2_NAME, "%d racing threads "
splat_vprint(file, SPLAT_MUTEX_TEST2_NAME, "%d racing threads "
"only processed %d/%d mutex work items\n",
num_online_cpus(), mp->mp_rc, KZT_MUTEX_TEST_COUNT);
num_online_cpus(), mp->mp_rc, SPLAT_MUTEX_TEST_COUNT);
rc = -EINVAL;
}
@ -199,18 +199,18 @@ out:
}
static int
kzt_mutex_test3(struct file *file, void *arg)
splat_mutex_test3(struct file *file, void *arg)
{
kmutex_t mtx;
int rc = 0;
mutex_init(&mtx, KZT_MUTEX_TEST_NAME, MUTEX_DEFAULT, NULL);
mutex_init(&mtx, SPLAT_MUTEX_TEST_NAME, MUTEX_DEFAULT, NULL);
mutex_enter(&mtx);
/* Mutex should be owned by current */
if (!mutex_owned(&mtx)) {
kzt_vprint(file, KZT_MUTEX_TEST3_NAME, "Mutex should "
splat_vprint(file, SPLAT_MUTEX_TEST3_NAME, "Mutex should "
"be owned by pid %d but is owned by pid %d\n",
current->pid, mtx.km_owner ? mtx.km_owner->pid : -1);
rc = -EINVAL;
@ -221,14 +221,14 @@ kzt_mutex_test3(struct file *file, void *arg)
/* Mutex should not be owned by any task */
if (mutex_owned(&mtx)) {
kzt_vprint(file, KZT_MUTEX_TEST3_NAME, "Mutex should "
splat_vprint(file, SPLAT_MUTEX_TEST3_NAME, "Mutex should "
"not be owned but is owned by pid %d\n",
mtx.km_owner ? mtx.km_owner->pid : -1);
rc = -EINVAL;
goto out;
}
kzt_vprint(file, KZT_MUTEX_TEST3_NAME, "%s",
splat_vprint(file, SPLAT_MUTEX_TEST3_NAME, "%s",
"Correct mutex_owned() behavior\n");
out:
mutex_destroy(&mtx);
@ -237,20 +237,20 @@ out:
}
static int
kzt_mutex_test4(struct file *file, void *arg)
splat_mutex_test4(struct file *file, void *arg)
{
kmutex_t mtx;
kthread_t *owner;
int rc = 0;
mutex_init(&mtx, KZT_MUTEX_TEST_NAME, MUTEX_DEFAULT, NULL);
mutex_init(&mtx, SPLAT_MUTEX_TEST_NAME, MUTEX_DEFAULT, NULL);
mutex_enter(&mtx);
/* Mutex should be owned by current */
owner = mutex_owner(&mtx);
if (current != owner) {
kzt_vprint(file, KZT_MUTEX_TEST3_NAME, "Mutex should "
splat_vprint(file, SPLAT_MUTEX_TEST3_NAME, "Mutex should "
"be owned by pid %d but is owned by pid %d\n",
current->pid, owner ? owner->pid : -1);
rc = -EINVAL;
@ -262,13 +262,13 @@ kzt_mutex_test4(struct file *file, void *arg)
/* Mutex should not be owned by any task */
owner = mutex_owner(&mtx);
if (owner) {
kzt_vprint(file, KZT_MUTEX_TEST3_NAME, "Mutex should not "
splat_vprint(file, SPLAT_MUTEX_TEST3_NAME, "Mutex should not "
"be owned but is owned by pid %d\n", owner->pid);
rc = -EINVAL;
goto out;
}
kzt_vprint(file, KZT_MUTEX_TEST3_NAME, "%s",
splat_vprint(file, SPLAT_MUTEX_TEST3_NAME, "%s",
"Correct mutex_owner() behavior\n");
out:
mutex_destroy(&mtx);
@ -276,48 +276,48 @@ out:
return rc;
}
kzt_subsystem_t *
kzt_mutex_init(void)
splat_subsystem_t *
splat_mutex_init(void)
{
kzt_subsystem_t *sub;
splat_subsystem_t *sub;
sub = kmalloc(sizeof(*sub), GFP_KERNEL);
if (sub == NULL)
return NULL;
memset(sub, 0, sizeof(*sub));
strncpy(sub->desc.name, KZT_MUTEX_NAME, KZT_NAME_SIZE);
strncpy(sub->desc.desc, KZT_MUTEX_DESC, KZT_DESC_SIZE);
strncpy(sub->desc.name, SPLAT_MUTEX_NAME, SPLAT_NAME_SIZE);
strncpy(sub->desc.desc, SPLAT_MUTEX_DESC, SPLAT_DESC_SIZE);
INIT_LIST_HEAD(&sub->subsystem_list);
INIT_LIST_HEAD(&sub->test_list);
spin_lock_init(&sub->test_lock);
sub->desc.id = KZT_SUBSYSTEM_MUTEX;
sub->desc.id = SPLAT_SUBSYSTEM_MUTEX;
KZT_TEST_INIT(sub, KZT_MUTEX_TEST1_NAME, KZT_MUTEX_TEST1_DESC,
KZT_MUTEX_TEST1_ID, kzt_mutex_test1);
KZT_TEST_INIT(sub, KZT_MUTEX_TEST2_NAME, KZT_MUTEX_TEST2_DESC,
KZT_MUTEX_TEST2_ID, kzt_mutex_test2);
KZT_TEST_INIT(sub, KZT_MUTEX_TEST3_NAME, KZT_MUTEX_TEST3_DESC,
KZT_MUTEX_TEST3_ID, kzt_mutex_test3);
KZT_TEST_INIT(sub, KZT_MUTEX_TEST4_NAME, KZT_MUTEX_TEST4_DESC,
KZT_MUTEX_TEST4_ID, kzt_mutex_test4);
SPLAT_TEST_INIT(sub, SPLAT_MUTEX_TEST1_NAME, SPLAT_MUTEX_TEST1_DESC,
SPLAT_MUTEX_TEST1_ID, splat_mutex_test1);
SPLAT_TEST_INIT(sub, SPLAT_MUTEX_TEST2_NAME, SPLAT_MUTEX_TEST2_DESC,
SPLAT_MUTEX_TEST2_ID, splat_mutex_test2);
SPLAT_TEST_INIT(sub, SPLAT_MUTEX_TEST3_NAME, SPLAT_MUTEX_TEST3_DESC,
SPLAT_MUTEX_TEST3_ID, splat_mutex_test3);
SPLAT_TEST_INIT(sub, SPLAT_MUTEX_TEST4_NAME, SPLAT_MUTEX_TEST4_DESC,
SPLAT_MUTEX_TEST4_ID, splat_mutex_test4);
return sub;
}
void
kzt_mutex_fini(kzt_subsystem_t *sub)
splat_mutex_fini(splat_subsystem_t *sub)
{
ASSERT(sub);
KZT_TEST_FINI(sub, KZT_MUTEX_TEST4_ID);
KZT_TEST_FINI(sub, KZT_MUTEX_TEST3_ID);
KZT_TEST_FINI(sub, KZT_MUTEX_TEST2_ID);
KZT_TEST_FINI(sub, KZT_MUTEX_TEST1_ID);
SPLAT_TEST_FINI(sub, SPLAT_MUTEX_TEST4_ID);
SPLAT_TEST_FINI(sub, SPLAT_MUTEX_TEST3_ID);
SPLAT_TEST_FINI(sub, SPLAT_MUTEX_TEST2_ID);
SPLAT_TEST_FINI(sub, SPLAT_MUTEX_TEST1_ID);
kfree(sub);
}
int
kzt_mutex_id(void) {
return KZT_SUBSYSTEM_MUTEX;
splat_mutex_id(void) {
return SPLAT_SUBSYSTEM_MUTEX;
}

View File

@ -1,12 +1,12 @@
#include <splat-ctl.h>
#include "splat-internal.h"
#define KZT_SUBSYSTEM_KRNG 0x0300
#define KZT_KRNG_NAME "krng"
#define KZT_KRNG_DESC "Kernel Random Number Generator Tests"
#define SPLAT_SUBSYSTEM_KRNG 0x0300
#define SPLAT_KRNG_NAME "krng"
#define SPLAT_KRNG_DESC "Kernel Random Number Generator Tests"
#define KZT_KRNG_TEST1_ID 0x0301
#define KZT_KRNG_TEST1_NAME "freq"
#define KZT_KRNG_TEST1_DESC "Frequency Test"
#define SPLAT_KRNG_TEST1_ID 0x0301
#define SPLAT_KRNG_TEST1_NAME "freq"
#define SPLAT_KRNG_TEST1_DESC "Frequency Test"
#define KRNG_NUM_BITS 1048576
#define KRNG_NUM_BYTES (KRNG_NUM_BITS >> 3)
@ -22,7 +22,7 @@
but is probably not necessary for our purposes */
static int
kzt_krng_test1(struct file *file, void *arg)
splat_krng_test1(struct file *file, void *arg)
{
uint8_t *buf;
int i, j, diff, num = 0, rc = 0;
@ -54,8 +54,8 @@ kzt_krng_test1(struct file *file, void *arg)
if (diff < 0)
diff *= -1;
kzt_print(file, "Test 1 Number of ones: %d\n", num);
kzt_print(file, "Test 1 Difference from expected: %d Allowed: %d\n",
splat_print(file, "Test 1 Number of ones: %d\n", num);
splat_print(file, "Test 1 Difference from expected: %d Allowed: %d\n",
diff, KRNG_ERROR_RANGE);
if (diff > KRNG_ERROR_RANGE)
@ -64,40 +64,40 @@ out:
return rc;
}
kzt_subsystem_t *
kzt_krng_init(void)
splat_subsystem_t *
splat_krng_init(void)
{
kzt_subsystem_t *sub;
splat_subsystem_t *sub;
sub = kmalloc(sizeof(*sub), GFP_KERNEL);
if (sub == NULL)
return NULL;
memset(sub, 0, sizeof(*sub));
strncpy(sub->desc.name, KZT_KRNG_NAME, KZT_NAME_SIZE);
strncpy(sub->desc.desc, KZT_KRNG_DESC, KZT_DESC_SIZE);
strncpy(sub->desc.name, SPLAT_KRNG_NAME, SPLAT_NAME_SIZE);
strncpy(sub->desc.desc, SPLAT_KRNG_DESC, SPLAT_DESC_SIZE);
INIT_LIST_HEAD(&sub->subsystem_list);
INIT_LIST_HEAD(&sub->test_list);
spin_lock_init(&sub->test_lock);
sub->desc.id = KZT_SUBSYSTEM_KRNG;
sub->desc.id = SPLAT_SUBSYSTEM_KRNG;
KZT_TEST_INIT(sub, KZT_KRNG_TEST1_NAME, KZT_KRNG_TEST1_DESC,
KZT_KRNG_TEST1_ID, kzt_krng_test1);
SPLAT_TEST_INIT(sub, SPLAT_KRNG_TEST1_NAME, SPLAT_KRNG_TEST1_DESC,
SPLAT_KRNG_TEST1_ID, splat_krng_test1);
return sub;
}
void
kzt_krng_fini(kzt_subsystem_t *sub)
splat_krng_fini(splat_subsystem_t *sub)
{
ASSERT(sub);
KZT_TEST_FINI(sub, KZT_KRNG_TEST1_ID);
SPLAT_TEST_FINI(sub, SPLAT_KRNG_TEST1_ID);
kfree(sub);
}
int
kzt_krng_id(void) {
return KZT_SUBSYSTEM_KRNG;
splat_krng_id(void) {
return SPLAT_SUBSYSTEM_KRNG;
}

View File

@ -1,40 +1,40 @@
#include <splat-ctl.h>
#include "splat-internal.h"
#define KZT_SUBSYSTEM_RWLOCK 0x0700
#define KZT_RWLOCK_NAME "rwlock"
#define KZT_RWLOCK_DESC "Kernel RW Lock Tests"
#define SPLAT_SUBSYSTEM_RWLOCK 0x0700
#define SPLAT_RWLOCK_NAME "rwlock"
#define SPLAT_RWLOCK_DESC "Kernel RW Lock Tests"
#define KZT_RWLOCK_TEST1_ID 0x0701
#define KZT_RWLOCK_TEST1_NAME "rwtest1"
#define KZT_RWLOCK_TEST1_DESC "Multiple Readers One Writer"
#define SPLAT_RWLOCK_TEST1_ID 0x0701
#define SPLAT_RWLOCK_TEST1_NAME "rwtest1"
#define SPLAT_RWLOCK_TEST1_DESC "Multiple Readers One Writer"
#define KZT_RWLOCK_TEST2_ID 0x0702
#define KZT_RWLOCK_TEST2_NAME "rwtest2"
#define KZT_RWLOCK_TEST2_DESC "Multiple Writers"
#define SPLAT_RWLOCK_TEST2_ID 0x0702
#define SPLAT_RWLOCK_TEST2_NAME "rwtest2"
#define SPLAT_RWLOCK_TEST2_DESC "Multiple Writers"
#define KZT_RWLOCK_TEST3_ID 0x0703
#define KZT_RWLOCK_TEST3_NAME "rwtest3"
#define KZT_RWLOCK_TEST3_DESC "Owner Verification"
#define SPLAT_RWLOCK_TEST3_ID 0x0703
#define SPLAT_RWLOCK_TEST3_NAME "rwtest3"
#define SPLAT_RWLOCK_TEST3_DESC "Owner Verification"
#define KZT_RWLOCK_TEST4_ID 0x0704
#define KZT_RWLOCK_TEST4_NAME "rwtest4"
#define KZT_RWLOCK_TEST4_DESC "Trylock Test"
#define SPLAT_RWLOCK_TEST4_ID 0x0704
#define SPLAT_RWLOCK_TEST4_NAME "rwtest4"
#define SPLAT_RWLOCK_TEST4_DESC "Trylock Test"
#define KZT_RWLOCK_TEST5_ID 0x0705
#define KZT_RWLOCK_TEST5_NAME "rwtest5"
#define KZT_RWLOCK_TEST5_DESC "Write Downgrade Test"
#define SPLAT_RWLOCK_TEST5_ID 0x0705
#define SPLAT_RWLOCK_TEST5_NAME "rwtest5"
#define SPLAT_RWLOCK_TEST5_DESC "Write Downgrade Test"
#define KZT_RWLOCK_TEST6_ID 0x0706
#define KZT_RWLOCK_TEST6_NAME "rwtest6"
#define KZT_RWLOCK_TEST6_DESC "Read Upgrade Test"
#define SPLAT_RWLOCK_TEST6_ID 0x0706
#define SPLAT_RWLOCK_TEST6_NAME "rwtest6"
#define SPLAT_RWLOCK_TEST6_DESC "Read Upgrade Test"
#define KZT_RWLOCK_TEST_MAGIC 0x115599DDUL
#define KZT_RWLOCK_TEST_NAME "rwlock_test"
#define KZT_RWLOCK_TEST_COUNT 8
#define SPLAT_RWLOCK_TEST_MAGIC 0x115599DDUL
#define SPLAT_RWLOCK_TEST_NAME "rwlock_test"
#define SPLAT_RWLOCK_TEST_COUNT 8
#define KZT_RWLOCK_RELEASE_INIT 0
#define KZT_RWLOCK_RELEASE_WRITERS 1
#define KZT_RWLOCK_RELEASE_READERS 2
#define SPLAT_RWLOCK_RELEASE_INIT 0
#define SPLAT_RWLOCK_RELEASE_WRITERS 1
#define SPLAT_RWLOCK_RELEASE_READERS 2
typedef struct rw_priv {
unsigned long rw_magic;
@ -56,13 +56,13 @@ typedef struct rw_thr {
} rw_thr_t;
static inline void
kzt_rwlock_sleep(signed long delay)
splat_rwlock_sleep(signed long delay)
{
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(delay);
}
#define kzt_rwlock_lock_and_test(lock,test) \
#define splat_rwlock_lock_and_test(lock,test) \
({ \
int ret = 0; \
\
@ -72,38 +72,38 @@ kzt_rwlock_sleep(signed long delay)
ret; \
})
void kzt_init_rw_priv(rw_priv_t *rwv, struct file *file)
void splat_init_rw_priv(rw_priv_t *rwv, struct file *file)
{
rwv->rw_magic = KZT_RWLOCK_TEST_MAGIC;
rwv->rw_magic = SPLAT_RWLOCK_TEST_MAGIC;
rwv->rw_file = file;
spin_lock_init(&rwv->rw_priv_lock);
init_waitqueue_head(&rwv->rw_waitq);
atomic_set(&rwv->rw_completed, 0);
atomic_set(&rwv->rw_acquired, 0);
atomic_set(&rwv->rw_waiters, 0);
atomic_set(&rwv->rw_release, KZT_RWLOCK_RELEASE_INIT);
atomic_set(&rwv->rw_release, SPLAT_RWLOCK_RELEASE_INIT);
/* Initialize the read/write lock */
rw_init(&rwv->rwl, KZT_RWLOCK_TEST_NAME, RW_DEFAULT, NULL);
rw_init(&rwv->rwl, SPLAT_RWLOCK_TEST_NAME, RW_DEFAULT, NULL);
}
int
kzt_rwlock_test1_writer_thread(void *arg)
splat_rwlock_test1_writer_thread(void *arg)
{
rw_thr_t *rwt = (rw_thr_t *)arg;
rw_priv_t *rwv = rwt->rwt_rwp;
uint8_t rnd = 0;
char name[16];
ASSERT(rwv->rw_magic == KZT_RWLOCK_TEST_MAGIC);
snprintf(name, sizeof(name), "%s%d",
KZT_RWLOCK_TEST_NAME, rwt->rwt_id);
ASSERT(rwv->rw_magic == SPLAT_RWLOCK_TEST_MAGIC);
snprintf(name, sizeof(name), "%s%d",
SPLAT_RWLOCK_TEST_NAME, rwt->rwt_id);
daemonize(name);
get_random_bytes((void *)&rnd, 1);
kzt_rwlock_sleep(rnd * HZ / 1000);
splat_rwlock_sleep(rnd * HZ / 1000);
spin_lock(&rwv->rw_priv_lock);
kzt_vprint(rwv->rw_file, rwt->rwt_name,
splat_vprint(rwv->rw_file, rwt->rwt_name,
"%s writer thread trying to acquire rwlock with "
"%d holding lock and %d waiting\n",
name, atomic_read(&rwv->rw_acquired),
@ -111,14 +111,14 @@ kzt_rwlock_test1_writer_thread(void *arg)
atomic_inc(&rwv->rw_waiters);
spin_unlock(&rwv->rw_priv_lock);
/* Take the semaphore for writing
/* Take the semaphore for writing
* release it when we are told to */
rw_enter(&rwv->rwl, RW_WRITER);
spin_lock(&rwv->rw_priv_lock);
atomic_dec(&rwv->rw_waiters);
atomic_inc(&rwv->rw_acquired);
kzt_vprint(rwv->rw_file, rwt->rwt_name,
splat_vprint(rwv->rw_file, rwt->rwt_name,
"%s writer thread acquired rwlock with "
"%d holding lock and %d waiting\n",
name, atomic_read(&rwv->rw_acquired),
@ -128,13 +128,13 @@ kzt_rwlock_test1_writer_thread(void *arg)
/* Wait here until the control thread
* says we can release the write lock */
wait_event_interruptible(rwv->rw_waitq,
kzt_rwlock_lock_and_test(&rwv->rw_priv_lock,
splat_rwlock_lock_and_test(&rwv->rw_priv_lock,
atomic_read(&rwv->rw_release) ==
KZT_RWLOCK_RELEASE_WRITERS));
SPLAT_RWLOCK_RELEASE_WRITERS));
spin_lock(&rwv->rw_priv_lock);
atomic_inc(&rwv->rw_completed);
atomic_dec(&rwv->rw_acquired);
kzt_vprint(rwv->rw_file, rwt->rwt_name,
splat_vprint(rwv->rw_file, rwt->rwt_name,
"%s writer thread dropped rwlock with "
"%d holding lock and %d waiting\n",
name, atomic_read(&rwv->rw_acquired),
@ -147,28 +147,28 @@ kzt_rwlock_test1_writer_thread(void *arg)
}
int
kzt_rwlock_test1_reader_thread(void *arg)
splat_rwlock_test1_reader_thread(void *arg)
{
rw_thr_t *rwt = (rw_thr_t *)arg;
rw_priv_t *rwv = rwt->rwt_rwp;
uint8_t rnd = 0;
char name[16];
ASSERT(rwv->rw_magic == KZT_RWLOCK_TEST_MAGIC);
ASSERT(rwv->rw_magic == SPLAT_RWLOCK_TEST_MAGIC);
snprintf(name, sizeof(name), "%s%d",
KZT_RWLOCK_TEST_NAME, rwt->rwt_id);
SPLAT_RWLOCK_TEST_NAME, rwt->rwt_id);
daemonize(name);
get_random_bytes((void *)&rnd, 1);
kzt_rwlock_sleep(rnd * HZ / 1000);
splat_rwlock_sleep(rnd * HZ / 1000);
/* Don't try and and take the semaphore until
* someone else has already acquired it */
wait_event_interruptible(rwv->rw_waitq,
kzt_rwlock_lock_and_test(&rwv->rw_priv_lock,
splat_rwlock_lock_and_test(&rwv->rw_priv_lock,
atomic_read(&rwv->rw_acquired) > 0));
spin_lock(&rwv->rw_priv_lock);
kzt_vprint(rwv->rw_file, rwt->rwt_name,
splat_vprint(rwv->rw_file, rwt->rwt_name,
"%s reader thread trying to acquire rwlock with "
"%d holding lock and %d waiting\n",
name, atomic_read(&rwv->rw_acquired),
@ -183,7 +183,7 @@ kzt_rwlock_test1_reader_thread(void *arg)
spin_lock(&rwv->rw_priv_lock);
atomic_dec(&rwv->rw_waiters);
atomic_inc(&rwv->rw_acquired);
kzt_vprint(rwv->rw_file, rwt->rwt_name,
splat_vprint(rwv->rw_file, rwt->rwt_name,
"%s reader thread acquired rwlock with "
"%d holding lock and %d waiting\n",
name, atomic_read(&rwv->rw_acquired),
@ -193,14 +193,14 @@ kzt_rwlock_test1_reader_thread(void *arg)
/* Wait here until the control thread
* says we can release the read lock */
wait_event_interruptible(rwv->rw_waitq,
kzt_rwlock_lock_and_test(&rwv->rw_priv_lock,
splat_rwlock_lock_and_test(&rwv->rw_priv_lock,
atomic_read(&rwv->rw_release) ==
KZT_RWLOCK_RELEASE_READERS));
SPLAT_RWLOCK_RELEASE_READERS));
spin_lock(&rwv->rw_priv_lock);
atomic_inc(&rwv->rw_completed);
atomic_dec(&rwv->rw_acquired);
kzt_vprint(rwv->rw_file, rwt->rwt_name,
splat_vprint(rwv->rw_file, rwt->rwt_name,
"%s reader thread dropped rwlock with "
"%d holding lock and %d waiting\n",
name, atomic_read(&rwv->rw_acquired),
@ -213,75 +213,74 @@ kzt_rwlock_test1_reader_thread(void *arg)
}
static int
kzt_rwlock_test1(struct file *file, void *arg)
splat_rwlock_test1(struct file *file, void *arg)
{
int i, count = 0, rc = 0;
long pids[KZT_RWLOCK_TEST_COUNT];
rw_thr_t rwt[KZT_RWLOCK_TEST_COUNT];
long pids[SPLAT_RWLOCK_TEST_COUNT];
rw_thr_t rwt[SPLAT_RWLOCK_TEST_COUNT];
rw_priv_t rwv;
/* Initialize private data
* including the rwlock */
kzt_init_rw_priv(&rwv, file);
/* Initialize private data including the rwlock */
splat_init_rw_priv(&rwv, file);
/* Create some threads, the exact number isn't important just as
* long as we know how many we managed to create and should expect. */
for (i = 0; i < KZT_RWLOCK_TEST_COUNT; i++) {
for (i = 0; i < SPLAT_RWLOCK_TEST_COUNT; i++) {
rwt[i].rwt_rwp = &rwv;
rwt[i].rwt_id = i;
rwt[i].rwt_name = KZT_RWLOCK_TEST1_NAME;
rwt[i].rwt_name = SPLAT_RWLOCK_TEST1_NAME;
rwt[i].rwt_rc = 0;
/* The first thread will be a writer */
if (i == 0) {
pids[i] = kernel_thread(kzt_rwlock_test1_writer_thread,
pids[i] = kernel_thread(splat_rwlock_test1_writer_thread,
&rwt[i], 0);
} else {
pids[i] = kernel_thread(kzt_rwlock_test1_reader_thread,
pids[i] = kernel_thread(splat_rwlock_test1_reader_thread,
&rwt[i], 0);
}
if (pids[i] >= 0) {
count++;
}
}
/* Once the writer has the lock, release the readers */
while (kzt_rwlock_lock_and_test(&rwv.rw_priv_lock, atomic_read(&rwv.rw_acquired) <= 0)) {
kzt_rwlock_sleep(1 * HZ);
while (splat_rwlock_lock_and_test(&rwv.rw_priv_lock, atomic_read(&rwv.rw_acquired) <= 0)) {
splat_rwlock_sleep(1 * HZ);
}
wake_up_interruptible(&rwv.rw_waitq);
/* Ensure that there is only 1 writer and all readers are waiting */
while (kzt_rwlock_lock_and_test(&rwv.rw_priv_lock,
while (splat_rwlock_lock_and_test(&rwv.rw_priv_lock,
atomic_read(&rwv.rw_acquired) != 1 ||
atomic_read(&rwv.rw_waiters) !=
KZT_RWLOCK_TEST_COUNT - 1)) {
SPLAT_RWLOCK_TEST_COUNT - 1)) {
kzt_rwlock_sleep(1 * HZ);
splat_rwlock_sleep(1 * HZ);
}
/* Relase the writer */
spin_lock(&rwv.rw_priv_lock);
atomic_set(&rwv.rw_release, KZT_RWLOCK_RELEASE_WRITERS);
atomic_set(&rwv.rw_release, SPLAT_RWLOCK_RELEASE_WRITERS);
spin_unlock(&rwv.rw_priv_lock);
wake_up_interruptible(&rwv.rw_waitq);
/* Now ensure that there are multiple reader threads holding the lock */
while (kzt_rwlock_lock_and_test(&rwv.rw_priv_lock,
while (splat_rwlock_lock_and_test(&rwv.rw_priv_lock,
atomic_read(&rwv.rw_acquired) <= 1)) {
kzt_rwlock_sleep(1 * HZ);
splat_rwlock_sleep(1 * HZ);
}
/* Release the readers */
spin_lock(&rwv.rw_priv_lock);
atomic_set(&rwv.rw_release, KZT_RWLOCK_RELEASE_READERS);
atomic_set(&rwv.rw_release, SPLAT_RWLOCK_RELEASE_READERS);
spin_unlock(&rwv.rw_priv_lock);
wake_up_interruptible(&rwv.rw_waitq);
/* Wait for the test to complete */
while (kzt_rwlock_lock_and_test(&rwv.rw_priv_lock,
while (splat_rwlock_lock_and_test(&rwv.rw_priv_lock,
atomic_read(&rwv.rw_acquired) != 0 ||
atomic_read(&rwv.rw_waiters) != 0)) {
kzt_rwlock_sleep(1 * HZ);
splat_rwlock_sleep(1 * HZ);
}
@ -290,26 +289,26 @@ kzt_rwlock_test1(struct file *file, void *arg)
}
int
kzt_rwlock_test2_writer_thread(void *arg)
splat_rwlock_test2_writer_thread(void *arg)
{
rw_thr_t *rwt = (rw_thr_t *)arg;
rw_priv_t *rwv = rwt->rwt_rwp;
uint8_t rnd = 0;
char name[16];
ASSERT(rwv->rw_magic == KZT_RWLOCK_TEST_MAGIC);
ASSERT(rwv->rw_magic == SPLAT_RWLOCK_TEST_MAGIC);
snprintf(name, sizeof(name), "%s%d",
KZT_RWLOCK_TEST_NAME, rwt->rwt_id);
SPLAT_RWLOCK_TEST_NAME, rwt->rwt_id);
daemonize(name);
get_random_bytes((void *)&rnd, 1);
kzt_rwlock_sleep(rnd * HZ / 1000);
splat_rwlock_sleep(rnd * HZ / 1000);
/* Here just increment the waiters count even if we are not
* exactly about to call rw_enter(). Not really a big deal
* since more than likely will be true when we simulate work
* later on */
spin_lock(&rwv->rw_priv_lock);
kzt_vprint(rwv->rw_file, rwt->rwt_name,
splat_vprint(rwv->rw_file, rwt->rwt_name,
"%s writer thread trying to acquire rwlock with "
"%d holding lock and %d waiting\n",
name, atomic_read(&rwv->rw_acquired),
@ -320,17 +319,17 @@ kzt_rwlock_test2_writer_thread(void *arg)
/* Wait here until the control thread
* says we can acquire the write lock */
wait_event_interruptible(rwv->rw_waitq,
kzt_rwlock_lock_and_test(&rwv->rw_priv_lock,
splat_rwlock_lock_and_test(&rwv->rw_priv_lock,
atomic_read(&rwv->rw_release) ==
KZT_RWLOCK_RELEASE_WRITERS));
SPLAT_RWLOCK_RELEASE_WRITERS));
/* Take the semaphore for writing */
rw_enter(&rwv->rwl, RW_WRITER);
spin_lock(&rwv->rw_priv_lock);
atomic_dec(&rwv->rw_waiters);
atomic_inc(&rwv->rw_acquired);
kzt_vprint(rwv->rw_file, rwt->rwt_name,
splat_vprint(rwv->rw_file, rwt->rwt_name,
"%s writer thread acquired rwlock with "
"%d holding lock and %d waiting\n",
name, atomic_read(&rwv->rw_acquired),
@ -339,7 +338,7 @@ kzt_rwlock_test2_writer_thread(void *arg)
/* Give up the processor for a bit to simulate
* doing some work while taking the write lock */
kzt_rwlock_sleep(rnd * HZ / 1000);
splat_rwlock_sleep(rnd * HZ / 1000);
/* Ensure that we are the only one writing */
if (atomic_read(&rwv->rw_acquired) > 1) {
@ -351,7 +350,7 @@ kzt_rwlock_test2_writer_thread(void *arg)
spin_lock(&rwv->rw_priv_lock);
atomic_inc(&rwv->rw_completed);
atomic_dec(&rwv->rw_acquired);
kzt_vprint(rwv->rw_file, rwt->rwt_name,
splat_vprint(rwv->rw_file, rwt->rwt_name,
"%s writer thread dropped rwlock with "
"%d holding lock and %d waiting\n",
name, atomic_read(&rwv->rw_acquired),
@ -359,33 +358,31 @@ kzt_rwlock_test2_writer_thread(void *arg)
spin_unlock(&rwv->rw_priv_lock);
rw_exit(&rwv->rwl);
return 0;
}
static int
kzt_rwlock_test2(struct file *file, void *arg)
splat_rwlock_test2(struct file *file, void *arg)
{
int i, count = 0, rc = 0;
long pids[KZT_RWLOCK_TEST_COUNT];
rw_thr_t rwt[KZT_RWLOCK_TEST_COUNT];
long pids[SPLAT_RWLOCK_TEST_COUNT];
rw_thr_t rwt[SPLAT_RWLOCK_TEST_COUNT];
rw_priv_t rwv;
/* Initialize private data
* including the rwlock */
kzt_init_rw_priv(&rwv, file);
/* Initialize private data including the rwlock */
splat_init_rw_priv(&rwv, file);
/* Create some threads, the exact number isn't important just as
* long as we know how many we managed to create and should expect. */
for (i = 0; i < KZT_RWLOCK_TEST_COUNT; i++) {
for (i = 0; i < SPLAT_RWLOCK_TEST_COUNT; i++) {
rwt[i].rwt_rwp = &rwv;
rwt[i].rwt_id = i;
rwt[i].rwt_name = KZT_RWLOCK_TEST2_NAME;
rwt[i].rwt_name = SPLAT_RWLOCK_TEST2_NAME;
rwt[i].rwt_rc = 0;
/* The first thread will be a writer */
pids[i] = kernel_thread(kzt_rwlock_test2_writer_thread,
pids[i] = kernel_thread(splat_rwlock_test2_writer_thread,
&rwt[i], 0);
if (pids[i] >= 0) {
@ -394,27 +391,27 @@ kzt_rwlock_test2(struct file *file, void *arg)
}
/* Wait for writers to get queued up */
while (kzt_rwlock_lock_and_test(&rwv.rw_priv_lock,
atomic_read(&rwv.rw_waiters) < KZT_RWLOCK_TEST_COUNT)) {
kzt_rwlock_sleep(1 * HZ);
while (splat_rwlock_lock_and_test(&rwv.rw_priv_lock,
atomic_read(&rwv.rw_waiters) < SPLAT_RWLOCK_TEST_COUNT)) {
splat_rwlock_sleep(1 * HZ);
}
/* Relase the writers */
spin_lock(&rwv.rw_priv_lock);
atomic_set(&rwv.rw_release, KZT_RWLOCK_RELEASE_WRITERS);
atomic_set(&rwv.rw_release, SPLAT_RWLOCK_RELEASE_WRITERS);
spin_unlock(&rwv.rw_priv_lock);
wake_up_interruptible(&rwv.rw_waitq);
/* Wait for the test to complete */
while (kzt_rwlock_lock_and_test(&rwv.rw_priv_lock,
while (splat_rwlock_lock_and_test(&rwv.rw_priv_lock,
atomic_read(&rwv.rw_acquired) != 0 ||
atomic_read(&rwv.rw_waiters) != 0)) {
kzt_rwlock_sleep(1 * HZ);
splat_rwlock_sleep(1 * HZ);
}
/* If any of the write threads ever acquired the lock
* while another thread had it, make sure we return
* an error */
for (i = 0; i < KZT_RWLOCK_TEST_COUNT; i++) {
for (i = 0; i < SPLAT_RWLOCK_TEST_COUNT; i++) {
if (rwt[i].rwt_rc) {
rc++;
}
@ -425,7 +422,7 @@ kzt_rwlock_test2(struct file *file, void *arg)
}
static int
kzt_rwlock_test3(struct file *file, void *arg)
splat_rwlock_test3(struct file *file, void *arg)
{
kthread_t *owner;
rw_priv_t rwv;
@ -433,13 +430,13 @@ kzt_rwlock_test3(struct file *file, void *arg)
/* Initialize private data
* including the rwlock */
kzt_init_rw_priv(&rwv, file);
splat_init_rw_priv(&rwv, file);
/* Take the rwlock for writing */
rw_enter(&rwv.rwl, RW_WRITER);
owner = rw_owner(&rwv.rwl);
if (current != owner) {
kzt_vprint(file, KZT_RWLOCK_TEST3_NAME, "rwlock should "
splat_vprint(file, SPLAT_RWLOCK_TEST3_NAME, "rwlock should "
"be owned by pid %d but is owned by pid %d\n",
current->pid, owner ? owner->pid : -1);
rc = -EINVAL;
@ -450,7 +447,7 @@ kzt_rwlock_test3(struct file *file, void *arg)
rw_exit(&rwv.rwl);
owner = rw_owner(&rwv.rwl);
if (owner) {
kzt_vprint(file, KZT_RWLOCK_TEST3_NAME, "rwlock should not "
splat_vprint(file, SPLAT_RWLOCK_TEST3_NAME, "rwlock should not "
"be owned but is owned by pid %d\n", owner->pid);
rc = -EINVAL;
goto out;
@ -461,7 +458,7 @@ kzt_rwlock_test3(struct file *file, void *arg)
rw_enter(&rwv.rwl, RW_READER);
owner = rw_owner(&rwv.rwl);
if (owner) {
kzt_vprint(file, KZT_RWLOCK_TEST3_NAME, "rwlock should not "
splat_vprint(file, SPLAT_RWLOCK_TEST3_NAME, "rwlock should not "
"be owned but is owned by pid %d\n", owner->pid);
/* Release the rwlock */
rw_exit(&rwv.rwl);
@ -478,28 +475,28 @@ out:
}
int
kzt_rwlock_test4_reader_thread(void *arg)
splat_rwlock_test4_reader_thread(void *arg)
{
rw_thr_t *rwt = (rw_thr_t *)arg;
rw_priv_t *rwv = rwt->rwt_rwp;
uint8_t rnd = 0;
char name[16];
ASSERT(rwv->rw_magic == KZT_RWLOCK_TEST_MAGIC);
ASSERT(rwv->rw_magic == SPLAT_RWLOCK_TEST_MAGIC);
snprintf(name, sizeof(name), "%s%d",
KZT_RWLOCK_TEST_NAME, rwt->rwt_id);
SPLAT_RWLOCK_TEST_NAME, rwt->rwt_id);
daemonize(name);
get_random_bytes((void *)&rnd, 1);
kzt_rwlock_sleep(rnd * HZ / 1000);
splat_rwlock_sleep(rnd * HZ / 1000);
/* Don't try and and take the semaphore until
* someone else has already acquired it */
wait_event_interruptible(rwv->rw_waitq,
kzt_rwlock_lock_and_test(&rwv->rw_priv_lock,
splat_rwlock_lock_and_test(&rwv->rw_priv_lock,
atomic_read(&rwv->rw_acquired) > 0));
spin_lock(&rwv->rw_priv_lock);
kzt_vprint(rwv->rw_file, rwt->rwt_name,
splat_vprint(rwv->rw_file, rwt->rwt_name,
"%s reader thread trying to acquire rwlock with "
"%d holding lock and %d waiting\n",
name, atomic_read(&rwv->rw_acquired),
@ -516,22 +513,22 @@ kzt_rwlock_test4_reader_thread(void *arg)
if (rwt->rwt_rc == 1) {
spin_lock(&rwv->rw_priv_lock);
atomic_inc(&rwv->rw_acquired);
kzt_vprint(rwv->rw_file, rwt->rwt_name,
splat_vprint(rwv->rw_file, rwt->rwt_name,
"%s reader thread acquired rwlock with "
"%d holding lock and %d waiting\n",
name, atomic_read(&rwv->rw_acquired),
atomic_read(&rwv->rw_waiters));
spin_unlock(&rwv->rw_priv_lock);
spin_lock(&rwv->rw_priv_lock);
atomic_dec(&rwv->rw_acquired);
kzt_vprint(rwv->rw_file, rwt->rwt_name,
splat_vprint(rwv->rw_file, rwt->rwt_name,
"%s reader thread dropped rwlock with "
"%d holding lock and %d waiting\n",
name, atomic_read(&rwv->rw_acquired),
atomic_read(&rwv->rw_waiters));
spin_unlock(&rwv->rw_priv_lock);
/* Release the semaphore */
rw_exit(&rwv->rwl);
}
@ -540,7 +537,7 @@ kzt_rwlock_test4_reader_thread(void *arg)
else {
spin_lock(&rwv->rw_priv_lock);
atomic_inc(&rwv->rw_completed);
kzt_vprint(rwv->rw_file, rwt->rwt_name,
splat_vprint(rwv->rw_file, rwt->rwt_name,
"%s reader thread could not acquire rwlock with "
"%d holding lock and %d waiting\n",
name, atomic_read(&rwv->rw_acquired),
@ -552,32 +549,32 @@ kzt_rwlock_test4_reader_thread(void *arg)
}
static int
kzt_rwlock_test4(struct file *file, void *arg)
splat_rwlock_test4(struct file *file, void *arg)
{
int i, count = 0, rc = 0;
long pids[KZT_RWLOCK_TEST_COUNT];
rw_thr_t rwt[KZT_RWLOCK_TEST_COUNT];
long pids[SPLAT_RWLOCK_TEST_COUNT];
rw_thr_t rwt[SPLAT_RWLOCK_TEST_COUNT];
rw_priv_t rwv;
/* Initialize private data
* including the rwlock */
kzt_init_rw_priv(&rwv, file);
splat_init_rw_priv(&rwv, file);
/* Create some threads, the exact number isn't important just as
* long as we know how many we managed to create and should expect. */
for (i = 0; i < KZT_RWLOCK_TEST_COUNT; i++) {
for (i = 0; i < SPLAT_RWLOCK_TEST_COUNT; i++) {
rwt[i].rwt_rwp = &rwv;
rwt[i].rwt_id = i;
rwt[i].rwt_name = KZT_RWLOCK_TEST4_NAME;
rwt[i].rwt_name = SPLAT_RWLOCK_TEST4_NAME;
rwt[i].rwt_rc = 0;
/* The first thread will be a writer */
if (i == 0) {
/* We can reuse the test1 writer thread here */
pids[i] = kernel_thread(kzt_rwlock_test1_writer_thread,
pids[i] = kernel_thread(splat_rwlock_test1_writer_thread,
&rwt[i], 0);
} else {
pids[i] = kernel_thread(kzt_rwlock_test4_reader_thread,
pids[i] = kernel_thread(splat_rwlock_test4_reader_thread,
&rwt[i], 0);
}
@ -587,34 +584,34 @@ kzt_rwlock_test4(struct file *file, void *arg)
}
/* Once the writer has the lock, release the readers */
while (kzt_rwlock_lock_and_test(&rwv.rw_priv_lock,
while (splat_rwlock_lock_and_test(&rwv.rw_priv_lock,
atomic_read(&rwv.rw_acquired) <= 0)) {
kzt_rwlock_sleep(1 * HZ);
splat_rwlock_sleep(1 * HZ);
}
wake_up_interruptible(&rwv.rw_waitq);
/* Make sure that the reader threads complete */
while (kzt_rwlock_lock_and_test(&rwv.rw_priv_lock,
atomic_read(&rwv.rw_completed) != KZT_RWLOCK_TEST_COUNT - 1)) {
kzt_rwlock_sleep(1 * HZ);
while (splat_rwlock_lock_and_test(&rwv.rw_priv_lock,
atomic_read(&rwv.rw_completed) != SPLAT_RWLOCK_TEST_COUNT - 1)) {
splat_rwlock_sleep(1 * HZ);
}
/* Release the writer */
spin_lock(&rwv.rw_priv_lock);
atomic_set(&rwv.rw_release, KZT_RWLOCK_RELEASE_WRITERS);
atomic_set(&rwv.rw_release, SPLAT_RWLOCK_RELEASE_WRITERS);
spin_unlock(&rwv.rw_priv_lock);
wake_up_interruptible(&rwv.rw_waitq);
/* Wait for the test to complete */
while (kzt_rwlock_lock_and_test(&rwv.rw_priv_lock,
while (splat_rwlock_lock_and_test(&rwv.rw_priv_lock,
atomic_read(&rwv.rw_acquired) != 0 ||
atomic_read(&rwv.rw_waiters) != 0)) {
kzt_rwlock_sleep(1 * HZ);
splat_rwlock_sleep(1 * HZ);
}
/* If any of the reader threads ever acquired the lock
* while another thread had it, make sure we return
* an error since the rw_tryenter() should have failed */
for (i = 0; i < KZT_RWLOCK_TEST_COUNT; i++) {
for (i = 0; i < SPLAT_RWLOCK_TEST_COUNT; i++) {
if (rwt[i].rwt_rc) {
rc++;
}
@ -625,7 +622,7 @@ kzt_rwlock_test4(struct file *file, void *arg)
}
static int
kzt_rwlock_test5(struct file *file, void *arg)
splat_rwlock_test5(struct file *file, void *arg)
{
kthread_t *owner;
rw_priv_t rwv;
@ -633,13 +630,13 @@ kzt_rwlock_test5(struct file *file, void *arg)
/* Initialize private data
* including the rwlock */
kzt_init_rw_priv(&rwv, file);
splat_init_rw_priv(&rwv, file);
/* Take the rwlock for writing */
rw_enter(&rwv.rwl, RW_WRITER);
owner = rw_owner(&rwv.rwl);
if (current != owner) {
kzt_vprint(file, KZT_RWLOCK_TEST5_NAME, "rwlock should "
splat_vprint(file, SPLAT_RWLOCK_TEST5_NAME, "rwlock should "
"be owned by pid %d but is owned by pid %d\n",
current->pid, owner ? owner->pid : -1);
rc = -EINVAL;
@ -652,7 +649,7 @@ kzt_rwlock_test5(struct file *file, void *arg)
owner = rw_owner(&rwv.rwl);
if (owner) {
kzt_vprint(file, KZT_RWLOCK_TEST5_NAME, "rwlock should not "
splat_vprint(file, SPLAT_RWLOCK_TEST5_NAME, "rwlock should not "
"be owned but is owned by pid %d\n", owner->pid);
/* Release the rwlock */
rw_exit(&rwv.rwl);
@ -669,7 +666,7 @@ out:
}
static int
kzt_rwlock_test6(struct file *file, void *arg)
splat_rwlock_test6(struct file *file, void *arg)
{
kthread_t *owner;
rw_priv_t rwv;
@ -677,13 +674,13 @@ kzt_rwlock_test6(struct file *file, void *arg)
/* Initialize private data
* including the rwlock */
kzt_init_rw_priv(&rwv, file);
splat_init_rw_priv(&rwv, file);
/* Take the rwlock for reading */
rw_enter(&rwv.rwl, RW_READER);
owner = rw_owner(&rwv.rwl);
if (owner) {
kzt_vprint(file, KZT_RWLOCK_TEST6_NAME, "rwlock should not "
splat_vprint(file, SPLAT_RWLOCK_TEST6_NAME, "rwlock should not "
"be owned but is owned by pid %d\n", owner->pid);
rc = -EINVAL;
goto out;
@ -695,7 +692,7 @@ kzt_rwlock_test6(struct file *file, void *arg)
owner = rw_owner(&rwv.rwl);
if (rc || current != owner) {
kzt_vprint(file, KZT_RWLOCK_TEST6_NAME, "rwlock should "
splat_vprint(file, SPLAT_RWLOCK_TEST6_NAME, "rwlock should "
"be owned by pid %d but is owned by pid %d "
"trylock rc %d\n",
current->pid, owner ? owner->pid : -1, rc);
@ -711,53 +708,53 @@ out:
return rc;
}
kzt_subsystem_t *
kzt_rwlock_init(void)
splat_subsystem_t *
splat_rwlock_init(void)
{
kzt_subsystem_t *sub;
splat_subsystem_t *sub;
sub = kmalloc(sizeof(*sub), GFP_KERNEL);
if (sub == NULL)
return NULL;
memset(sub, 0, sizeof(*sub));
strncpy(sub->desc.name, KZT_RWLOCK_NAME, KZT_NAME_SIZE);
strncpy(sub->desc.desc, KZT_RWLOCK_DESC, KZT_DESC_SIZE);
strncpy(sub->desc.name, SPLAT_RWLOCK_NAME, SPLAT_NAME_SIZE);
strncpy(sub->desc.desc, SPLAT_RWLOCK_DESC, SPLAT_DESC_SIZE);
INIT_LIST_HEAD(&sub->subsystem_list);
INIT_LIST_HEAD(&sub->test_list);
spin_lock_init(&sub->test_lock);
sub->desc.id = KZT_SUBSYSTEM_RWLOCK;
sub->desc.id = SPLAT_SUBSYSTEM_RWLOCK;
KZT_TEST_INIT(sub, KZT_RWLOCK_TEST1_NAME, KZT_RWLOCK_TEST1_DESC,
KZT_RWLOCK_TEST1_ID, kzt_rwlock_test1);
KZT_TEST_INIT(sub, KZT_RWLOCK_TEST2_NAME, KZT_RWLOCK_TEST2_DESC,
KZT_RWLOCK_TEST2_ID, kzt_rwlock_test2);
KZT_TEST_INIT(sub, KZT_RWLOCK_TEST3_NAME, KZT_RWLOCK_TEST3_DESC,
KZT_RWLOCK_TEST3_ID, kzt_rwlock_test3);
KZT_TEST_INIT(sub, KZT_RWLOCK_TEST4_NAME, KZT_RWLOCK_TEST4_DESC,
KZT_RWLOCK_TEST4_ID, kzt_rwlock_test4);
KZT_TEST_INIT(sub, KZT_RWLOCK_TEST5_NAME, KZT_RWLOCK_TEST5_DESC,
KZT_RWLOCK_TEST5_ID, kzt_rwlock_test5);
KZT_TEST_INIT(sub, KZT_RWLOCK_TEST6_NAME, KZT_RWLOCK_TEST6_DESC,
KZT_RWLOCK_TEST6_ID, kzt_rwlock_test6);
SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST1_NAME, SPLAT_RWLOCK_TEST1_DESC,
SPLAT_RWLOCK_TEST1_ID, splat_rwlock_test1);
SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST2_NAME, SPLAT_RWLOCK_TEST2_DESC,
SPLAT_RWLOCK_TEST2_ID, splat_rwlock_test2);
SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST3_NAME, SPLAT_RWLOCK_TEST3_DESC,
SPLAT_RWLOCK_TEST3_ID, splat_rwlock_test3);
SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST4_NAME, SPLAT_RWLOCK_TEST4_DESC,
SPLAT_RWLOCK_TEST4_ID, splat_rwlock_test4);
SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST5_NAME, SPLAT_RWLOCK_TEST5_DESC,
SPLAT_RWLOCK_TEST5_ID, splat_rwlock_test5);
SPLAT_TEST_INIT(sub, SPLAT_RWLOCK_TEST6_NAME, SPLAT_RWLOCK_TEST6_DESC,
SPLAT_RWLOCK_TEST6_ID, splat_rwlock_test6);
return sub;
}
void
kzt_rwlock_fini(kzt_subsystem_t *sub)
splat_rwlock_fini(splat_subsystem_t *sub)
{
ASSERT(sub);
KZT_TEST_FINI(sub, KZT_RWLOCK_TEST6_ID);
KZT_TEST_FINI(sub, KZT_RWLOCK_TEST5_ID);
KZT_TEST_FINI(sub, KZT_RWLOCK_TEST4_ID);
KZT_TEST_FINI(sub, KZT_RWLOCK_TEST3_ID);
KZT_TEST_FINI(sub, KZT_RWLOCK_TEST2_ID);
KZT_TEST_FINI(sub, KZT_RWLOCK_TEST1_ID);
SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST6_ID);
SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST5_ID);
SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST4_ID);
SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST3_ID);
SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST2_ID);
SPLAT_TEST_FINI(sub, SPLAT_RWLOCK_TEST1_ID);
kfree(sub);
}
int
kzt_rwlock_id(void) {
return KZT_SUBSYSTEM_RWLOCK;
splat_rwlock_id(void) {
return SPLAT_SUBSYSTEM_RWLOCK;
}

View File

@ -1,75 +1,75 @@
#include <splat-ctl.h>
#include "splat-internal.h"
#define KZT_SUBSYSTEM_TASKQ 0x0200
#define KZT_TASKQ_NAME "taskq"
#define KZT_TASKQ_DESC "Kernel Task Queue Tests"
#define SPLAT_SUBSYSTEM_TASKQ 0x0200
#define SPLAT_TASKQ_NAME "taskq"
#define SPLAT_TASKQ_DESC "Kernel Task Queue Tests"
#define KZT_TASKQ_TEST1_ID 0x0201
#define KZT_TASKQ_TEST1_NAME "single"
#define KZT_TASKQ_TEST1_DESC "Single task queue, single task"
#define SPLAT_TASKQ_TEST1_ID 0x0201
#define SPLAT_TASKQ_TEST1_NAME "single"
#define SPLAT_TASKQ_TEST1_DESC "Single task queue, single task"
#define KZT_TASKQ_TEST2_ID 0x0202
#define KZT_TASKQ_TEST2_NAME "multiple"
#define KZT_TASKQ_TEST2_DESC "Multiple task queues, multiple tasks"
#define SPLAT_TASKQ_TEST2_ID 0x0202
#define SPLAT_TASKQ_TEST2_NAME "multiple"
#define SPLAT_TASKQ_TEST2_DESC "Multiple task queues, multiple tasks"
typedef struct kzt_taskq_arg {
typedef struct splat_taskq_arg {
int flag;
int id;
struct file *file;
const char *name;
} kzt_taskq_arg_t;
} splat_taskq_arg_t;
/* Validation Test 1 - Create a taskq, queue a task, wait until
* task completes, ensure task ran properly, cleanup taskq,
*/
static void
kzt_taskq_test1_func(void *arg)
splat_taskq_test1_func(void *arg)
{
kzt_taskq_arg_t *tq_arg = (kzt_taskq_arg_t *)arg;
splat_taskq_arg_t *tq_arg = (splat_taskq_arg_t *)arg;
ASSERT(tq_arg);
kzt_vprint(tq_arg->file, KZT_TASKQ_TEST1_NAME,
splat_vprint(tq_arg->file, SPLAT_TASKQ_TEST1_NAME,
"Taskq '%s' function '%s' setting flag\n",
tq_arg->name, sym2str(kzt_taskq_test1_func));
tq_arg->name, sym2str(splat_taskq_test1_func));
tq_arg->flag = 1;
}
static int
kzt_taskq_test1(struct file *file, void *arg)
splat_taskq_test1(struct file *file, void *arg)
{
taskq_t *tq;
taskqid_t id;
kzt_taskq_arg_t tq_arg;
splat_taskq_arg_t tq_arg;
kzt_vprint(file, KZT_TASKQ_TEST1_NAME, "Taskq '%s' creating\n",
KZT_TASKQ_TEST1_NAME);
if ((tq = taskq_create(KZT_TASKQ_TEST1_NAME, 1, 0, 0, 0, 0)) == NULL) {
kzt_vprint(file, KZT_TASKQ_TEST1_NAME,
splat_vprint(file, SPLAT_TASKQ_TEST1_NAME, "Taskq '%s' creating\n",
SPLAT_TASKQ_TEST1_NAME);
if ((tq = taskq_create(SPLAT_TASKQ_TEST1_NAME, 1, 0, 0, 0, 0)) == NULL) {
splat_vprint(file, SPLAT_TASKQ_TEST1_NAME,
"Taskq '%s' create failed\n",
KZT_TASKQ_TEST1_NAME);
SPLAT_TASKQ_TEST1_NAME);
return -EINVAL;
}
tq_arg.flag = 0;
tq_arg.id = 0;
tq_arg.file = file;
tq_arg.name = KZT_TASKQ_TEST1_NAME;
tq_arg.name = SPLAT_TASKQ_TEST1_NAME;
kzt_vprint(file, KZT_TASKQ_TEST1_NAME,
splat_vprint(file, SPLAT_TASKQ_TEST1_NAME,
"Taskq '%s' function '%s' dispatching\n",
tq_arg.name, sym2str(kzt_taskq_test1_func));
if ((id = taskq_dispatch(tq, kzt_taskq_test1_func, &tq_arg, 0)) == 0) {
kzt_vprint(file, KZT_TASKQ_TEST1_NAME,
tq_arg.name, sym2str(splat_taskq_test1_func));
if ((id = taskq_dispatch(tq, splat_taskq_test1_func, &tq_arg, 0)) == 0) {
splat_vprint(file, SPLAT_TASKQ_TEST1_NAME,
"Taskq '%s' function '%s' dispatch failed\n",
tq_arg.name, sym2str(kzt_taskq_test1_func));
tq_arg.name, sym2str(splat_taskq_test1_func));
taskq_destory(tq);
return -EINVAL;
}
kzt_vprint(file, KZT_TASKQ_TEST1_NAME, "Taskq '%s' waiting\n",
splat_vprint(file, SPLAT_TASKQ_TEST1_NAME, "Taskq '%s' waiting\n",
tq_arg.name);
taskq_wait(tq);
kzt_vprint(file, KZT_TASKQ_TEST1_NAME, "Taskq '%s' destroying\n",
splat_vprint(file, SPLAT_TASKQ_TEST1_NAME, "Taskq '%s' destroying\n",
tq_arg.name);
taskq_destory(tq);
@ -81,50 +81,50 @@ kzt_taskq_test1(struct file *file, void *arg)
* the correct order, cleanup taskq's
*/
static void
kzt_taskq_test2_func1(void *arg)
splat_taskq_test2_func1(void *arg)
{
kzt_taskq_arg_t *tq_arg = (kzt_taskq_arg_t *)arg;
splat_taskq_arg_t *tq_arg = (splat_taskq_arg_t *)arg;
ASSERT(tq_arg);
kzt_vprint(tq_arg->file, KZT_TASKQ_TEST2_NAME,
splat_vprint(tq_arg->file, SPLAT_TASKQ_TEST2_NAME,
"Taskq '%s/%d' function '%s' flag = %d = %d * 2\n",
tq_arg->name, tq_arg->id,
sym2str(kzt_taskq_test2_func1),
sym2str(splat_taskq_test2_func1),
tq_arg->flag * 2, tq_arg->flag);
tq_arg->flag *= 2;
}
static void
kzt_taskq_test2_func2(void *arg)
splat_taskq_test2_func2(void *arg)
{
kzt_taskq_arg_t *tq_arg = (kzt_taskq_arg_t *)arg;
splat_taskq_arg_t *tq_arg = (splat_taskq_arg_t *)arg;
ASSERT(tq_arg);
kzt_vprint(tq_arg->file, KZT_TASKQ_TEST2_NAME,
splat_vprint(tq_arg->file, SPLAT_TASKQ_TEST2_NAME,
"Taskq '%s/%d' function '%s' flag = %d = %d + 1\n",
tq_arg->name, tq_arg->id,
sym2str(kzt_taskq_test2_func2),
sym2str(splat_taskq_test2_func2),
tq_arg->flag + 1, tq_arg->flag);
tq_arg->flag += 1;
}
#define TEST2_TASKQS 8
static int
kzt_taskq_test2(struct file *file, void *arg) {
splat_taskq_test2(struct file *file, void *arg) {
taskq_t *tq[TEST2_TASKQS] = { NULL };
taskqid_t id;
kzt_taskq_arg_t tq_args[TEST2_TASKQS];
splat_taskq_arg_t tq_args[TEST2_TASKQS];
int i, rc = 0;
for (i = 0; i < TEST2_TASKQS; i++) {
kzt_vprint(file, KZT_TASKQ_TEST2_NAME, "Taskq '%s/%d' "
"creating\n", KZT_TASKQ_TEST2_NAME, i);
if ((tq[i] = taskq_create(KZT_TASKQ_TEST2_NAME,
splat_vprint(file, SPLAT_TASKQ_TEST2_NAME, "Taskq '%s/%d' "
"creating\n", SPLAT_TASKQ_TEST2_NAME, i);
if ((tq[i] = taskq_create(SPLAT_TASKQ_TEST2_NAME,
1, 0, 0, 0, 0)) == NULL) {
kzt_vprint(file, KZT_TASKQ_TEST2_NAME,
splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
"Taskq '%s/%d' create failed\n",
KZT_TASKQ_TEST2_NAME, i);
SPLAT_TASKQ_TEST2_NAME, i);
rc = -EINVAL;
break;
}
@ -132,32 +132,32 @@ kzt_taskq_test2(struct file *file, void *arg) {
tq_args[i].flag = i;
tq_args[i].id = i;
tq_args[i].file = file;
tq_args[i].name = KZT_TASKQ_TEST2_NAME;
tq_args[i].name = SPLAT_TASKQ_TEST2_NAME;
kzt_vprint(file, KZT_TASKQ_TEST2_NAME,
splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
"Taskq '%s/%d' function '%s' dispatching\n",
tq_args[i].name, tq_args[i].id,
sym2str(kzt_taskq_test2_func1));
tq_args[i].name, tq_args[i].id,
sym2str(splat_taskq_test2_func1));
if ((id = taskq_dispatch(
tq[i], kzt_taskq_test2_func1, &tq_args[i], 0)) == 0) {
kzt_vprint(file, KZT_TASKQ_TEST2_NAME,
tq[i], splat_taskq_test2_func1, &tq_args[i], 0)) == 0) {
splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
"Taskq '%s/%d' function '%s' dispatch "
"failed\n", tq_args[i].name, tq_args[i].id,
sym2str(kzt_taskq_test2_func1));
sym2str(splat_taskq_test2_func1));
rc = -EINVAL;
break;
}
kzt_vprint(file, KZT_TASKQ_TEST2_NAME,
splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
"Taskq '%s/%d' function '%s' dispatching\n",
tq_args[i].name, tq_args[i].id,
sym2str(kzt_taskq_test2_func2));
tq_args[i].name, tq_args[i].id,
sym2str(splat_taskq_test2_func2));
if ((id = taskq_dispatch(
tq[i], kzt_taskq_test2_func2, &tq_args[i], 0)) == 0) {
kzt_vprint(file, KZT_TASKQ_TEST2_NAME,
tq[i], splat_taskq_test2_func2, &tq_args[i], 0)) == 0) {
splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
"Taskq '%s/%d' function '%s' dispatch failed\n",
tq_args[i].name, tq_args[i].id,
sym2str(kzt_taskq_test2_func2));
sym2str(splat_taskq_test2_func2));
rc = -EINVAL;
break;
}
@ -167,24 +167,24 @@ kzt_taskq_test2(struct file *file, void *arg) {
* ignore new errors in that case. They just cause noise. */
for (i = 0; i < TEST2_TASKQS; i++) {
if (tq[i] != NULL) {
kzt_vprint(file, KZT_TASKQ_TEST2_NAME,
splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
"Taskq '%s/%d' waiting\n",
tq_args[i].name, tq_args[i].id);
taskq_wait(tq[i]);
kzt_vprint(file, KZT_TASKQ_TEST2_NAME,
splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
"Taskq '%s/%d; destroying\n",
tq_args[i].name, tq_args[i].id);
taskq_destory(tq[i]);
if (!rc && tq_args[i].flag != ((i * 2) + 1)) {
kzt_vprint(file, KZT_TASKQ_TEST2_NAME,
splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
"Taskq '%s/%d' processed tasks "
"out of order; %d != %d\n",
tq_args[i].name, tq_args[i].id,
tq_args[i].flag, i * 2 + 1);
rc = -EINVAL;
} else {
kzt_vprint(file, KZT_TASKQ_TEST2_NAME,
splat_vprint(file, SPLAT_TASKQ_TEST2_NAME,
"Taskq '%s/%d' processed tasks "
"in the correct order; %d == %d\n",
tq_args[i].name, tq_args[i].id,
@ -196,42 +196,42 @@ kzt_taskq_test2(struct file *file, void *arg) {
return rc;
}
kzt_subsystem_t *
kzt_taskq_init(void)
splat_subsystem_t *
splat_taskq_init(void)
{
kzt_subsystem_t *sub;
splat_subsystem_t *sub;
sub = kmalloc(sizeof(*sub), GFP_KERNEL);
if (sub == NULL)
return NULL;
memset(sub, 0, sizeof(*sub));
strncpy(sub->desc.name, KZT_TASKQ_NAME, KZT_NAME_SIZE);
strncpy(sub->desc.desc, KZT_TASKQ_DESC, KZT_DESC_SIZE);
strncpy(sub->desc.name, SPLAT_TASKQ_NAME, SPLAT_NAME_SIZE);
strncpy(sub->desc.desc, SPLAT_TASKQ_DESC, SPLAT_DESC_SIZE);
INIT_LIST_HEAD(&sub->subsystem_list);
INIT_LIST_HEAD(&sub->test_list);
spin_lock_init(&sub->test_lock);
sub->desc.id = KZT_SUBSYSTEM_TASKQ;
sub->desc.id = SPLAT_SUBSYSTEM_TASKQ;
KZT_TEST_INIT(sub, KZT_TASKQ_TEST1_NAME, KZT_TASKQ_TEST1_DESC,
KZT_TASKQ_TEST1_ID, kzt_taskq_test1);
KZT_TEST_INIT(sub, KZT_TASKQ_TEST2_NAME, KZT_TASKQ_TEST2_DESC,
KZT_TASKQ_TEST2_ID, kzt_taskq_test2);
SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST1_NAME, SPLAT_TASKQ_TEST1_DESC,
SPLAT_TASKQ_TEST1_ID, splat_taskq_test1);
SPLAT_TEST_INIT(sub, SPLAT_TASKQ_TEST2_NAME, SPLAT_TASKQ_TEST2_DESC,
SPLAT_TASKQ_TEST2_ID, splat_taskq_test2);
return sub;
}
void
kzt_taskq_fini(kzt_subsystem_t *sub)
splat_taskq_fini(splat_subsystem_t *sub)
{
ASSERT(sub);
KZT_TEST_FINI(sub, KZT_TASKQ_TEST2_ID);
KZT_TEST_FINI(sub, KZT_TASKQ_TEST1_ID);
SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST2_ID);
SPLAT_TEST_FINI(sub, SPLAT_TASKQ_TEST1_ID);
kfree(sub);
}
int
kzt_taskq_id(void) {
return KZT_SUBSYSTEM_TASKQ;
splat_taskq_id(void) {
return SPLAT_SUBSYSTEM_TASKQ;
}

View File

@ -1,14 +1,14 @@
#include <splat-ctl.h>
#include "splat-internal.h"
#define KZT_SUBSYSTEM_THREAD 0x0600
#define KZT_THREAD_NAME "thread"
#define KZT_THREAD_DESC "Kernel Thread Tests"
#define SPLAT_SUBSYSTEM_THREAD 0x0600
#define SPLAT_THREAD_NAME "thread"
#define SPLAT_THREAD_DESC "Kernel Thread Tests"
#define KZT_THREAD_TEST1_ID 0x0601
#define KZT_THREAD_TEST1_NAME "create"
#define KZT_THREAD_TEST1_DESC "Validate thread creation and destruction"
#define SPLAT_THREAD_TEST1_ID 0x0601
#define SPLAT_THREAD_TEST1_NAME "create"
#define SPLAT_THREAD_TEST1_DESC "Validate thread creation and destruction"
#define KZT_THREAD_TEST_MAGIC 0x4488CC00UL
#define SPLAT_THREAD_TEST_MAGIC 0x4488CC00UL
typedef struct thread_priv {
unsigned long tp_magic;
@ -20,12 +20,12 @@ typedef struct thread_priv {
static void
kzt_thread_work(void *priv)
splat_thread_work(void *priv)
{
thread_priv_t *tp = (thread_priv_t *)priv;
spin_lock(&tp->tp_lock);
ASSERT(tp->tp_magic == KZT_THREAD_TEST_MAGIC);
ASSERT(tp->tp_magic == SPLAT_THREAD_TEST_MAGIC);
tp->tp_rc = 1;
spin_unlock(&tp->tp_lock);
@ -35,14 +35,14 @@ kzt_thread_work(void *priv)
}
static int
kzt_thread_test1(struct file *file, void *arg)
splat_thread_test1(struct file *file, void *arg)
{
thread_priv_t tp;
DEFINE_WAIT(wait);
kthread_t *thr;
int rc = 0;
tp.tp_magic = KZT_THREAD_TEST_MAGIC;
tp.tp_magic = SPLAT_THREAD_TEST_MAGIC;
tp.tp_file = file;
spin_lock_init(&tp.tp_lock);
init_waitqueue_head(&tp.tp_waitq);
@ -50,7 +50,7 @@ kzt_thread_test1(struct file *file, void *arg)
spin_lock(&tp.tp_lock);
thr = (kthread_t *)thread_create(NULL, 0, kzt_thread_work, &tp, 0,
thr = (kthread_t *)thread_create(NULL, 0, splat_thread_work, &tp, 0,
(proc_t *) &p0, TS_RUN, minclsyspri);
/* Must never fail under Solaris, but we check anyway so we can
* report an error when this impossible thing happens */
@ -69,7 +69,7 @@ kzt_thread_test1(struct file *file, void *arg)
spin_lock(&tp.tp_lock);
}
kzt_vprint(file, KZT_THREAD_TEST1_NAME, "%s",
splat_vprint(file, SPLAT_THREAD_TEST1_NAME, "%s",
"Thread successfully started and exited cleanly\n");
out:
spin_unlock(&tp.tp_lock);
@ -77,39 +77,39 @@ out:
return rc;
}
kzt_subsystem_t *
kzt_thread_init(void)
splat_subsystem_t *
splat_thread_init(void)
{
kzt_subsystem_t *sub;
splat_subsystem_t *sub;
sub = kmalloc(sizeof(*sub), GFP_KERNEL);
if (sub == NULL)
return NULL;
memset(sub, 0, sizeof(*sub));
strncpy(sub->desc.name, KZT_THREAD_NAME, KZT_NAME_SIZE);
strncpy(sub->desc.desc, KZT_THREAD_DESC, KZT_DESC_SIZE);
strncpy(sub->desc.name, SPLAT_THREAD_NAME, SPLAT_NAME_SIZE);
strncpy(sub->desc.desc, SPLAT_THREAD_DESC, SPLAT_DESC_SIZE);
INIT_LIST_HEAD(&sub->subsystem_list);
INIT_LIST_HEAD(&sub->test_list);
spin_lock_init(&sub->test_lock);
sub->desc.id = KZT_SUBSYSTEM_THREAD;
sub->desc.id = SPLAT_SUBSYSTEM_THREAD;
KZT_TEST_INIT(sub, KZT_THREAD_TEST1_NAME, KZT_THREAD_TEST1_DESC,
KZT_THREAD_TEST1_ID, kzt_thread_test1);
SPLAT_TEST_INIT(sub, SPLAT_THREAD_TEST1_NAME, SPLAT_THREAD_TEST1_DESC,
SPLAT_THREAD_TEST1_ID, splat_thread_test1);
return sub;
}
void
kzt_thread_fini(kzt_subsystem_t *sub)
splat_thread_fini(splat_subsystem_t *sub)
{
ASSERT(sub);
KZT_TEST_FINI(sub, KZT_THREAD_TEST1_ID);
SPLAT_TEST_FINI(sub, SPLAT_THREAD_TEST1_ID);
kfree(sub);
}
int
kzt_thread_id(void) {
return KZT_SUBSYSTEM_THREAD;
splat_thread_id(void) {
return SPLAT_SUBSYSTEM_THREAD;
}

View File

@ -1,40 +1,42 @@
#include <splat-ctl.h>
#include "splat-internal.h"
#define KZT_SUBSYSTEM_TIME 0x0800
#define KZT_TIME_NAME "time"
#define KZT_TIME_DESC "Kernel Time Tests"
#define SPLAT_SUBSYSTEM_TIME 0x0800
#define SPLAT_TIME_NAME "time"
#define SPLAT_TIME_DESC "Kernel Time Tests"
#define KZT_TIME_TEST1_ID 0x0801
#define KZT_TIME_TEST1_NAME "time1"
#define KZT_TIME_TEST1_DESC "HZ Test"
#define SPLAT_TIME_TEST1_ID 0x0801
#define SPLAT_TIME_TEST1_NAME "time1"
#define SPLAT_TIME_TEST1_DESC "HZ Test"
#define KZT_TIME_TEST2_ID 0x0802
#define KZT_TIME_TEST2_NAME "time2"
#define KZT_TIME_TEST2_DESC "Monotonic Test"
#define SPLAT_TIME_TEST2_ID 0x0802
#define SPLAT_TIME_TEST2_NAME "time2"
#define SPLAT_TIME_TEST2_DESC "Monotonic Test"
static int
kzt_time_test1(struct file *file, void *arg)
splat_time_test1(struct file *file, void *arg)
{
int myhz = hz;
kzt_vprint(file, KZT_TIME_TEST1_NAME, "hz is %d\n", myhz);
splat_vprint(file, SPLAT_TIME_TEST1_NAME, "hz is %d\n", myhz);
return 0;
}
static int
kzt_time_test2(struct file *file, void *arg)
splat_time_test2(struct file *file, void *arg)
{
hrtime_t tm1, tm2;
int i;
tm1 = gethrtime();
kzt_vprint(file, KZT_TIME_TEST2_NAME, "time is %lld\n", tm1);
splat_vprint(file, SPLAT_TIME_TEST2_NAME, "time is %lld\n", tm1);
for(i = 0; i < 100; i++) {
tm2 = gethrtime();
kzt_vprint(file, KZT_TIME_TEST2_NAME, "time is %lld\n", tm2);
splat_vprint(file, SPLAT_TIME_TEST2_NAME, "time is %lld\n", tm2);
if(tm1 > tm2) {
kzt_print(file, "%s: gethrtime() is not giving monotonically increasing values\n", KZT_TIME_TEST2_NAME);
splat_print(file, "%s: gethrtime() is not giving "
"monotonically increasing values\n",
SPLAT_TIME_TEST2_NAME);
return 1;
}
tm1 = tm2;
@ -46,44 +48,44 @@ kzt_time_test2(struct file *file, void *arg)
return 0;
}
kzt_subsystem_t *
kzt_time_init(void)
splat_subsystem_t *
splat_time_init(void)
{
kzt_subsystem_t *sub;
splat_subsystem_t *sub;
sub = kmalloc(sizeof(*sub), GFP_KERNEL);
if (sub == NULL)
return NULL;
memset(sub, 0, sizeof(*sub));
strncpy(sub->desc.name, KZT_TIME_NAME, KZT_NAME_SIZE);
strncpy(sub->desc.desc, KZT_TIME_DESC, KZT_DESC_SIZE);
strncpy(sub->desc.name, SPLAT_TIME_NAME, SPLAT_NAME_SIZE);
strncpy(sub->desc.desc, SPLAT_TIME_DESC, SPLAT_DESC_SIZE);
INIT_LIST_HEAD(&sub->subsystem_list);
INIT_LIST_HEAD(&sub->test_list);
spin_lock_init(&sub->test_lock);
sub->desc.id = KZT_SUBSYSTEM_TIME;
sub->desc.id = SPLAT_SUBSYSTEM_TIME;
KZT_TEST_INIT(sub, KZT_TIME_TEST1_NAME, KZT_TIME_TEST1_DESC,
KZT_TIME_TEST1_ID, kzt_time_test1);
KZT_TEST_INIT(sub, KZT_TIME_TEST2_NAME, KZT_TIME_TEST2_DESC,
KZT_TIME_TEST2_ID, kzt_time_test2);
SPLAT_TEST_INIT(sub, SPLAT_TIME_TEST1_NAME, SPLAT_TIME_TEST1_DESC,
SPLAT_TIME_TEST1_ID, splat_time_test1);
SPLAT_TEST_INIT(sub, SPLAT_TIME_TEST2_NAME, SPLAT_TIME_TEST2_DESC,
SPLAT_TIME_TEST2_ID, splat_time_test2);
return sub;
}
void
kzt_time_fini(kzt_subsystem_t *sub)
splat_time_fini(splat_subsystem_t *sub)
{
ASSERT(sub);
KZT_TEST_FINI(sub, KZT_TIME_TEST2_ID);
KZT_TEST_FINI(sub, KZT_TIME_TEST1_ID);
SPLAT_TEST_FINI(sub, SPLAT_TIME_TEST2_ID);
SPLAT_TEST_FINI(sub, SPLAT_TIME_TEST1_ID);
kfree(sub);
}
int
kzt_time_id(void)
splat_time_id(void)
{
return KZT_SUBSYSTEM_TIME;
return SPLAT_SUBSYSTEM_TIME;
}