Thu Dec 3 12:16:36 2009 UTC ()
Soft-fail xcall thread creation to make RUMP_THREADS=0 work again.


(pooka)
diff -r1.4 -r1.5 src/sys/rump/librump/rumpkern/threads.c

cvs diff -r1.4 -r1.5 src/sys/rump/librump/rumpkern/threads.c (switch to unified diff)

--- src/sys/rump/librump/rumpkern/threads.c 2009/12/01 09:50:51 1.4
+++ src/sys/rump/librump/rumpkern/threads.c 2009/12/03 12:16:36 1.5
@@ -1,157 +1,161 @@ @@ -1,157 +1,161 @@
1/* $NetBSD: threads.c,v 1.4 2009/12/01 09:50:51 pooka Exp $ */ 1/* $NetBSD: threads.c,v 1.5 2009/12/03 12:16:36 pooka Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2007-2009 Antti Kantee. All Rights Reserved. 4 * Copyright (c) 2007-2009 Antti Kantee. All Rights Reserved.
5 * 5 *
6 * Development of this software was supported by 6 * Development of this software was supported by
7 * The Finnish Cultural Foundation. 7 * The Finnish Cultural Foundation.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE. 28 * SUCH DAMAGE.
29 */ 29 */
30 30
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__KERNEL_RCSID(0, "$NetBSD: threads.c,v 1.4 2009/12/01 09:50:51 pooka Exp $"); 32__KERNEL_RCSID(0, "$NetBSD: threads.c,v 1.5 2009/12/03 12:16:36 pooka Exp $");
33 33
34#include <sys/param.h> 34#include <sys/param.h>
35#include <sys/kmem.h> 35#include <sys/kmem.h>
36#include <sys/kthread.h> 36#include <sys/kthread.h>
37#include <sys/systm.h> 37#include <sys/systm.h>
38 38
39#include <machine/stdarg.h> 39#include <machine/stdarg.h>
40 40
41#include <rump/rumpuser.h> 41#include <rump/rumpuser.h>
42 42
43#include "rump_private.h" 43#include "rump_private.h"
44 44
45struct kthdesc { 45struct kthdesc {
46 void (*f)(void *); 46 void (*f)(void *);
47 void *arg; 47 void *arg;
48 struct lwp *mylwp; 48 struct lwp *mylwp;
49}; 49};
50 50
51static void * 51static void *
52threadbouncer(void *arg) 52threadbouncer(void *arg)
53{ 53{
54 struct kthdesc *k = arg; 54 struct kthdesc *k = arg;
55 struct lwp *l = k->mylwp; 55 struct lwp *l = k->mylwp;
56 void (*f)(void *); 56 void (*f)(void *);
57 void *thrarg; 57 void *thrarg;
58 58
59 f = k->f; 59 f = k->f;
60 thrarg = k->arg; 60 thrarg = k->arg;
61 rumpuser_free(k); 61 rumpuser_free(k);
62 62
63 /* schedule ourselves */ 63 /* schedule ourselves */
64 rumpuser_set_curlwp(l); 64 rumpuser_set_curlwp(l);
65 rump_schedule(); 65 rump_schedule();
66 66
67 if ((curlwp->l_pflag & LP_MPSAFE) == 0) 67 if ((curlwp->l_pflag & LP_MPSAFE) == 0)
68 KERNEL_LOCK(1, NULL); 68 KERNEL_LOCK(1, NULL);
69 69
70 f(thrarg); 70 f(thrarg);
71 71
72 panic("unreachable, should kthread_exit()"); 72 panic("unreachable, should kthread_exit()");
73} 73}
74 74
75int 75int
76kthread_create(pri_t pri, int flags, struct cpu_info *ci, 76kthread_create(pri_t pri, int flags, struct cpu_info *ci,
77 void (*func)(void *), void *arg, lwp_t **newlp, const char *fmt, ...) 77 void (*func)(void *), void *arg, lwp_t **newlp, const char *fmt, ...)
78{ 78{
79 char thrstore[MAXCOMLEN]; 79 char thrstore[MAXCOMLEN];
80 const char *thrname = NULL; 80 const char *thrname = NULL;
81 va_list ap; 81 va_list ap;
82 struct kthdesc *k; 82 struct kthdesc *k;
83 struct lwp *l; 83 struct lwp *l;
84 int rv; 84 int rv;
85 85
86 thrstore[0] = '\0'; 86 thrstore[0] = '\0';
87 if (fmt) { 87 if (fmt) {
88 va_start(ap, fmt); 88 va_start(ap, fmt);
89 vsnprintf(thrstore, sizeof(thrstore), fmt, ap); 89 vsnprintf(thrstore, sizeof(thrstore), fmt, ap);
90 va_end(ap); 90 va_end(ap);
91 thrname = thrstore; 91 thrname = thrstore;
92 } 92 }
93 93
94 /* 94 /*
95 * We don't want a module unload thread. 95 * We don't want a module unload thread.
96 * (XXX: yes, this is a kludge too, and the kernel should 96 * (XXX: yes, this is a kludge too, and the kernel should
97 * have a more flexible method for configuring which threads 97 * have a more flexible method for configuring which threads
98 * we want). 98 * we want).
99 */ 99 */
100 if (strcmp(thrstore, "modunload") == 0) { 100 if (strcmp(thrstore, "modunload") == 0) {
101 return 0; 101 return 0;
102 } 102 }
103 103
104 if (!rump_threads) { 104 if (!rump_threads) {
105 /* fake them */ 105 /* fake them */
106 if (strcmp(thrstore, "vrele") == 0) { 106 if (strcmp(thrstore, "vrele") == 0) {
107 printf("rump warning: threads not enabled, not starting" 107 printf("rump warning: threads not enabled, not starting"
108 " vrele thread\n"); 108 " vrele thread\n");
109 return 0; 109 return 0;
110 } else if (strcmp(thrstore, "cachegc") == 0) { 110 } else if (strcmp(thrstore, "cachegc") == 0) {
111 printf("rump warning: threads not enabled, not starting" 111 printf("rump warning: threads not enabled, not starting"
112 " namecache g/c thread\n"); 112 " namecache g/c thread\n");
113 return 0; 113 return 0;
114 } else if (strcmp(thrstore, "nfssilly") == 0) { 114 } else if (strcmp(thrstore, "nfssilly") == 0) {
115 printf("rump warning: threads not enabled, not enabling" 115 printf("rump warning: threads not enabled, not enabling"
116 " nfs silly rename\n"); 116 " nfs silly rename\n");
117 return 0; 117 return 0;
118 } else if (strcmp(thrstore, "unpgc") == 0) { 118 } else if (strcmp(thrstore, "unpgc") == 0) {
119 printf("rump warning: threads not enabled, not enabling" 119 printf("rump warning: threads not enabled, not enabling"
120 " UNP garbage collection\n"); 120 " UNP garbage collection\n");
121 return 0; 121 return 0;
 122 } else if (strncmp(thrstore, "xcall", sizeof("xcall")-1) == 0) {
 123 printf("rump warning: threads not enabled, CPU xcall"
 124 " not functional\n");
 125 return 0;
122 } else 126 } else
123 panic("threads not available, setenv RUMP_THREADS 1"); 127 panic("threads not available, setenv RUMP_THREADS 1");
124 } 128 }
125 KASSERT(fmt != NULL); 129 KASSERT(fmt != NULL);
126 130
127 k = rumpuser_malloc(sizeof(struct kthdesc), 0); 131 k = rumpuser_malloc(sizeof(struct kthdesc), 0);
128 k->f = func; 132 k->f = func;
129 k->arg = arg; 133 k->arg = arg;
130 k->mylwp = l = rump_lwp_alloc(0, rump_nextlid()); 134 k->mylwp = l = rump_lwp_alloc(0, rump_nextlid());
131 if (flags & KTHREAD_MPSAFE) 135 if (flags & KTHREAD_MPSAFE)
132 l->l_pflag |= LP_MPSAFE; 136 l->l_pflag |= LP_MPSAFE;
133 if (flags & KTHREAD_INTR) 137 if (flags & KTHREAD_INTR)
134 l->l_pflag |= LP_INTR; 138 l->l_pflag |= LP_INTR;
135 if (ci) { 139 if (ci) {
136 l->l_pflag |= LP_BOUND; 140 l->l_pflag |= LP_BOUND;
137 l->l_cpu = ci; 141 l->l_cpu = ci;
138 } 142 }
139 rv = rumpuser_thread_create(threadbouncer, k, thrname); 143 rv = rumpuser_thread_create(threadbouncer, k, thrname);
140 if (rv) 144 if (rv)
141 return rv; 145 return rv;
142 146
143 if (newlp) 147 if (newlp)
144 *newlp = l; 148 *newlp = l;
145 return 0; 149 return 0;
146} 150}
147 151
148void 152void
149kthread_exit(int ecode) 153kthread_exit(int ecode)
150{ 154{
151 155
152 if ((curlwp->l_pflag & LP_MPSAFE) == 0) 156 if ((curlwp->l_pflag & LP_MPSAFE) == 0)
153 KERNEL_UNLOCK_ONE(NULL); 157 KERNEL_UNLOCK_ONE(NULL);
154 rump_lwp_release(curlwp); 158 rump_lwp_release(curlwp);
155 rump_unschedule(); 159 rump_unschedule();
156 rumpuser_thread_exit(); 160 rumpuser_thread_exit();
157} 161}