]> git.proxmox.com Git - mirror_spl-debian.git/blob - modules/splat/splat-thread.c
Remove 3 instances of unused variables.
[mirror_spl-debian.git] / modules / splat / splat-thread.c
1 /*
2 * This file is part of the SPL: Solaris Porting Layer.
3 *
4 * Copyright (c) 2008 Lawrence Livermore National Security, LLC.
5 * Produced at Lawrence Livermore National Laboratory
6 * Written by:
7 * Brian Behlendorf <behlendorf1@llnl.gov>,
8 * Herb Wartens <wartens2@llnl.gov>,
9 * Jim Garlick <garlick@llnl.gov>
10 * UCRL-CODE-235197
11 *
12 * This is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 *
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 */
26
27 #include "splat-internal.h"
28
29 #define SPLAT_SUBSYSTEM_THREAD 0x0600
30 #define SPLAT_THREAD_NAME "thread"
31 #define SPLAT_THREAD_DESC "Kernel Thread Tests"
32
33 #define SPLAT_THREAD_TEST1_ID 0x0601
34 #define SPLAT_THREAD_TEST1_NAME "create"
35 #define SPLAT_THREAD_TEST1_DESC "Validate thread creation"
36
37 #define SPLAT_THREAD_TEST2_ID 0x0602
38 #define SPLAT_THREAD_TEST2_NAME "exit"
39 #define SPLAT_THREAD_TEST2_DESC "Validate thread exit"
40
41 #define SPLAT_THREAD_TEST_MAGIC 0x4488CC00UL
42
43 typedef struct thread_priv {
44 unsigned long tp_magic;
45 struct file *tp_file;
46 spinlock_t tp_lock;
47 wait_queue_head_t tp_waitq;
48 int tp_rc;
49 } thread_priv_t;
50
51 static int
52 splat_thread_rc(thread_priv_t *tp, int rc)
53 {
54 int ret;
55
56 spin_lock(&tp->tp_lock);
57 ret = (tp->tp_rc == rc);
58 spin_unlock(&tp->tp_lock);
59
60 return ret;
61 }
62
63 static void
64 splat_thread_work1(void *priv)
65 {
66 thread_priv_t *tp = (thread_priv_t *)priv;
67
68 spin_lock(&tp->tp_lock);
69 ASSERT(tp->tp_magic == SPLAT_THREAD_TEST_MAGIC);
70 tp->tp_rc = 1;
71 spin_unlock(&tp->tp_lock);
72
73 wake_up(&tp->tp_waitq);
74 thread_exit();
75 }
76
77 static int
78 splat_thread_test1(struct file *file, void *arg)
79 {
80 thread_priv_t tp;
81 kthread_t *thr;
82
83 tp.tp_magic = SPLAT_THREAD_TEST_MAGIC;
84 tp.tp_file = file;
85 spin_lock_init(&tp.tp_lock);
86 init_waitqueue_head(&tp.tp_waitq);
87 tp.tp_rc = 0;
88
89 thr = (kthread_t *)thread_create(NULL, 0, splat_thread_work1, &tp, 0,
90 &p0, TS_RUN, minclsyspri);
91 /* Must never fail under Solaris, but we check anyway since this
92 * can happen in the linux SPL, we may want to change this behavior */
93 if (thr == NULL)
94 return -ESRCH;
95
96 /* Sleep until the thread sets tp.tp_rc == 1 */
97 wait_event(tp.tp_waitq, splat_thread_rc(&tp, 1));
98
99 splat_vprint(file, SPLAT_THREAD_TEST1_NAME, "%s",
100 "Thread successfully started properly\n");
101 return 0;
102 }
103
104 static void
105 splat_thread_work2(void *priv)
106 {
107 thread_priv_t *tp = (thread_priv_t *)priv;
108
109 spin_lock(&tp->tp_lock);
110 ASSERT(tp->tp_magic == SPLAT_THREAD_TEST_MAGIC);
111 tp->tp_rc = 1;
112 spin_unlock(&tp->tp_lock);
113
114 wake_up(&tp->tp_waitq);
115 thread_exit();
116
117 /* The following code is unreachable when thread_exit() is
118 * working properly, which is exactly what we're testing */
119 spin_lock(&tp->tp_lock);
120 tp->tp_rc = 2;
121 spin_unlock(&tp->tp_lock);
122
123 wake_up(&tp->tp_waitq);
124 }
125
126 static int
127 splat_thread_test2(struct file *file, void *arg)
128 {
129 thread_priv_t tp;
130 kthread_t *thr;
131 int rc = 0;
132
133 tp.tp_magic = SPLAT_THREAD_TEST_MAGIC;
134 tp.tp_file = file;
135 spin_lock_init(&tp.tp_lock);
136 init_waitqueue_head(&tp.tp_waitq);
137 tp.tp_rc = 0;
138
139 thr = (kthread_t *)thread_create(NULL, 0, splat_thread_work2, &tp, 0,
140 &p0, TS_RUN, minclsyspri);
141 /* Must never fail under Solaris, but we check anyway since this
142 * can happen in the linux SPL, we may want to change this behavior */
143 if (thr == NULL)
144 return -ESRCH;
145
146 /* Sleep until the thread sets tp.tp_rc == 1 */
147 wait_event(tp.tp_waitq, splat_thread_rc(&tp, 1));
148
149 /* Sleep until the thread sets tp.tp_rc == 2, or until we hit
150 * the timeout. If thread exit is working properly we should
151 * hit the timeout and never see to.tp_rc == 2. */
152 rc = wait_event_timeout(tp.tp_waitq, splat_thread_rc(&tp, 2), HZ / 10);
153 if (rc > 0) {
154 rc = -EINVAL;
155 splat_vprint(file, SPLAT_THREAD_TEST2_NAME, "%s",
156 "Thread did not exit properly at thread_exit()\n");
157 } else {
158 splat_vprint(file, SPLAT_THREAD_TEST2_NAME, "%s",
159 "Thread successfully exited at thread_exit()\n");
160 }
161
162 return rc;
163 }
164
165 splat_subsystem_t *
166 splat_thread_init(void)
167 {
168 splat_subsystem_t *sub;
169
170 sub = kmalloc(sizeof(*sub), GFP_KERNEL);
171 if (sub == NULL)
172 return NULL;
173
174 memset(sub, 0, sizeof(*sub));
175 strncpy(sub->desc.name, SPLAT_THREAD_NAME, SPLAT_NAME_SIZE);
176 strncpy(sub->desc.desc, SPLAT_THREAD_DESC, SPLAT_DESC_SIZE);
177 INIT_LIST_HEAD(&sub->subsystem_list);
178 INIT_LIST_HEAD(&sub->test_list);
179 spin_lock_init(&sub->test_lock);
180 sub->desc.id = SPLAT_SUBSYSTEM_THREAD;
181
182 SPLAT_TEST_INIT(sub, SPLAT_THREAD_TEST1_NAME, SPLAT_THREAD_TEST1_DESC,
183 SPLAT_THREAD_TEST1_ID, splat_thread_test1);
184 SPLAT_TEST_INIT(sub, SPLAT_THREAD_TEST2_NAME, SPLAT_THREAD_TEST2_DESC,
185 SPLAT_THREAD_TEST2_ID, splat_thread_test2);
186
187 return sub;
188 }
189
190 void
191 splat_thread_fini(splat_subsystem_t *sub)
192 {
193 ASSERT(sub);
194 SPLAT_TEST_FINI(sub, SPLAT_THREAD_TEST2_ID);
195 SPLAT_TEST_FINI(sub, SPLAT_THREAD_TEST1_ID);
196
197 kfree(sub);
198 }
199
200 int
201 splat_thread_id(void) {
202 return SPLAT_SUBSYSTEM_THREAD;
203 }