内核进程实验
实验目的
通过/proc/<PID>/ctx
,查看进程被调用的次数。认识linux
中的进程结构。
实验环境
- 宿主机:
Ubuntu 20.04
- 内核版本:
v6.1
实验内容
task_struct
在linux
中使用task_struct
作为进程描述符,用于进程管理。我们可以在include/linux/sched.h
中看到它的结构。下面是参考的报告中的内容:
struct task_struct {
int ctx; //add a type
int on_rq;
int prio;
int static_prio;
int normal_prio;
unsigned int rt_priority;
//...
}
进程的创建
linux
进程创建的代码位于kernel/fork.c
中。
首先分析Linux
中三个系统调用fork
,vfork
, clone
,这三个系统调用都在设置参数后,通过_do_fork
返回。
long _do_fork(struct kernel_clone_args *args){
//...
}
可以看出_do_fork()
会完成进程的复制。_do_fork()
会调用copy_process
函数,接着添加lantent entropy
,随后调用trace_sched_process_fork()
函数唤醒新的线程。
p = copy_process(NULL, trace, NUMA_NO_NODE, args);
add_latent_entropy();
if(IS_ERR(p))
return PTR_ERR(p);
/*
* Do this prior waking up the new thread - the thread pointer
* might get invalid affter that point, if the thread exits quickly.
*/
trace_sched_process_fork(current, p);
加下来是copy_process
的函数说明, 我们在这一步进行ctx
变量的初始化。
static __latent_entropy struct task_struct *copy_process(
struct pid *pid,
int trace,
int node,
struct kernel_clone_args *args)
{
p->ctx = 0;
retval = sched_fork(clone_flags, p);
if(retval)
goto bad_fork_cleanup_policy;
//...
}
每次进程被调度时,我们要对其进行加1的操作,我们定位到kernel/sched/core.c
中的schedule
函数,我们在每次调用时,对ctx
进行加1的操作。
asmlinkage __visible void __sched schedule(void){
struct task_struct *tsk = current;
tsk->ctx ++;
sched_submit_work(tsk);
do{
preempt_disable();
__schedule(false);
sched_preempt_enable_no_resched();
} while(need_resched());
sched_update_worker(tsk);
}
EXPORT_SYMBOL(schedule);
该函数会创建指向当前进程的指针tsk
,并调用sched_submit_work()
死锁检测,然后在循环中进行该进程的调度,preempt_disable()
用于禁用内核抢占,然后__schedule()
函数进行调度。
伪文件接口
linux
中proc
中pid
对应的目录文件实现在fs/proc/base.c
中,其中pid_entry
数组tgid_base_stuff[]
定义了可以访问的pid
,我们参照personality
的声明格式,定义一个handle function
, 最后我们只需要调用cat /proc/[PID]/ctx
就可以进行ctx
输出
static int proc_pid_ctx(struct seq_file*m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task){
int err = lock_trace(task);
if(!err){
seq_printf(m, "%d\n", task->ctx);
unlock_trace(task);
}
return err;
}
说明
该实验说明书写时,笔者实验环境已经被拆除,并没有进行重现,报告参考[DicardoX/SJTU_CS353_Linux_Kernel (github.com)](https://github.com/DicardoX/SJTU_CS353_Linux_Kernel)