Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tools/uma/smrstress/smrstress.c
39478 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2020 Jeffrey Roberson <[email protected]>
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
* 1. Redistributions of source code must retain the above copyright
10
* notice unmodified, this list of conditions, and the following
11
* disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
*
27
*/
28
#include <sys/param.h>
29
#include <sys/systm.h>
30
#include <sys/kernel.h>
31
#include <sys/libkern.h>
32
#include <sys/module.h>
33
#include <sys/mutex.h>
34
#include <sys/proc.h>
35
#include <sys/kthread.h>
36
#include <sys/conf.h>
37
#include <sys/mbuf.h>
38
#include <sys/smp.h>
39
#include <sys/smr.h>
40
#include <sys/stdarg.h>
41
42
#include <vm/uma.h>
43
44
static uma_zone_t smrs_zone;
45
static smr_t smrs_smr;
46
47
static int smrs_cpus;
48
static int smrs_writers;
49
static int smrs_started;
50
static int smrs_iterations = 10000000;
51
static int smrs_failures = 0;
52
static volatile int smrs_completed;
53
54
struct smrs {
55
int generation;
56
volatile u_int count;
57
};
58
59
uintptr_t smrs_current;
60
61
static void
62
smrs_error(struct smrs *smrs, const char *fmt, ...)
63
{
64
va_list ap;
65
66
atomic_add_int(&smrs_failures, 1);
67
printf("SMR ERROR: wr_seq %d, rd_seq %d, c_seq %d, generation %d, count %d ",
68
smrs_smr->c_shared->s_wr.seq, smrs_smr->c_shared->s_rd_seq,
69
zpcpu_get(smrs_smr)->c_seq, smrs->generation, smrs->count);
70
va_start(ap, fmt);
71
(void)vprintf(fmt, ap);
72
va_end(ap);
73
}
74
75
static void
76
smrs_read(void)
77
{
78
struct smrs *cur;
79
int cnt;
80
81
/* Wait for the writer to exit. */
82
while (smrs_completed == 0) {
83
smr_enter(smrs_smr);
84
cur = (void *)atomic_load_acq_ptr(&smrs_current);
85
if (cur->generation == -1)
86
smrs_error(cur, "read early: Use after free!\n");
87
atomic_add_int(&cur->count, 1);
88
DELAY(100);
89
cnt = atomic_fetchadd_int(&cur->count, -1);
90
if (cur->generation == -1)
91
smrs_error(cur, "read late: Use after free!\n");
92
else if (cnt <= 0)
93
smrs_error(cur, "Invalid ref\n");
94
smr_exit(smrs_smr);
95
maybe_yield();
96
}
97
}
98
99
static void
100
smrs_write(void)
101
{
102
struct smrs *cur;
103
int i;
104
105
for (i = 0; i < smrs_iterations; i++) {
106
cur = uma_zalloc_smr(smrs_zone, M_WAITOK);
107
atomic_thread_fence_rel();
108
cur = (void *)atomic_swap_ptr(&smrs_current, (uintptr_t)cur);
109
uma_zfree_smr(smrs_zone, cur);
110
}
111
}
112
113
static void
114
smrs_thread(void *arg)
115
{
116
int rw = (intptr_t)arg;
117
118
if (rw < smrs_writers)
119
smrs_write();
120
else
121
smrs_read();
122
atomic_add_int(&smrs_completed, 1);
123
kthread_exit();
124
}
125
126
static void
127
smrs_start(void)
128
{
129
struct smrs *cur;
130
int i;
131
132
smrs_cpus = mp_ncpus;
133
if (mp_ncpus > 3)
134
smrs_writers = 2;
135
else
136
smrs_writers = 1;
137
smrs_started = smrs_cpus;
138
smrs_completed = 0;
139
atomic_store_rel_ptr(&smrs_current,
140
(uintptr_t)uma_zalloc_smr(smrs_zone, M_WAITOK));
141
for (i = 0; i < smrs_started; i++)
142
kthread_add((void (*)(void *))smrs_thread,
143
(void *)(intptr_t)i, curproc, NULL, 0, 0, "smrs-%d", i);
144
145
while (smrs_completed != smrs_started)
146
pause("prf", hz/2);
147
148
cur = (void *)smrs_current;
149
smrs_current = (uintptr_t)NULL;
150
uma_zfree_smr(smrs_zone, cur);
151
152
printf("Completed %d loops with %d failures\n",
153
smrs_iterations, smrs_failures);
154
}
155
156
static int
157
smrs_ctor(void *mem, int size, void *arg, int flags)
158
{
159
static int smr_generation = 0;
160
struct smrs *smrs = mem;
161
162
if (smrs->generation != -1 && smrs->generation != 0)
163
smrs_error(smrs, "ctor: Invalid smr generation on ctor\n");
164
else if (smrs->count != 0)
165
smrs_error(smrs, "ctor: Invalid count\n");
166
smrs->generation = ++smr_generation;
167
168
return (0);
169
}
170
171
172
static void
173
smrs_dtor(void *mem, int size, void *arg)
174
{
175
struct smrs *smrs = mem;
176
177
if (smrs->generation == -1)
178
smrs_error(smrs, "dtor: Invalid generation");
179
smrs->generation = -1;
180
if (smrs->count != 0)
181
smrs_error(smrs, "dtor: Invalid count\n");
182
}
183
184
185
static void
186
smrs_init(void)
187
{
188
189
smrs_zone = uma_zcreate("smrs", sizeof(struct smrs),
190
smrs_ctor, smrs_dtor, NULL, NULL, UMA_ALIGN_PTR,
191
UMA_ZONE_SMR | UMA_ZONE_ZINIT);
192
smrs_smr = uma_zone_get_smr(smrs_zone);
193
}
194
195
static void
196
smrs_fini(void)
197
{
198
199
uma_zdestroy(smrs_zone);
200
}
201
202
static int
203
smrs_modevent(module_t mod, int what, void *arg)
204
{
205
206
switch (what) {
207
case MOD_LOAD:
208
smrs_init();
209
smrs_start();
210
break;
211
case MOD_UNLOAD:
212
smrs_fini();
213
break;
214
default:
215
break;
216
}
217
return (0);
218
}
219
220
moduledata_t smrs_meta = {
221
"smrstress",
222
smrs_modevent,
223
NULL
224
};
225
DECLARE_MODULE(smrstress, smrs_meta, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
226
MODULE_VERSION(smrstress, 1);
227
228