mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-10 08:06: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);
|
||||
current_pcb->flags = 0;
|
||||
// 将返回用户层的代码压入堆栈,向rdx传入regs的地址,然后jmp到do_execve这个系统调用api的处理函数
|
||||
// 这里的设计思路和switch_proc类似 加载用户态程序:shell.elf
|
||||
// 这里的设计思路和switch_to类似 加载用户态程序:shell.elf
|
||||
__asm__ __volatile__("movq %1, %%rsp \n\t"
|
||||
"pushq %2 \n\t"
|
||||
"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。
|
||||
*/
|
||||
|
||||
#define switch_proc(prev, next) \
|
||||
#define switch_to(prev, next) \
|
||||
do \
|
||||
{ \
|
||||
__asm__ __volatile__("pushq %%rbp \n\t" \
|
||||
"pushq %%rax \n\t" \
|
||||
"movq %%rsp, %0 \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" \
|
||||
"pushq %3 \n\t" \
|
||||
"jmp __switch_to \n\t" \
|
||||
"switch_proc_ret_addr: \n\t" \
|
||||
"2: \n\t" \
|
||||
"popq %%rax \n\t" \
|
||||
"popq %%rbp \n\t" \
|
||||
: "=m"(prev->thread->rsp), "=m"(prev->thread->rip) \
|
||||
: "m"(next->thread->rsp), "m"(next->thread->rip), "D"(prev), "S"(next) \
|
||||
: "memory"); \
|
||||
: "memory", "rax"); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "cfs.h"
|
||||
#include <common/kprint.h>
|
||||
#include <driver/video/video.h>
|
||||
#include <common/spinlock.h>
|
||||
#include <driver/video/video.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
--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])
|
||||
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)
|
||||
{
|
||||
while (proc->virtual_runtime < pcb->virtual_runtime)
|
||||
@ -58,12 +60,16 @@ void sched_cfs()
|
||||
current_pcb->flags &= ~PF_NEED_SCHED;
|
||||
// kdebug("current_pcb pid= %d", current_pcb->pid);
|
||||
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);
|
||||
if (current_pcb->virtual_runtime >= proc->virtual_runtime || !(current_pcb->state & PROC_RUNNING)) // 当前进程运行时间大于了下一进程的运行时间,进行切换
|
||||
// kdebug("sched_cfs_ready_queue[proc_current_cpu_id].count = %d",
|
||||
// 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);
|
||||
if (current_pcb->state & PROC_RUNNING) // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理
|
||||
// kdebug("current_pcb->virtual_runtime = %d,proc->vt= %d", current_pcb->virtual_runtime,
|
||||
// proc->virtual_runtime);
|
||||
if (current_pcb->state &
|
||||
PROC_RUNNING) // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理
|
||||
sched_cfs_enqueue(current_pcb);
|
||||
// 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)
|
||||
@ -72,18 +78,20 @@ void sched_cfs()
|
||||
{
|
||||
case 0:
|
||||
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;
|
||||
case 2:
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
process_switch_mm(proc);
|
||||
|
||||
barrier();
|
||||
switch_proc(current_pcb, proc);
|
||||
barrier();
|
||||
}
|
||||
else // 不进行切换
|
||||
{
|
||||
@ -96,12 +104,14 @@ void sched_cfs()
|
||||
{
|
||||
case 0:
|
||||
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;
|
||||
case 2:
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
#include "sched.h"
|
||||
#include <common/kprint.h>
|
||||
#include <common/spinlock.h>
|
||||
#include <common/string.h>
|
||||
#include <driver/video/video.h>
|
||||
#include <sched/cfs.h>
|
||||
#include <common/string.h>
|
||||
|
||||
/**
|
||||
* @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();
|
||||
}
|
||||
@ -73,5 +73,23 @@ void sched_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 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_rt_sigreturn(struct pt_regs * regs);
|
||||
extern uint64_t sys_getpid(struct pt_regs * regs);
|
||||
extern uint64_t sys_sched(struct pt_regs * regs);
|
||||
|
||||
/**
|
||||
* @brief 导出系统调用处理函数的符号
|
||||
@ -592,6 +593,7 @@ system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] = {
|
||||
[24] = sys_sigaction,
|
||||
[25] = sys_rt_sigreturn,
|
||||
[26] = sys_getpid,
|
||||
[27 ... 254] = system_call_not_exists,
|
||||
[27] = sys_sched,
|
||||
[28 ... 254] = system_call_not_exists,
|
||||
[255] = sys_ahci_end_req,
|
||||
};
|
||||
|
@ -37,6 +37,7 @@
|
||||
#define SYS_KILL 23 // kill一个进程(向这个进程发出信号)
|
||||
#define SYS_SIGACTION 24 // 设置进程的信号处理动作
|
||||
#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的系统调用
|
Loading…
x
Reference in New Issue
Block a user