Skip to content

Commit b5cf1e3

Browse files
author
whitequark
committedAug 7, 2015
runtime: avoid race condition when running kernel.
Also, don't bother passing kernel name: entry point is already recorded in DT_INIT when the kernel is linked.
1 parent 1a969aa commit b5cf1e3

File tree

6 files changed

+41
-62
lines changed

6 files changed

+41
-62
lines changed
 

Diff for: ‎artiq/coredevice/comm_generic.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,9 @@ def load(self, kcode):
130130
if ty != _D2HMsgType.LOAD_COMPLETED:
131131
raise IOError("Incorrect reply from device: "+str(ty))
132132

133-
def run(self, kname):
134-
self._write_header(len(kname) + 9, _H2DMsgType.RUN_KERNEL)
135-
self.write(bytes(kname, "ascii"))
136-
logger.debug("running kernel: %s", kname)
133+
def run(self):
134+
self._write_header(9, _H2DMsgType.RUN_KERNEL)
135+
logger.debug("running kernel")
137136

138137
def flash_storage_read(self, key):
139138
self._write_header(9+len(key), _H2DMsgType.FLASH_READ_REQUEST)

Diff for: ‎soc/runtime/kloader.c

+15-8
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,29 @@ void kloader_start_bridge()
3030
start_kernel_cpu(NULL);
3131
}
3232

33-
static int load_or_start_kernel(void *library, const char *kernel)
33+
static int load_or_start_kernel(void *library, int run_kernel)
3434
{
3535
static struct dyld_info library_info;
3636
struct msg_load_request request = {
3737
.library = library,
3838
.library_info = &library_info,
39-
.kernel = kernel,
39+
.run_kernel = run_kernel,
4040
};
4141
start_kernel_cpu(&request);
4242

4343
struct msg_load_reply *reply = mailbox_wait_and_receive();
44-
if(reply != NULL && reply->type == MESSAGE_TYPE_LOAD_REPLY) {
45-
log("cannot load/run kernel: %s", reply->error);
44+
if(reply->type != MESSAGE_TYPE_LOAD_REPLY) {
45+
log("BUG: unexpected reply to load/run request");
4646
return 0;
4747
}
4848

49+
if(reply->error != NULL) {
50+
log("cannot load kernel: %s", reply->error);
51+
return 0;
52+
}
53+
54+
mailbox_acknowledge();
55+
4956
return 1;
5057
}
5158

@@ -56,12 +63,12 @@ int kloader_load_library(void *library)
5663
return 0;
5764
}
5865

59-
return load_or_start_kernel(library, NULL);
66+
return load_or_start_kernel(library, 0);
6067
}
6168

62-
int kloader_start_kernel(const char *name)
69+
void kloader_start_kernel()
6370
{
64-
return load_or_start_kernel(NULL, name);
71+
load_or_start_kernel(NULL, 1);
6572
}
6673

6774
int kloader_start_idle_kernel(void)
@@ -74,7 +81,7 @@ int kloader_start_idle_kernel(void)
7481
if(length <= 0)
7582
return 0;
7683

77-
return load_or_start_kernel(buffer, "test.__modinit__");
84+
return load_or_start_kernel(buffer, 1);
7885
#else
7986
return 0;
8087
#endif

Diff for: ‎soc/runtime/kloader.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ int kloader_load_library(void *code);
1212

1313
void kloader_start_bridge(void);
1414
int kloader_start_idle_kernel(void);
15-
int kloader_start_kernel(const char *name);
15+
void kloader_start_kernel(void);
1616
void kloader_stop(void);
1717

1818
int kloader_validate_kpointer(void *p);

Diff for: ‎soc/runtime/ksupport.c

+20-34
Original file line numberDiff line numberDiff line change
@@ -184,51 +184,37 @@ void exception_handler(unsigned long vect, unsigned long *regs,
184184
int main(void);
185185
int main(void)
186186
{
187-
struct msg_load_request *msg = mailbox_receive();
187+
struct msg_load_request *request = mailbox_receive();
188+
struct msg_load_reply load_reply = {
189+
.type = MESSAGE_TYPE_LOAD_REPLY,
190+
.error = NULL
191+
};
188192

189-
if(msg == NULL) {
193+
if(request == NULL) {
190194
bridge_main();
191195
while(1);
192196
}
193197

194-
if(msg->library != NULL) {
195-
const char *error;
196-
if(!dyld_load(msg->library, KERNELCPU_PAYLOAD_ADDRESS,
197-
resolve_runtime_export, msg->library_info, &error)) {
198-
struct msg_load_reply msg = {
199-
.type = MESSAGE_TYPE_LOAD_REPLY,
200-
.error = error
201-
};
202-
mailbox_send(&msg);
198+
if(request->library != NULL) {
199+
if(!dyld_load(request->library, KERNELCPU_PAYLOAD_ADDRESS,
200+
resolve_runtime_export, request->library_info,
201+
&load_reply.error)) {
202+
mailbox_send(&load_reply);
203203
while(1);
204204
}
205205
}
206206

207-
void (*kernel)(void) = NULL;
208-
if(msg->kernel != NULL) {
209-
kernel = dyld_lookup(msg->kernel, msg->library_info);
210-
if(kernel == NULL) {
211-
char error[256];
212-
snprintf(error, sizeof(error),
213-
"kernel '%s' not found in library", msg->kernel);
214-
struct msg_load_reply msg = {
215-
.type = MESSAGE_TYPE_LOAD_REPLY,
216-
.error = error
217-
};
218-
mailbox_send(&msg);
219-
while(1);
220-
}
221-
}
207+
if(request->run_kernel) {
208+
void (*kernel_init)() = request->library_info->init;
222209

223-
mailbox_acknowledge();
224-
225-
if(kernel) {
226-
void (*run_closure)(void *) = msg->library_info->init;
227-
run_closure(kernel);
210+
mailbox_send_and_wait(&load_reply);
211+
kernel_init();
228212

229-
struct msg_base msg;
230-
msg.type = MESSAGE_TYPE_FINISHED;
231-
mailbox_send_and_wait(&msg);
213+
struct msg_base finished_reply;
214+
finished_reply.type = MESSAGE_TYPE_FINISHED;
215+
mailbox_send_and_wait(&finished_reply);
216+
} else {
217+
mailbox_send(&load_reply);
232218
}
233219

234220
while(1);

Diff for: ‎soc/runtime/messages.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ struct msg_base {
3939
struct msg_load_request {
4040
void *library;
4141
struct dyld_info *library_info;
42-
const char *kernel;
42+
int run_kernel;
4343
};
4444

4545
struct msg_load_reply {

Diff for: ‎soc/runtime/session.c

+1-14
Original file line numberDiff line numberDiff line change
@@ -184,21 +184,8 @@ static int process_input(void)
184184
break;
185185
}
186186

187-
if((buffer_in_index + 1) > BUFFER_OUT_SIZE) {
188-
log("Kernel name too long");
189-
buffer_out[8] = REMOTEMSG_TYPE_KERNEL_STARTUP_FAILED;
190-
submit_output(9);
191-
break;
192-
}
193-
buffer_in[buffer_in_index] = 0;
194-
195187
watchdog_init();
196-
if(!kloader_start_kernel((char *)&buffer_in[9])) {
197-
log("Failed to find kernel entry point '%s' in object", &buffer_in[9]);
198-
buffer_out[8] = REMOTEMSG_TYPE_KERNEL_STARTUP_FAILED;
199-
submit_output(9);
200-
break;
201-
}
188+
kloader_start_kernel();
202189

203190
user_kernel_state = USER_KERNEL_RUNNING;
204191
break;

0 commit comments

Comments
 (0)