Fri Dec 9 17:21:45 2011 UTC ()
Disable aio usage in thunkbus_ld since mixing ucontext_t and threads is a NONO
according to the manpage.

Why is AIO using a pthread?


(reinoud)
diff -r1.19 -r1.20 src/sys/arch/usermode/dev/ld_thunkbus.c

cvs diff -r1.19 -r1.20 src/sys/arch/usermode/dev/ld_thunkbus.c (switch to unified diff)

--- src/sys/arch/usermode/dev/ld_thunkbus.c 2011/11/27 21:22:28 1.19
+++ src/sys/arch/usermode/dev/ld_thunkbus.c 2011/12/09 17:21:45 1.20
@@ -1,284 +1,284 @@ @@ -1,284 +1,284 @@
1/* $NetBSD: ld_thunkbus.c,v 1.19 2011/11/27 21:22:28 reinoud Exp $ */ 1/* $NetBSD: ld_thunkbus.c,v 1.20 2011/12/09 17:21:45 reinoud Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: ld_thunkbus.c,v 1.19 2011/11/27 21:22:28 reinoud Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: ld_thunkbus.c,v 1.20 2011/12/09 17:21:45 reinoud Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/proc.h> 33#include <sys/proc.h>
34#include <sys/systm.h> 34#include <sys/systm.h>
35#include <sys/device.h> 35#include <sys/device.h>
36#include <sys/buf.h> 36#include <sys/buf.h>
37#include <sys/disk.h> 37#include <sys/disk.h>
38#include <sys/kmem.h> 38#include <sys/kmem.h>
39 39
40#include <dev/ldvar.h> 40#include <dev/ldvar.h>
41 41
42#include <machine/mainbus.h> 42#include <machine/mainbus.h>
43#include <machine/thunk.h> 43#include <machine/thunk.h>
44#include <machine/intr.h> 44#include <machine/intr.h>
45 45
46static int ld_thunkbus_match(device_t, cfdata_t, void *); 46static int ld_thunkbus_match(device_t, cfdata_t, void *);
47static void ld_thunkbus_attach(device_t, device_t, void *); 47static void ld_thunkbus_attach(device_t, device_t, void *);
48 48
49static int ld_thunkbus_ldstart(struct ld_softc *, struct buf *); 49static int ld_thunkbus_ldstart(struct ld_softc *, struct buf *);
50static int ld_thunkbus_lddump(struct ld_softc *, void *, int, int); 50static int ld_thunkbus_lddump(struct ld_softc *, void *, int, int);
51static int ld_thunkbus_ldflush(struct ld_softc *, int); 51static int ld_thunkbus_ldflush(struct ld_softc *, int);
52 52
53#define LD_USE_AIO 53//#define LD_USE_AIO
54 54
55#ifdef LD_USE_AIO 55#ifdef LD_USE_AIO
56static void ld_thunkbus_sig(int, siginfo_t *, void *); 56static void ld_thunkbus_sig(int, siginfo_t *, void *);
57#endif 57#endif
58static void ld_thunkbus_complete(void *arg); 58static void ld_thunkbus_complete(void *arg);
59 59
60struct ld_thunkbus_softc; 60struct ld_thunkbus_softc;
61 61
62struct ld_thunkbus_transfer { 62struct ld_thunkbus_transfer {
63 struct ld_thunkbus_softc *tt_sc; 63 struct ld_thunkbus_softc *tt_sc;
64 struct aiocb tt_aio; 64 struct aiocb tt_aio;
65 struct buf *tt_bp; 65 struct buf *tt_bp;
66}; 66};
67 67
68struct ld_thunkbus_softc { 68struct ld_thunkbus_softc {
69 struct ld_softc sc_ld; 69 struct ld_softc sc_ld;
70 70
71 int sc_fd; 71 int sc_fd;
72 void *sc_ih; 72 void *sc_ih;
73 73
74 struct ld_thunkbus_transfer sc_tt; 74 struct ld_thunkbus_transfer sc_tt;
75 bool busy; 75 bool busy;
76}; 76};
77 77
78CFATTACH_DECL_NEW(ld_thunkbus, sizeof(struct ld_thunkbus_softc), 78CFATTACH_DECL_NEW(ld_thunkbus, sizeof(struct ld_thunkbus_softc),
79 ld_thunkbus_match, ld_thunkbus_attach, NULL, NULL); 79 ld_thunkbus_match, ld_thunkbus_attach, NULL, NULL);
80 80
81static int 81static int
82ld_thunkbus_match(device_t parent, cfdata_t match, void *opaque) 82ld_thunkbus_match(device_t parent, cfdata_t match, void *opaque)
83{ 83{
84 struct thunkbus_attach_args *taa = opaque; 84 struct thunkbus_attach_args *taa = opaque;
85 85
86 if (taa->taa_type != THUNKBUS_TYPE_DISKIMAGE) 86 if (taa->taa_type != THUNKBUS_TYPE_DISKIMAGE)
87 return 0; 87 return 0;
88 88
89 return 1; 89 return 1;
90} 90}
91 91
92static void 92static void
93ld_thunkbus_attach(device_t parent, device_t self, void *opaque) 93ld_thunkbus_attach(device_t parent, device_t self, void *opaque)
94{ 94{
95 struct ld_thunkbus_softc *sc = device_private(self); 95 struct ld_thunkbus_softc *sc = device_private(self);
96 struct ld_softc *ld = &sc->sc_ld; 96 struct ld_softc *ld = &sc->sc_ld;
97 struct thunkbus_attach_args *taa = opaque; 97 struct thunkbus_attach_args *taa = opaque;
98#ifdef LD_USE_AIO 98#ifdef LD_USE_AIO
99 struct sigaction sa; 99 struct sigaction sa;
100#endif 100#endif
101 const char *path = taa->u.diskimage.path; 101 const char *path = taa->u.diskimage.path;
102 ssize_t size, blksize; 102 ssize_t size, blksize;
103 103
104 ld->sc_dv = self; 104 ld->sc_dv = self;
105 105
106 sc->sc_fd = thunk_open(path, O_RDWR, 0); 106 sc->sc_fd = thunk_open(path, O_RDWR, 0);
107 if (sc->sc_fd == -1) { 107 if (sc->sc_fd == -1) {
108 aprint_error(": couldn't open %s: %d\n", path, thunk_geterrno()); 108 aprint_error(": couldn't open %s: %d\n", path, thunk_geterrno());
109 return; 109 return;
110 } 110 }
111 if (thunk_fstat_getsize(sc->sc_fd, &size, &blksize) == -1) { 111 if (thunk_fstat_getsize(sc->sc_fd, &size, &blksize) == -1) {
112 aprint_error(": couldn't stat %s: %d\n", path, thunk_geterrno()); 112 aprint_error(": couldn't stat %s: %d\n", path, thunk_geterrno());
113 return; 113 return;
114 } 114 }
115 115
116 aprint_naive("\n"); 116 aprint_naive("\n");
117 aprint_normal(": %s (%lld)\n", path, (long long)size); 117 aprint_normal(": %s (%lld)\n", path, (long long)size);
118 118
119 ld->sc_flags = LDF_ENABLED; 119 ld->sc_flags = LDF_ENABLED;
120 ld->sc_maxxfer = blksize; 120 ld->sc_maxxfer = blksize;
121 ld->sc_secsize = 512; 121 ld->sc_secsize = 512;
122 ld->sc_secperunit = size / ld->sc_secsize; 122 ld->sc_secperunit = size / ld->sc_secsize;
123 ld->sc_maxqueuecnt = 1; 123 ld->sc_maxqueuecnt = 1;
124 ld->sc_start = ld_thunkbus_ldstart; 124 ld->sc_start = ld_thunkbus_ldstart;
125 ld->sc_dump = ld_thunkbus_lddump; 125 ld->sc_dump = ld_thunkbus_lddump;
126 ld->sc_flush = ld_thunkbus_ldflush; 126 ld->sc_flush = ld_thunkbus_ldflush;
127 127
128 sc->sc_ih = softint_establish(SOFTINT_BIO, 128 sc->sc_ih = softint_establish(SOFTINT_BIO,
129 ld_thunkbus_complete, sc); 129 ld_thunkbus_complete, sc);
130 130
131#ifdef LD_USE_AIO 131#ifdef LD_USE_AIO
132 sa.sa_flags = SA_RESTART | SA_SIGINFO; 132 sa.sa_flags = SA_RESTART | SA_SIGINFO;
133 sa.sa_sigaction = ld_thunkbus_sig; 133 sa.sa_sigaction = ld_thunkbus_sig;
134 thunk_sigemptyset(&sa.sa_mask); 134 thunk_sigemptyset(&sa.sa_mask);
135// thunk_sigaddset(&sa.sa_mask, SIGALRM); 135// thunk_sigaddset(&sa.sa_mask, SIGALRM);
136 if (thunk_sigaction(SIGIO, &sa, NULL) == -1) 136 if (thunk_sigaction(SIGIO, &sa, NULL) == -1)
137 panic("couldn't register SIGIO handler: %d", thunk_geterrno()); 137 panic("couldn't register SIGIO handler: %d", thunk_geterrno());
138#endif 138#endif
139 139
140 sc->busy = false; 140 sc->busy = false;
141 141
142 ldattach(ld); 142 ldattach(ld);
143} 143}
144 144
145#ifdef LD_USE_AIO 145#ifdef LD_USE_AIO
146static void 146static void
147ld_thunkbus_sig(int sig, siginfo_t *info, void *ctx) 147ld_thunkbus_sig(int sig, siginfo_t *info, void *ctx)
148{ 148{
149 struct ld_thunkbus_transfer *tt = NULL; 149 struct ld_thunkbus_transfer *tt = NULL;
150 struct ld_thunkbus_softc *sc; 150 struct ld_thunkbus_softc *sc;
151 151
152 curcpu()->ci_idepth++; 152 curcpu()->ci_idepth++;
153 153
154 if (info->si_signo == SIGIO) { 154 if (info->si_signo == SIGIO) {
155 if (info->si_code == SI_ASYNCIO) 155 if (info->si_code == SI_ASYNCIO)
156 tt = info->si_value.sival_ptr; 156 tt = info->si_value.sival_ptr;
157 if (tt) { 157 if (tt) {
158 sc = tt->tt_sc; 158 sc = tt->tt_sc;
159 spl_intr(IPL_BIO, softint_schedule, sc->sc_ih); 159 spl_intr(IPL_BIO, softint_schedule, sc->sc_ih);
160 // spl_intr(IPL_BIO, ld_thunkbus_complete, sc); 160 // spl_intr(IPL_BIO, ld_thunkbus_complete, sc);
161 // softint_schedule(sc->sc_ih); 161 // softint_schedule(sc->sc_ih);
162 } 162 }
163 } 163 }
164 164
165 curcpu()->ci_idepth--; 165 curcpu()->ci_idepth--;
166} 166}
167#endif 167#endif
168 168
169static int 169static int
170ld_thunkbus_ldstart(struct ld_softc *ld, struct buf *bp) 170ld_thunkbus_ldstart(struct ld_softc *ld, struct buf *bp)
171{ 171{
172 struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld; 172 struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld;
173 struct ld_thunkbus_transfer *tt = &sc->sc_tt; 173 struct ld_thunkbus_transfer *tt = &sc->sc_tt;
174 int error; 174 int error;
175 175
176 tt->tt_sc = sc; 176 tt->tt_sc = sc;
177 tt->tt_bp = bp; 177 tt->tt_bp = bp;
178 memset(&tt->tt_aio, 0, sizeof(tt->tt_aio)); 178 memset(&tt->tt_aio, 0, sizeof(tt->tt_aio));
179 tt->tt_aio.aio_fildes = sc->sc_fd; 179 tt->tt_aio.aio_fildes = sc->sc_fd;
180 tt->tt_aio.aio_buf = bp->b_data; 180 tt->tt_aio.aio_buf = bp->b_data;
181 tt->tt_aio.aio_nbytes = bp->b_bcount; 181 tt->tt_aio.aio_nbytes = bp->b_bcount;
182 tt->tt_aio.aio_offset = bp->b_rawblkno * ld->sc_secsize; 182 tt->tt_aio.aio_offset = bp->b_rawblkno * ld->sc_secsize;
183 183
184 tt->tt_aio.aio_sigevent.sigev_notify = SIGEV_SIGNAL; 184 tt->tt_aio.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
185 tt->tt_aio.aio_sigevent.sigev_signo = SIGIO; 185 tt->tt_aio.aio_sigevent.sigev_signo = SIGIO;
186 tt->tt_aio.aio_sigevent.sigev_value.sival_ptr = tt; 186 tt->tt_aio.aio_sigevent.sigev_value.sival_ptr = tt;
187#ifdef LD_USE_AIO 187#ifdef LD_USE_AIO
188#if 0 188#if 0
189 device_printf(sc->sc_ld.sc_dv, "%s addr %p, off=%lld, count=%lld\n", 189 device_printf(sc->sc_ld.sc_dv, "%s addr %p, off=%lld, count=%lld\n",
190 (bp->b_flags & B_READ) ? "rd" : "wr", 190 (bp->b_flags & B_READ) ? "rd" : "wr",
191 bp->b_data, 191 bp->b_data,
192 (long long)bp->b_rawblkno, 192 (long long)bp->b_rawblkno,
193 (long long)bp->b_bcount); 193 (long long)bp->b_bcount);
194#endif 194#endif
195 if (sc->busy) 195 if (sc->busy)
196 panic("%s: reentry", __func__); 196 panic("%s: reentry", __func__);
197 sc->busy = true; 197 sc->busy = true;
198 198
199 if (bp->b_flags & B_READ) 199 if (bp->b_flags & B_READ)
200 error = thunk_aio_read(&tt->tt_aio); 200 error = thunk_aio_read(&tt->tt_aio);
201 else 201 else
202 error = thunk_aio_write(&tt->tt_aio); 202 error = thunk_aio_write(&tt->tt_aio);
203#else 203#else
204 /* let the softint do the work */ 204 /* let the softint do the work */
205 spl_intr(IPL_BIO, softint_schedule, sc->sc_ih); 205 spl_intr(IPL_BIO, softint_schedule, sc->sc_ih);
206 sc->busy = true; 206 sc->busy = true;
207 error = 0; 207 error = 0;
208#endif 208#endif
209 return error == -1 ? thunk_geterrno() : 0; 209 return error == -1 ? thunk_geterrno() : 0;
210} 210}
211 211
212static void 212static void
213ld_thunkbus_complete(void *arg) 213ld_thunkbus_complete(void *arg)
214{ 214{
215 struct ld_thunkbus_softc *sc = arg; 215 struct ld_thunkbus_softc *sc = arg;
216 struct ld_thunkbus_transfer *tt = &sc->sc_tt; 216 struct ld_thunkbus_transfer *tt = &sc->sc_tt;
217 struct buf *bp = tt->tt_bp; 217 struct buf *bp = tt->tt_bp;
218 218
219 if (!sc->busy) 219 if (!sc->busy)
220 panic("%s: but not busy?\n", __func__); 220 panic("%s: but not busy?\n", __func__);
221 221
222#ifdef LD_USE_AIO 222#ifdef LD_USE_AIO
223 if (thunk_aio_error(&tt->tt_aio) == 0 && 223 if (thunk_aio_error(&tt->tt_aio) == 0 &&
224 thunk_aio_return(&tt->tt_aio) != -1) { 224 thunk_aio_return(&tt->tt_aio) != -1) {
225 bp->b_resid = 0; 225 bp->b_resid = 0;
226 } else { 226 } else {
227 bp->b_error = thunk_geterrno(); 227 bp->b_error = thunk_geterrno();
228 bp->b_resid = bp->b_bcount; 228 bp->b_resid = bp->b_bcount;
229 } 229 }
230#else 230#else
231 size_t ret; 231 size_t ret;
232 off_t offset = tt->tt_aio.aio_offset; 232 off_t offset = tt->tt_aio.aio_offset;
233 233
234 /* read/write the request */ 234 /* read/write the request */
235 if (bp->b_flags & B_READ) 235 if (bp->b_flags & B_READ)
236 ret = thunk_pread(sc->sc_fd, bp->b_data, bp->b_bcount, offset); 236 ret = thunk_pread(sc->sc_fd, bp->b_data, bp->b_bcount, offset);
237 else 237 else
238 ret = thunk_pwrite(sc->sc_fd, bp->b_data, bp->b_bcount, offset); 238 ret = thunk_pwrite(sc->sc_fd, bp->b_data, bp->b_bcount, offset);
239 239
240 /* setup return params */ 240 /* setup return params */
241 if ((ret >= 0) && (ret == bp->b_bcount)) { 241 if ((ret >= 0) && (ret == bp->b_bcount)) {
242 bp->b_resid = 0; 242 bp->b_resid = 0;
243 } else { 243 } else {
244 bp->b_error = thunk_geterrno(); 244 bp->b_error = thunk_geterrno();
245 bp->b_resid = bp->b_bcount; 245 bp->b_resid = bp->b_bcount;
246 } 246 }
247#endif 247#endif
248 248
249 dprintf_debug("\tfin\n"); 249 dprintf_debug("\tfin\n");
250 if (bp->b_error) 250 if (bp->b_error)
251 dprintf_debug("error!\n"); 251 dprintf_debug("error!\n");
252 252
253 sc->busy = false; 253 sc->busy = false;
254 lddone(&sc->sc_ld, bp); 254 lddone(&sc->sc_ld, bp);
255} 255}
256 256
257static int 257static int
258ld_thunkbus_lddump(struct ld_softc *ld, void *data, int blkno, int blkcnt) 258ld_thunkbus_lddump(struct ld_softc *ld, void *data, int blkno, int blkcnt)
259{ 259{
260 struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld; 260 struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld;
261 ssize_t len; 261 ssize_t len;
262 262
263 len = thunk_pwrite(sc->sc_fd, data, blkcnt, blkno); 263 len = thunk_pwrite(sc->sc_fd, data, blkcnt, blkno);
264 if (len == -1) 264 if (len == -1)
265 return thunk_geterrno(); 265 return thunk_geterrno();
266 else if (len != blkcnt) { 266 else if (len != blkcnt) {
267 device_printf(ld->sc_dv, "%s failed (short xfer)\n", __func__); 267 device_printf(ld->sc_dv, "%s failed (short xfer)\n", __func__);
268 return EIO; 268 return EIO;
269 } 269 }
270 270
271 return 0; 271 return 0;
272} 272}
273 273
274static int 274static int
275ld_thunkbus_ldflush(struct ld_softc *ld, int flags) 275ld_thunkbus_ldflush(struct ld_softc *ld, int flags)
276{ 276{
277 struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld; 277 struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld;
278 278
279 if (thunk_fsync(sc->sc_fd) == -1) 279 if (thunk_fsync(sc->sc_fd) == -1)
280 return thunk_geterrno(); 280 return thunk_geterrno();
281 281
282 return 0; 282 return 0;
283} 283}
284 284