mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-11 04:56:48 +00:00
bugfix:修复当使用sched()运行调度器,在切换进程的时候,由于不在中断上下文内,导致当前进程的上下文丢失的问题。 (#130)
bugfix:修复当使用sched()运行调度器,在切换进程的时候,由于不在中断上下文内,导致当前进程的上下文丢失的问题。 bugfix:修复切换进程的宏的汇编代码的损坏部分,未声明rax寄存器,从而导致的编译器未定义行为问题。
This commit is contained in:
parent
882f0b7e74
commit
156949680c
@ -513,7 +513,7 @@ ul initial_kernel_thread(ul arg)
|
|||||||
// kdebug("current_pcb->thread->rsp=%#018lx", current_pcb->thread->rsp);
|
// kdebug("current_pcb->thread->rsp=%#018lx", current_pcb->thread->rsp);
|
||||||
current_pcb->flags = 0;
|
current_pcb->flags = 0;
|
||||||
// 将返回用户层的代码压入堆栈,向rdx传入regs的地址,然后jmp到do_execve这个系统调用api的处理函数
|
// 将返回用户层的代码压入堆栈,向rdx传入regs的地址,然后jmp到do_execve这个系统调用api的处理函数
|
||||||
// 这里的设计思路和switch_proc类似 加载用户态程序:shell.elf
|
// 这里的设计思路和switch_to类似 加载用户态程序:shell.elf
|
||||||
__asm__ __volatile__("movq %1, %%rsp \n\t"
|
__asm__ __volatile__("movq %1, %%rsp \n\t"
|
||||||
"pushq %2 \n\t"
|
"pushq %2 \n\t"
|
||||||
"jmp do_execve \n\t" ::"D"(current_pcb->thread->rsp),
|
"jmp do_execve \n\t" ::"D"(current_pcb->thread->rsp),
|
||||||
|
@ -51,23 +51,23 @@ extern uint64_t process_exit_files(struct process_control_block *pcb);
|
|||||||
* 然后调用__switch_to切换栈,配置其他信息,最后恢复下一个进程的rax rbp。
|
* 然后调用__switch_to切换栈,配置其他信息,最后恢复下一个进程的rax rbp。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define switch_proc(prev, next) \
|
#define switch_to(prev, next) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
__asm__ __volatile__("pushq %%rbp \n\t" \
|
__asm__ __volatile__("pushq %%rbp \n\t" \
|
||||||
"pushq %%rax \n\t" \
|
"pushq %%rax \n\t" \
|
||||||
"movq %%rsp, %0 \n\t" \
|
"movq %%rsp, %0 \n\t" \
|
||||||
"movq %2, %%rsp \n\t" \
|
"movq %2, %%rsp \n\t" \
|
||||||
"leaq switch_proc_ret_addr(%%rip), %%rax \n\t" \
|
"leaq 2f(%%rip), %%rax \n\t" \
|
||||||
"movq %%rax, %1 \n\t" \
|
"movq %%rax, %1 \n\t" \
|
||||||
"pushq %3 \n\t" \
|
"pushq %3 \n\t" \
|
||||||
"jmp __switch_to \n\t" \
|
"jmp __switch_to \n\t" \
|
||||||
"switch_proc_ret_addr: \n\t" \
|
"2: \n\t" \
|
||||||
"popq %%rax \n\t" \
|
"popq %%rax \n\t" \
|
||||||
"popq %%rbp \n\t" \
|
"popq %%rbp \n\t" \
|
||||||
: "=m"(prev->thread->rsp), "=m"(prev->thread->rip) \
|
: "=m"(prev->thread->rsp), "=m"(prev->thread->rip) \
|
||||||
: "m"(next->thread->rsp), "m"(next->thread->rip), "D"(prev), "S"(next) \
|
: "m"(next->thread->rsp), "m"(next->thread->rip), "D"(prev), "S"(next) \
|
||||||
: "memory"); \
|
: "memory", "rax"); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "cfs.h"
|
#include "cfs.h"
|
||||||
#include <common/kprint.h>
|
#include <common/kprint.h>
|
||||||
#include <driver/video/video.h>
|
|
||||||
#include <common/spinlock.h>
|
#include <common/spinlock.h>
|
||||||
|
#include <driver/video/video.h>
|
||||||
|
|
||||||
struct sched_queue_t sched_cfs_ready_queue[MAX_CPU_NUM]; // 就绪队列
|
struct sched_queue_t sched_cfs_ready_queue[MAX_CPU_NUM]; // 就绪队列
|
||||||
|
|
||||||
@ -18,7 +18,8 @@ struct process_control_block *sched_cfs_dequeue()
|
|||||||
return &initial_proc_union.pcb;
|
return &initial_proc_union.pcb;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list), struct process_control_block, list);
|
struct process_control_block *proc = container_of(
|
||||||
|
list_next(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list), struct process_control_block, list);
|
||||||
|
|
||||||
list_del(&proc->list);
|
list_del(&proc->list);
|
||||||
--sched_cfs_ready_queue[proc_current_cpu_id].count;
|
--sched_cfs_ready_queue[proc_current_cpu_id].count;
|
||||||
@ -34,7 +35,8 @@ void sched_cfs_enqueue(struct process_control_block *pcb)
|
|||||||
{
|
{
|
||||||
if (pcb == initial_proc[proc_current_cpu_id])
|
if (pcb == initial_proc[proc_current_cpu_id])
|
||||||
return;
|
return;
|
||||||
struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list), struct process_control_block, list);
|
struct process_control_block *proc = container_of(
|
||||||
|
list_next(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list), struct process_control_block, list);
|
||||||
if ((list_empty(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list)) == 0)
|
if ((list_empty(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list)) == 0)
|
||||||
{
|
{
|
||||||
while (proc->virtual_runtime < pcb->virtual_runtime)
|
while (proc->virtual_runtime < pcb->virtual_runtime)
|
||||||
@ -58,12 +60,16 @@ void sched_cfs()
|
|||||||
current_pcb->flags &= ~PF_NEED_SCHED;
|
current_pcb->flags &= ~PF_NEED_SCHED;
|
||||||
// kdebug("current_pcb pid= %d", current_pcb->pid);
|
// kdebug("current_pcb pid= %d", current_pcb->pid);
|
||||||
struct process_control_block *proc = sched_cfs_dequeue();
|
struct process_control_block *proc = sched_cfs_dequeue();
|
||||||
// kdebug("sched_cfs_ready_queue[proc_current_cpu_id].count = %d", sched_cfs_ready_queue[proc_current_cpu_id].count);
|
// kdebug("sched_cfs_ready_queue[proc_current_cpu_id].count = %d",
|
||||||
if (current_pcb->virtual_runtime >= proc->virtual_runtime || !(current_pcb->state & PROC_RUNNING)) // 当前进程运行时间大于了下一进程的运行时间,进行切换
|
// sched_cfs_ready_queue[proc_current_cpu_id].count);
|
||||||
|
if (current_pcb->virtual_runtime >= proc->virtual_runtime ||
|
||||||
|
!(current_pcb->state & PROC_RUNNING)) // 当前进程运行时间大于了下一进程的运行时间,进行切换
|
||||||
{
|
{
|
||||||
|
|
||||||
// kdebug("current_pcb->virtual_runtime = %d,proc->vt= %d", current_pcb->virtual_runtime, proc->virtual_runtime);
|
// kdebug("current_pcb->virtual_runtime = %d,proc->vt= %d", current_pcb->virtual_runtime,
|
||||||
if (current_pcb->state & PROC_RUNNING) // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理
|
// proc->virtual_runtime);
|
||||||
|
if (current_pcb->state &
|
||||||
|
PROC_RUNNING) // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理
|
||||||
sched_cfs_enqueue(current_pcb);
|
sched_cfs_enqueue(current_pcb);
|
||||||
// kdebug("proc->pid=%d, count=%d", proc->pid, sched_cfs_ready_queue[proc_current_cpu_id].count);
|
// kdebug("proc->pid=%d, count=%d", proc->pid, sched_cfs_ready_queue[proc_current_cpu_id].count);
|
||||||
if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0)
|
if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0)
|
||||||
@ -72,18 +78,20 @@ void sched_cfs()
|
|||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue[proc_current_cpu_id].count;
|
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies =
|
||||||
|
4 / sched_cfs_ready_queue[proc_current_cpu_id].count;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
default:
|
default:
|
||||||
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue[proc_current_cpu_id].count) << 2;
|
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies =
|
||||||
|
(4 / sched_cfs_ready_queue[proc_current_cpu_id].count) << 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
process_switch_mm(proc);
|
barrier();
|
||||||
|
|
||||||
switch_proc(current_pcb, proc);
|
switch_proc(current_pcb, proc);
|
||||||
|
barrier();
|
||||||
}
|
}
|
||||||
else // 不进行切换
|
else // 不进行切换
|
||||||
{
|
{
|
||||||
@ -96,12 +104,14 @@ void sched_cfs()
|
|||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue[proc_current_cpu_id].count;
|
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies =
|
||||||
|
4 / sched_cfs_ready_queue[proc_current_cpu_id].count;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
default:
|
default:
|
||||||
|
|
||||||
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue[proc_current_cpu_id].count) << 2;
|
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies =
|
||||||
|
(4 / sched_cfs_ready_queue[proc_current_cpu_id].count) << 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#include "sched.h"
|
#include "sched.h"
|
||||||
#include <common/kprint.h>
|
#include <common/kprint.h>
|
||||||
#include <common/spinlock.h>
|
#include <common/spinlock.h>
|
||||||
|
#include <common/string.h>
|
||||||
#include <driver/video/video.h>
|
#include <driver/video/video.h>
|
||||||
#include <sched/cfs.h>
|
#include <sched/cfs.h>
|
||||||
#include <common/string.h>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
@ -60,10 +60,10 @@ void sched_enqueue(struct process_control_block *pcb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 包裹sched_cfs(),调度函数
|
* @brief 该函数只能由sys_sched调用
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void sched()
|
static void __sched()
|
||||||
{
|
{
|
||||||
sched_cfs();
|
sched_cfs();
|
||||||
}
|
}
|
||||||
@ -73,5 +73,23 @@ void sched_init()
|
|||||||
sched_cfs_init();
|
sched_cfs_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t sys_sched(struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
if(user_mode(regs)){
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
|
__sched();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sched()
|
||||||
|
{
|
||||||
|
|
||||||
|
enter_syscall_int(SYS_SCHED, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void switch_proc(struct process_control_block *prev, struct process_control_block *proc)
|
||||||
|
{
|
||||||
|
process_switch_mm(proc);
|
||||||
|
io_mfence();
|
||||||
|
switch_to(prev, proc);
|
||||||
|
}
|
||||||
|
@ -77,3 +77,4 @@ void sched_init();
|
|||||||
*/
|
*/
|
||||||
void sched_update_jiffies();
|
void sched_update_jiffies();
|
||||||
|
|
||||||
|
void switch_proc(struct process_control_block *prev, struct process_control_block *proc);
|
@ -23,6 +23,7 @@ extern uint64_t sys_kill(struct pt_regs *regs);
|
|||||||
extern uint64_t sys_sigaction(struct pt_regs * regs);
|
extern uint64_t sys_sigaction(struct pt_regs * regs);
|
||||||
extern uint64_t sys_rt_sigreturn(struct pt_regs * regs);
|
extern uint64_t sys_rt_sigreturn(struct pt_regs * regs);
|
||||||
extern uint64_t sys_getpid(struct pt_regs * regs);
|
extern uint64_t sys_getpid(struct pt_regs * regs);
|
||||||
|
extern uint64_t sys_sched(struct pt_regs * regs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 导出系统调用处理函数的符号
|
* @brief 导出系统调用处理函数的符号
|
||||||
@ -592,6 +593,7 @@ system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] = {
|
|||||||
[24] = sys_sigaction,
|
[24] = sys_sigaction,
|
||||||
[25] = sys_rt_sigreturn,
|
[25] = sys_rt_sigreturn,
|
||||||
[26] = sys_getpid,
|
[26] = sys_getpid,
|
||||||
[27 ... 254] = system_call_not_exists,
|
[27] = sys_sched,
|
||||||
|
[28 ... 254] = system_call_not_exists,
|
||||||
[255] = sys_ahci_end_req,
|
[255] = sys_ahci_end_req,
|
||||||
};
|
};
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#define SYS_KILL 23 // kill一个进程(向这个进程发出信号)
|
#define SYS_KILL 23 // kill一个进程(向这个进程发出信号)
|
||||||
#define SYS_SIGACTION 24 // 设置进程的信号处理动作
|
#define SYS_SIGACTION 24 // 设置进程的信号处理动作
|
||||||
#define SYS_RT_SIGRETURN 25 // 从信号处理函数返回
|
#define SYS_RT_SIGRETURN 25 // 从信号处理函数返回
|
||||||
#define SYS_GETPID 26 // 获取当前进程的pid(进程标识符)
|
#define SYS_GETPID 26 // 获取当前进程的pid(进程标识符)
|
||||||
|
#define SYS_SCHED 27 // 让系统立即运行调度器(该系统调用不能由运行在Ring3的程序发起)
|
||||||
|
|
||||||
#define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用
|
#define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用
|
Loading…
x
Reference in New Issue
Block a user