b65fe0356b
We currently have a race for a free SPE. With one thread doing a spu_yield(), and another doing a spu_activate(): thread 1 thread 2 spu_yield(oldctx) spu_activate(ctx) __spu_deactivate(oldctx) spu_unschedule(oldctx, spu) spu->alloc_state = SPU_FREE spu = spu_get_idle(ctx) - searches for a SPE in state SPU_FREE, gets the context just freed by thread 1 spu_schedule(ctx, spu) spu->alloc_state = SPU_USED spu_schedule(newctx, spu) - assumes spu is still free - tries to schedule context on already-used spu This change introduces a 'free_spu' flag to spu_unschedule, to indicate whether or not the function should free the spu after descheduling the context. We only set this flag if we're not going to re-schedule another context on this SPU. Add a comment to document this behaviour. Signed-off-by: Jeremy Kerr <jk@ozlabs.org> |
||
---|---|---|
.. | ||
.gitignore | ||
backing_ops.c | ||
context.c | ||
coredump.c | ||
fault.c | ||
file.c | ||
gang.c | ||
hw_ops.c | ||
inode.c | ||
lscsa_alloc.c | ||
Makefile | ||
run.c | ||
sched.c | ||
spu_restore_crt0.S | ||
spu_restore_dump.h_shipped | ||
spu_restore.c | ||
spu_save_crt0.S | ||
spu_save_dump.h_shipped | ||
spu_save.c | ||
spu_utils.h | ||
spufs.h | ||
sputrace.c | ||
switch.c | ||
syscalls.c |