湖南城市建设技术学院官方网站,做个兼职网站设计,wordpress建站入门,云端网站建设cookie的原理借助于unsigned long型#xff0c;和refcount_t引用计数器。
32位64位char *4字节8字节unsigned long4字节8字节
数据结构修改
首先看看实现core scheduling功能对数据结构有哪些修改
task_struct
struct task_struct{struct rb_node core_node;unsigned long…cookie的原理借助于unsigned long型和refcount_t引用计数器。
32位64位char *4字节8字节unsigned long4字节8字节
数据结构修改
首先看看实现core scheduling功能对数据结构有哪些修改
task_struct
struct task_struct{struct rb_node core_node;unsigned long core_cookie;unsigned int core_occupation;
}sched_statistics
struct sched_statistics{u64 core_forceidle_sum;
}sched_core_cookie
cookie本质就是一个内核引用计数器refcount_t成员构成的struct结构体。然后task_struct中保存的core_cookie是unsigned long型数据刚好能存放指针变量值就是存放的该结构体的内存地址。
使用alloc分配出来的sched_core_cookie结构体的address内存地址作为一个task的cookie值cookie 类型是unsigned long的指针。
/*新增*/
struct sched_core_cookie{refcount_t refcnt;
}rq
rq中增加了有关core sched的开关等信息。
struct rq {//...省略
#ifdef CONFIG_SCHED_CORE/* per rq */struct rq *core;struct task_struct *core_pick;unsigned int core_enabled;unsigned int core_sched_seq;struct rb_root core_tree; /*可以使用同一个core的都要加入红黑树*//* shared state -- careful with sched_core_cpu_deactivate() */unsigned int core_task_seq;unsigned int core_pick_seq;unsigned long core_cookie;unsigned int core_forceidle_count;unsigned int core_forceidle_seq;unsigned int core_forceidle_occupation;u64 core_forceidle_start;
#endif
}这部分初始化
#ifdef CONFIG_SCHED_CORErq-core rq;rq-core_pick NULL;rq-core_enabled 0;rq-core_tree RB_ROOT;rq-core_forceidle_count 0;rq-core_forceidle_occupation 0;rq-core_forceidle_start 0;rq-core_cookie 0UL;
#endifcfs_rq
struct cfs_rq{//...省略代码#ifdef CONFIG_SCHED_COREunsigned int forceidle_seq;u64 min_vruntime_fi;
#endif
}cookie
用户态程序通过prctl系统调用来操作相关进程的cookie动作。
prctl接口
prctl系统调用接口中新增有关PR_SCHED_CORE的操作处理函数。
SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,unsigned long, arg4, unsigned long, arg5)
{...
#ifdef CONFIG_SCHED_COREcase PR_SCHED_CORE:error sched_core_share_pid(arg2, arg3, arg4, arg5);break;
#endif
}int sched_core_share_pid(unsigned int cmd, pid_t pid, enum pid_type type,unsigned long uaddr)
{unsigned long cookie 0, id 0;struct task_struct *task, *p;struct pid *grp;int err 0;//...省略rcu_read_lock();if (pid 0) {task current; /*pid为0,则是设置进程本身*/} else {task find_task_by_vpid(pid); /*根据pid查找进程PCB*/if (!task) {rcu_read_unlock();return -ESRCH;}}get_task_struct(task); /*该函数就是为了给task_struct引用符计数1,防止中断处理中程序被kill掉访问非法PCB指针*/rcu_read_unlock();/* 检查进程是否有权限修改指定的进程* Check if this process has the right to modify the specified* process. Use the regular ptrace_may_access() checks.*/if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) {err -EPERM;goto out;}switch (cmd) {case PR_SCHED_CORE_GET: if (type ! PIDTYPE_PID || uaddr 7) {err -EINVAL;goto out;}cookie sched_core_clone_cookie(task); /*获取task任务的cookie值*/if (cookie) {/* XXX improve ? */ptr_to_hashval((void *)cookie, id);}err put_user(id, (u64 __user *)uaddr);goto out;case PR_SCHED_CORE_CREATE:cookie sched_core_alloc_cookie(); /*创建task任务的cookie值*/if (!cookie) {err -ENOMEM;goto out;}break;case PR_SCHED_CORE_SHARE_TO:cookie sched_core_clone_cookie(current); /*共享继承指定task任务的cookie值*/break;case PR_SCHED_CORE_SHARE_FROM:if (type ! PIDTYPE_PID) {err -EINVAL;goto out;}cookie sched_core_clone_cookie(task);__sched_core_set(current, cookie); /*将自身cookie共享给指定的task任务*/goto out;default:err -EINVAL;goto out;};if (type PIDTYPE_PID) {__sched_core_set(task, cookie); /*设置任务task的cookie值*/goto out;}read_lock(tasklist_lock); /*这里是对任务组进行设置对任务组中每个任务都设置cookie*/grp task_pid_type(task, type);do_each_pid_thread(grp, type, p) {if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS)) {err -EPERM;goto out_tasklist;goto out_tasklist;}} while_each_pid_thread(grp, type, p);do_each_pid_thread(grp, type, p) {__sched_core_set(p, cookie);} while_each_pid_thread(grp, type, p);
out_tasklist:read_unlock(tasklist_lock);out:sched_core_put_cookie(cookie); /*cookie指针计数器减1并检查是否为0没有人用则需要释放*/put_task_struct(task); /*检查task指针技术减1*/return err;
}该函数中out出口时为何需要对cookie进行put对task进行put
对task进行put是因为调用了get_task_struct(task)函数该函数中会对task引用计数加1所以在sched_core_share_pid()函数末尾需要对task指针引用计数减1对cookie计数减1是因为在get_cookieclone_cookieallock_cookie等函数中对cookie的引用计数加了1然后再**__sched_core_set函数中又调用get_cookie又再次对cookie的计数加了1一共加了两次所以函数末尾需要相应的对cookie计数减1并检查是否为0__sched_core_set**函数中也有一次减1操作不过是对old_cookie的操作。所以最终cookie的引用次数整体还是加了1的
创建cookie
何时需要创建cookie是每个进程都有一个cookie么cookie值保存在哪里
static unsigned long sched_core_alloc_cookie(void)
{struct sched_core_cookie *ck kmalloc(sizeof(*ck), GFP_KERNEL);if (!ck)return 0;refcount_set(ck-refcnt, 1); /*cookie的计数器加1*/sched_core_get(); /*enable core sched功能就是打开开关标志*/return (unsigned long)ck;
}获取cookie
static unsigned long sched_core_get_cookie(unsigned long cookie)
{struct sched_core_cookie *ptr (void *)cookie;if (ptr)refcount_inc(ptr-refcnt);return cookie;
}入参某个task_struct的cookie值p-core_cookie; 类型unsigned long存放的其实是指针该指针指向结构体sched_core_cookie计数器。
get_cookie的操作主要就是对cookie中的refcnt计数器加1。
共享cookie
task任务共享当前current任务的cookie
cookie sched_core_clone_cookie(current);
__sched_set_core(task, cookie);static unsigned long sched_core_clone_cookie(struct task_struct *p)
{unsigned long cookie, flags;raw_spin_lock_irqsave(p-pi_lock, flags);cookie sched_core_get_cookie(p-core_cookie); //获取指定进程的core_cookie值raw_spin_unlock_irqrestore(p-pi_lock, flags);return cookie;
}分享cookie
分享当前current任务的cookie给指定任务task。
cookie sched_core_clone_cookie(task);
__sched_core_set(current, cookie);清除cookie
static void sched_core_put_cookie(unsigned long cookie)
{struct sched_core_cookie *ptr (void *)cookie;if (ptr refcount_dec_and_test(ptr-refcnt)) {kfree(ptr);sched_core_put();}
}当清除task_struct时也要记得清除其中的cookie
#mermaid-svg-O3tZFqOl1jLc3WBZ {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-O3tZFqOl1jLc3WBZ .error-icon{fill:#552222;}#mermaid-svg-O3tZFqOl1jLc3WBZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-O3tZFqOl1jLc3WBZ .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-O3tZFqOl1jLc3WBZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-O3tZFqOl1jLc3WBZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-O3tZFqOl1jLc3WBZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-O3tZFqOl1jLc3WBZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-O3tZFqOl1jLc3WBZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-O3tZFqOl1jLc3WBZ .marker.cross{stroke:#333333;}#mermaid-svg-O3tZFqOl1jLc3WBZ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-O3tZFqOl1jLc3WBZ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-O3tZFqOl1jLc3WBZ .cluster-label text{fill:#333;}#mermaid-svg-O3tZFqOl1jLc3WBZ .cluster-label span{color:#333;}#mermaid-svg-O3tZFqOl1jLc3WBZ .label text,#mermaid-svg-O3tZFqOl1jLc3WBZ span{fill:#333;color:#333;}#mermaid-svg-O3tZFqOl1jLc3WBZ .node rect,#mermaid-svg-O3tZFqOl1jLc3WBZ .node circle,#mermaid-svg-O3tZFqOl1jLc3WBZ .node ellipse,#mermaid-svg-O3tZFqOl1jLc3WBZ .node polygon,#mermaid-svg-O3tZFqOl1jLc3WBZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-O3tZFqOl1jLc3WBZ .node .label{text-align:center;}#mermaid-svg-O3tZFqOl1jLc3WBZ .node.clickable{cursor:pointer;}#mermaid-svg-O3tZFqOl1jLc3WBZ .arrowheadPath{fill:#333333;}#mermaid-svg-O3tZFqOl1jLc3WBZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-O3tZFqOl1jLc3WBZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-O3tZFqOl1jLc3WBZ .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-O3tZFqOl1jLc3WBZ .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-O3tZFqOl1jLc3WBZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-O3tZFqOl1jLc3WBZ .cluster text{fill:#333;}#mermaid-svg-O3tZFqOl1jLc3WBZ .cluster span{color:#333;}#mermaid-svg-O3tZFqOl1jLc3WBZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-O3tZFqOl1jLc3WBZ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}put_task_struct__put_task_structsched_core_freesched_core_put_cookievoid sched_core_free(struct task_struct *p)
{sched_core_put_cookie(p-core_cookie);
}父子进程cookie关系
在fork系统调用中copy_process创建新进程的时候子进程的cookie值继承父进程的cookie值。
#mermaid-svg-QT7tlcrMO96Z0OPn {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-QT7tlcrMO96Z0OPn .error-icon{fill:#552222;}#mermaid-svg-QT7tlcrMO96Z0OPn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QT7tlcrMO96Z0OPn .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-QT7tlcrMO96Z0OPn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QT7tlcrMO96Z0OPn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QT7tlcrMO96Z0OPn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QT7tlcrMO96Z0OPn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QT7tlcrMO96Z0OPn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QT7tlcrMO96Z0OPn .marker.cross{stroke:#333333;}#mermaid-svg-QT7tlcrMO96Z0OPn svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QT7tlcrMO96Z0OPn .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-QT7tlcrMO96Z0OPn .cluster-label text{fill:#333;}#mermaid-svg-QT7tlcrMO96Z0OPn .cluster-label span{color:#333;}#mermaid-svg-QT7tlcrMO96Z0OPn .label text,#mermaid-svg-QT7tlcrMO96Z0OPn span{fill:#333;color:#333;}#mermaid-svg-QT7tlcrMO96Z0OPn .node rect,#mermaid-svg-QT7tlcrMO96Z0OPn .node circle,#mermaid-svg-QT7tlcrMO96Z0OPn .node ellipse,#mermaid-svg-QT7tlcrMO96Z0OPn .node polygon,#mermaid-svg-QT7tlcrMO96Z0OPn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QT7tlcrMO96Z0OPn .node .label{text-align:center;}#mermaid-svg-QT7tlcrMO96Z0OPn .node.clickable{cursor:pointer;}#mermaid-svg-QT7tlcrMO96Z0OPn .arrowheadPath{fill:#333333;}#mermaid-svg-QT7tlcrMO96Z0OPn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-QT7tlcrMO96Z0OPn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-QT7tlcrMO96Z0OPn .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-QT7tlcrMO96Z0OPn .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-QT7tlcrMO96Z0OPn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QT7tlcrMO96Z0OPn .cluster text{fill:#333;}#mermaid-svg-QT7tlcrMO96Z0OPn .cluster span{color:#333;}#mermaid-svg-QT7tlcrMO96Z0OPn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-QT7tlcrMO96Z0OPn :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}copy_processsched_core_forkvoid sched_core_fork(struct task_struct *p)
{RB_CLEAR_NODE(p-core_node); /*core_node红黑树节点清空*/p-core_cookie sched_core_clone_cookie(current); /*子进程cookie 父进程cookie*/
}周期性调度器
scheduler_tick()周期性调度器中也会涉及到core sched的操作。
#mermaid-svg-CHXA1kt7jfeDMbvA {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-CHXA1kt7jfeDMbvA .error-icon{fill:#552222;}#mermaid-svg-CHXA1kt7jfeDMbvA .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-CHXA1kt7jfeDMbvA .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-CHXA1kt7jfeDMbvA .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-CHXA1kt7jfeDMbvA .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-CHXA1kt7jfeDMbvA .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-CHXA1kt7jfeDMbvA .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-CHXA1kt7jfeDMbvA .marker{fill:#333333;stroke:#333333;}#mermaid-svg-CHXA1kt7jfeDMbvA .marker.cross{stroke:#333333;}#mermaid-svg-CHXA1kt7jfeDMbvA svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-CHXA1kt7jfeDMbvA .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-CHXA1kt7jfeDMbvA .cluster-label text{fill:#333;}#mermaid-svg-CHXA1kt7jfeDMbvA .cluster-label span{color:#333;}#mermaid-svg-CHXA1kt7jfeDMbvA .label text,#mermaid-svg-CHXA1kt7jfeDMbvA span{fill:#333;color:#333;}#mermaid-svg-CHXA1kt7jfeDMbvA .node rect,#mermaid-svg-CHXA1kt7jfeDMbvA .node circle,#mermaid-svg-CHXA1kt7jfeDMbvA .node ellipse,#mermaid-svg-CHXA1kt7jfeDMbvA .node polygon,#mermaid-svg-CHXA1kt7jfeDMbvA .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-CHXA1kt7jfeDMbvA .node .label{text-align:center;}#mermaid-svg-CHXA1kt7jfeDMbvA .node.clickable{cursor:pointer;}#mermaid-svg-CHXA1kt7jfeDMbvA .arrowheadPath{fill:#333333;}#mermaid-svg-CHXA1kt7jfeDMbvA .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-CHXA1kt7jfeDMbvA .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-CHXA1kt7jfeDMbvA .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-CHXA1kt7jfeDMbvA .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-CHXA1kt7jfeDMbvA .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-CHXA1kt7jfeDMbvA .cluster text{fill:#333;}#mermaid-svg-CHXA1kt7jfeDMbvA .cluster span{color:#333;}#mermaid-svg-CHXA1kt7jfeDMbvA div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-CHXA1kt7jfeDMbvA :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}scheduler_ticksched_core_tick__sched_core_tick__sched_core_account_forceidle