schedule(): do not preempt while holding spinlocks or while in offloaded syscall

This commit is contained in:
Balazs Gerofi
2015-08-06 10:36:13 +09:00
parent b77755d0f7
commit 328e69a335
7 changed files with 39 additions and 0 deletions

View File

@ -23,6 +23,7 @@
extern int num_processors;
struct cpu_local_var *clv;
static int cpu_local_var_initialized = 0;
void cpu_local_var_init(void)
{
@ -33,9 +34,22 @@ void cpu_local_var_init(void)
clv = allocate_pages(z, IHK_MC_AP_CRITICAL);
memset(clv, 0, z * PAGE_SIZE);
cpu_local_var_initialized = 1;
}
struct cpu_local_var *get_cpu_local_var(int id)
{
return clv + id;
}
void preempt_enable(void)
{
if (cpu_local_var_initialized)
--cpu_local_var(no_preempt);
}
void preempt_disable(void)
{
if (cpu_local_var_initialized)
++cpu_local_var(no_preempt);
}

View File

@ -68,6 +68,7 @@ struct cpu_local_var {
ihk_spinlock_t migq_lock;
struct list_head migq;
int in_interrupt;
int no_preempt;
} __attribute__((aligned(64)));

View File

@ -411,6 +411,7 @@ struct process {
fp_regs_struct *fp_regs;
char *saved_cmdline;
long saved_cmdline_len;
int in_syscall_offload;
};
struct process_vm {

View File

@ -370,6 +370,8 @@ static void page_fault_handler(void *fault_addr, uint64_t reason, void *regs)
dkprintf("[%d]page_fault_handler(%p,%lx,%p)\n",
ihk_mc_get_processor_id(), fault_addr, reason, regs);
preempt_disable();
cpu_enable_interrupt();
error = page_fault_process_vm(proc->vm, fault_addr, reason);
@ -422,6 +424,7 @@ static void page_fault_handler(void *fault_addr, uint64_t reason, void *regs)
error = 0;
out:
preempt_enable();
dkprintf("[%d]page_fault_handler(%p,%lx,%p): (%d)\n",
ihk_mc_get_processor_id(), fault_addr, reason,
regs, error);

View File

@ -2225,6 +2225,16 @@ void schedule(void)
unsigned long irqstate;
struct process *last;
if (cpu_local_var(no_preempt)) {
dkprintf("no schedule() while no preemption! \n");
return;
}
if (cpu_local_var(current)->in_syscall_offload) {
dkprintf("no schedule() while syscall offload!\n");
return;
}
redo:
irqstate = ihk_mc_spinlock_lock(&(get_this_cpu_local_var()->runq_lock));
v = get_this_cpu_local_var();

View File

@ -192,6 +192,7 @@ long do_syscall(struct syscall_request *req, int cpu, int pid)
unsigned long irqstate;
struct process *proc = cpu_local_var(current);
++proc->in_syscall_offload;
dkprintf("SC(%d)[%3d] sending syscall\n",
ihk_mc_get_processor_id(),
req->number);
@ -252,6 +253,7 @@ long do_syscall(struct syscall_request *req, int cpu, int pid)
ihk_mc_spinlock_unlock(&syscall_lock, irqstate);
}
--proc->in_syscall_offload;
return rc;
}