首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Linux进程上下文切换过程context_switch详解--Linux进程的管理与调度(二十一)

如果要将CPU分配给与当前活动进程不同的另外一个进程(即抢占),都会直接或者调用调度函数, 包括schedule或者其子函数__schedule, 其中schedule在关闭内核抢占后调用__schedule...而__schedule则执行了如下操作 **__schedule如何完成内核抢占** 完成一些必要的检查, 并设置进程状态, 处理进程所在的就绪队列 调度全局的pick_next_task选择抢占的进程...有些进程是来自各种程序、系统和应用程序的单独进程,而某些进程来自被分解为很多进程的应用或程序。当一个进程从内核中移出,另一个进程成为活动的, 这些进程之间便发生了上下文切换....”的地址空间记录在active_mm中 /* 如果next是内核线程,则线程使用prev所使用的地址空间 * schedule( )函数把该线程设置为懒惰TLB模式 * 内核线程并不拥有自己的页表集...在进程A被选中再次执行的时候, 会出现一个问题, 此时控制权即将回到A, switch_to函数返回, 内核开始执行switch_to之后的点, 此时内核栈准确的恢复到切换之前的状态, 即进程A上次被切换出去时的状态

4.5K31

进程切换内核源码分析

罗军 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 进程调度的时机 (1)进程状态转换的时刻...标记调用schedule(),此时发生了用户抢占 内核线程可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度;...switch_to代码 switch_to是通过内联汇编操作的,在调试过程中无法进入,只能进入__switch_to函数。...、__schedule、context_switch、switch_to(断点无法断下)、__switch_to 运行后单步跟踪到schedule函数,发现实际调用的是__schedule函数,接下来完成进程切换的操作...context_switch函数: ? switch_to函数: ? __switch_to函数: ?

1.3K30
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    Linux内核如何替换内核函数并调用原始函数

    首先我不会去HOOK用户态的进程的函数,因为这样意义不大,改一下重启服务会好很多。所以说,本文特指HOOK内核函数的做法。毕竟内核重新编译,重启设备代价非常大。...非常幸运,内核已经有了现成的 text_poke/text_poke_smp 函数来完成上面的事情。 同样的,针对一个堆上或者栈上分配的buffer不可执行,我们依然有办法。...函数,当内核在调用ipv4_conntrack_in的时候,将会到达这个函数。...有个非常现实的问题。在我保存原始函数的头n条指令的时候,n到底是多少呢?在本例中,显然n是5,符合如今Linux内核函数第一条指令几乎都是callq xxx的惯例。...阅码场"是专业的Linux及系统软件技术交流社区,企业和Linux人才的连接枢纽。

    3.4K20

    原 浅谈Linux进程调度过程

    进行进程调用的时机有以下几种: 中断处理过程(包括时钟中断、I/O中断、系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule(); 内核线程可以直接调用...schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度; 用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度...schedule函数进行调度时,首先选择一个新的进程来运行,然后调用context_switch进行上下文的切换,这个宏又调用switch_to进行关键上下文的切换。...是一个宏而不是一个函数,因此它的参数prev, next, last不是值拷贝,而是它的调用者context_switch()中的局部变量。...陈政/arc001    原创作品转载请注明出处  《Linux内核分析》MOOC课程

    1.7K80

    Linux进程核心调度器之主调度器schedule--Linux进程的管理与调度(十九)

    schedule(); ...... } 1.2 schedule函数 schedule就是主调度器的函数, 在内核中的许多地方, 如果要将CPU分配给与当前活动进程不同的另一个进程, 都会直接调用主调度器函数...内核抢占是Linux 2.6以后引入的一个重要的概念 我们说:如果进程正执行内核函数时,即它在内核态运行时,允许发生内核切换(被替换的进程是正执行内核函数的进程),这个内核就是抢占的。...内核为了支撑内核抢占, 提供了很多机制和结构, 必要时候开关内核抢占也是必须的, 这些函数定义在include/linux/preempt.h, L145 #define preempt_disable...内核中的进程被堵塞的时候 2 总结 2.1 schedule调度流程 schedule就是主调度器的函数, 在内核中的许多地方, 如果要将CPU分配给与当前活动进程不同的另一个进程, 都会直接调用主调度器函数...标志,则函数重新执行进行调度 */ 2.2 __schedule如何完成内核抢占 完成一些必要的检查, 并设置进程状态, 处理进程所在的就绪队列 调度全局的pick_next_task选择抢占的进程

    3.9K31

    Linux进程调度(三)

    ; \ } while (0) __switch_to 函数的具体内容这里就不看了,它里面做的最重要的一件事就是切换内核栈,将栈顶指针寄存器指向新进程的内核栈 到这里,进程的切换就已经完成了...我们前面一直强调,进程切换都是调用 schedule 函数来实现的,schedule 函数中会调用 switch_to 来进行进程切换。...,进程A就会进入睡眠,调用 schedule 函数发生进程切换,schedule 又会调用 switch_to 来真正完成进程切换,此时该进程的内核栈就变成下面这个样子 在进程A的内核栈中,在调用 schedule...函数的时候,会保存下来 tap_do_read 的返回地址,在调用 switch_to 的时候,会保存 schedule 函数的返回地址 而在调用 switch_to 后,栈顶指针就会指向新进程的内核栈...那么进程B内核栈的内容跟进程A的内核也是相似的,如下: 所以切换到进程B后,还是在 switch_to 函数中继续运行,之后函数调用返回,从栈中弹出返回地址,最后会返回到 button_do_read

    2.5K10

    Linux内核13-进程切换

    2 执行进程切换 进程切换的时机: 中断处理程序中直接调用schedule()函数,实现进程调度。 内核线程,是一个特殊的进程,只有内核态没有用户态。...所以即可以主动调用schedule()函数进行调度,也可以被中断处理程序调用。 内核态进程没法直接主动调度,因为schedule()是一个内核函数,不是系统调用。所以只能在中断处理程序进行调度。...我们将会在第7章发现,prev和next正是schedule()函数的局部变量。 2.1 switch_to宏 进程硬件上下文的切换是由宏switch_to完成的。...当进程切换涉及到3个进程的时候,3个进程分别假设为A、B、C。假设内核决定关掉A进程,激活B进程。在schedule函数中,prev指向A的描述符,而next指向B的描述符。...这个函数和普通的函数有些差别,因为__switch_to()函数从eax和edx寄存器中获取prev_p和next_p这两个参数(在分析switch_to宏的时候已经讲过),而不是像普通函数那样,从栈中获取参数

    1.9K20

    分析Linux系统的执行过程

    分析Linux系统的执行过程 一、阅读理解task_struct数据结构 二、分析fork函数对应的内核处理过程do_fork 三、使用gdb跟踪分析一个fork系统调用内核处理函数do_fork 四、...八、理解Linux系统中进程调度的时机,可以在内核代码中搜索schedule()函数,看都是哪里调用了schedule(),判断我们课程内容中的总结是否准确; 九、使用gdb跟踪分析一个schedule...八、理解Linux系统中进程调度的时机,可以在内核代码中搜索schedule()函数,看都是哪里调用了schedule(),判断我们课程内容中的总结是否准确; 中断处理过程(包括时钟中断、I/O中断、系统调用和异常...十、分析switch_to中的汇编代码,理解进程上下文的切换机制,以及与中断上下文切换的关系 函数的调用关系: schedule() --> context_switch() --> switch_to...对于进程切换的时机,中断处理以后是其中一个时机,内核线程也可以进程schedule函数的调用,来完成进程的切换。对于schedule函数。

    99020

    linux内核上下文切换解析

    linux的上下文切换就是进程线程的切换,也就是切换struct task_struct结构体,一个任务的上下文包括cpu的寄存器,内核栈等,由于1个cpu上的所有任务共享一套寄存器,所以在任务挂起的时候需要保存寄存器...但是Linux为了适用更多的cpu架构没使用处理器相关的上下文切换技术,而是大部分通过软件实现。linux上下文切换就在schedule()函数里,很多地方都会调用这个函数。...先看一段linux2.6.18版本还使用O(1)调度算法的schedule函数代码: /* * schedule() is the main scheduler function. */ asmlinkage...然后切换到next内核栈,至此prev进程就被挂起来了,把next上次被挂起的地址压栈,调用__switch_to函数,__switch_to函数返回的时候会直接跳到标号1或者ret_from_fork...从整体看流程 由schedule函数到context_switch,context_switch主要切换mm(cr3页表寄存器),寄存器,内核栈。

    1.3K31

    操作系统进程的实现---中---05

    ---- 核心级线程的两套栈,核心是内核栈… 先来回顾一下内核级线程切换的两套栈: 中断(磁盘读或者时钟中断) 调用schedule完成切换 调度算法获取下一个线程的TCB,然后调用switch_to...函数,即iret返回 reschedule函数首先将ret_from_sys_call子程序标号入栈,然后去执行具体的_schedule函数,这里是一个c函数。...---- 再来看看执行调度的具体过程,即_schedule函数执行: 通过相关调度算法,找出切换到哪个线程继续执行 switch_to完成具体切换,主要是完成对内存级线程PCB的切换 ---- switch_to...难点分析 参考: Linux0.11内核–进程的调度schedule和switch_to解析 任务状态段TSS及TSS描述符、局部描述符表LDT及LDT描述符 Linux 0.11用tss切换,但也可以...不能使用malloc分配内存,是因为malloc是用户态函数,而这里需要调用内核态分配内存的函数 linux 0.11中线程的切换,是靠tss完成的,因此这里创建内核级线程时,最重要的就是,初始化该内核级线程对应

    90760

    Linux进程调度器概述--Linux进程的管理与调度(十五)

    有时用复杂的算法求出进程当前的优先级, 但最后的结果是相同的: 每个进程都与一个值(优先级)相关联, 这个值表示把进程如何适当地分配给CPU. 在linux中, 进程的优先级是动态的....此外如何进程中如果存在实时进程, 则实时进程总是在普通进程之前被调度 3 linux调度器的演变 一开始的调度器是复杂度为O(n)的始调度算法(实际上每次会遍历所有任务,所以复杂度为O(n)), 这个算法的缺点是当内核中有很多任务时...这也是隐式的调用schedule()函数 如果内核中的任务显式的调用schedule(), 任务主动放弃CPU使用权 如果内核中的任务阻塞(这同样也会导致调用schedule()), 导致需要调用schedule...来通知内核在必要的时间由主调度函数完成真正的调度工作, 此种做法称之为延迟调度策略 4.6 主调度器schedule 主调度器 schedule就是主调度器的工作函数, 在内核中的许多地方, 如果要将CPU...分配给与当前活动进程不同的另一个进程, 都会直接调用主调度器函数schedule或者其子函数__schedule.

    3.6K20

    Linux 进程调度之schdule主调度器

    至于CFS调度算法的实现后面后专门写一篇文章,这里只要记住调度时选择一个优先级最高的任务执行 一、调度单位简介 1.1 task_struct 结构体简介 对于Linux内核来说,调度的基本单位是任务,...(); //开启内核抢占 ...... } 这里注意schedule调用__schedule函数是传入的是false参数,表示schedule函数主调度器。...而schedule函数参数固定传入的参数是false,也就是0,就是调用schedule函数就是主动发起调度,不是抢占调度,因此schedule函数称为主调度器。...()是主调度器的主要函数,__schedule在内核源码中有很多注释,如下所示: 驱使调度器并因此进入此函数的主要方法有: 1.显式阻塞:互斥、信号量、等待队列等。...sched_in()函数和 sched_out函数是内核提供给我们开发者的接口。

    1.9K20

    操作系统的那棵“树”---06

    schedule switch_to切换 接下来会怎么样? 我们的目标是什么? 时钟中断 有那么一次时钟中断 schedule+switch_to 接下来会怎么样? 我们的目标达到了吗?...又有那么一次时钟中断, 再一次schedule+switch_to 接下来会怎么样? ---- 操作系统的那棵“树” 今天从一颗 开始,我们看看如何从小树苗长成一颗苍天大树。...---- 得让CPU好好运转 如何解决上面同步等待的问题呢?...wait函数,也会进行系统调用,底层会将自己的状态设置为阻塞态,然后进行进程调度。 ---- schedule 假设此时调度算法,默认选中就绪队列中第一个元素,即切换到进程A执行。...---- schedule+switch_to 通过switch_to将当前CPU状态扣到进程A的TSS上面,然后将进程B的TSS拍到CPU上面,就完成了进程的切换。

    40840

    内核地址空间大冒险4:线程切换

    进入sleep()函数后,又来到了nano_sleep()函数,接着看到了一个syscall系统调用指令,我继续执行,来到了内核空间。...终于,我来到了一个叫schedule()的函数面前。 线程调度 进入schedule()后,迎面走来一位发须皆已花白的长者。 ?...告别了长者,我和小T踏上了这神秘的switch_to,跟随着一步一步的指令,我把自己线程上下文的寄存器都保存到了我的内核栈上面,然后将栈指针指向了小T的内核栈,最后把小T保存在他内核栈的指令地址加载进指令寄存器...我小心翼翼的执行了这里的代码,只是简单输出了一行日志,然后来到了一个叫__restore_rt()的函数,又一条syscall指令摆在了我的面前,我没有犹豫再一次一头扎进了内核空间。...不过,同样的事情接二连三的出现,经历了上次那件事的小Q不敢大意,赶紧向安全部长汇报了情况。 预知后事如何,请关注后续精彩······

    87820

    ucoreOS_lab4 实验报告

    next_safe = proc->pid; } } } return last_pid; } 练习3:阅读代码,理解 proc_run 函数和它调用的函数如何完成进程切换的...即 schedule 函数通过查找 proc_list 进程队列,在这里只能找到一个处于就绪态的 initproc 内核线程。...再分析 switch_to 函数 * 实现思路: switch_to 函数主要完成的是进程的上下文切换,先保存当前寄存器的值,然后再将下一进程的上下文信息保存到对于寄存器中。 1....的eip压入栈中 ret 最后分析一下 proc_run 函数 4、由 switch_to函数完成具体的两个线程的执行现场切换,即切换各个寄存器,当 switch_to 函数执行完“ret”指令后...由 switch_to 函数完成具体的两个线程的执行现场切换,即切换各个寄存器,当 switch_to 函数执行完 “ret” 指令后,就切换到 initproc 执行了。

    1.4K30

    进程实现原理

    problem: Linux内核是如何初始化操作系统,并开始运行第一个程序呢? ? 我们都知道,系统启动过程为:bootsect.s —>setup.s —>head.s。...init()函数中,便是用来调用linux的shell脚本程序,从而可以与用户进行交互。那么问题来了,fork是如何做到进程的创建的呢?系统如何让两个进程或多个进程并发的执行呢?...目标代码(linux/kernel/sched.c): void schedule(void){ int i,next,c; ..........switch_to(next); } ? 进入调度函数后,先忽略前述的某些优先级调度算法,直接转入switch_to函数,你会发现它是通过建立映象来完成内核栈的切换的。...将tmp.b指向的新tss的内容全部映射到寄存器中,从而完成切换。 switch_to(n)一旦完成切换,内核栈的内容便是子进程的内容了。

    1.4K40

    Linux内核24-内核同步理解

    我们首先了解一下如何向内核请求服务。然后,看一下这些请求如何实现同步。Linux内核又是采用了哪些同步技术。...2 如何请求内核服务 为了更好地理解内核是如何工作的,我们把内核比喻成一个酒吧服务员,他响应两种请求服务:一种是来自顾客,另外一种来自多个老板。...我们已经知道所有的进程切换动作都由switch_to宏完成。不论是抢占式还是非抢占式,当进程完成内核活动的某个线程并调用调度器时就会发生进程切换。...如果设置,说明需要进行进程切换,就会调用函数preempt_schedule(),其代码片段如下所示: if (!current_thread_info->preempt_count && !...内核控制路径的交错执行给内核开发者带来很大的麻烦:必须小心地在异常处理程序、中断处理程序、可延时处理函数和内核线程中确定临界区。

    1.1K20

    深入分析Linux内核源代码阅读笔记 第四章、第五章

    内核线程执行的是内核中的函数,而普通进程只有通过系统调用才能执行内核中的函数。 内核线程只运行在内核态,而普通进程既可以运行在用户态,也可以运行在内核态。...Linux 内核中提供了两个函数 down()和 up(),分别对应于操作系统教科书中的 P、V 操作。...中引入一种通用链表 list_head 第五章 进程调度与切换 本章首先讨论与时间相关的主题,然后才讨论进程的调度,最后介绍了 Linux 中进程是如何进行切换的。...用宏 switch_to()进行真正的进程切换 进程切换 为了控制进程的执行,内核必须有能力挂起正在 CPU 上运行的进程,并恢复以前挂起的某个进程的执行。...进程切换: 前面所介绍的 schedule() 中调用了 switch_to 宏,这个宏实现了进程之间的真正切换。

    85650

    深入理解Linux内核之主调度器(下)

    注:这里的上下文实际上是指进程运行时最小寄存器的集合。 如果切换的next进程不是同一个进程,才进行切换: __schedule i f (likely(prev !...于是执行到ret_from_fork:这里首先调用schedule_tail对前一个进程做清理工作,然后判断是否为内核线程如果是执行内核线程的执行函数,如果是用户任务通过ret_to_user返回到用户态...2)如果是之前已经被切换过的进程,lr为cpu_switch_to调用的下一条指令地址(这里实际上是__schedule函数中调用barrier()的指令地址)。...5.2 关于__switch_to的参数和返回值 switch_to(prev, next, prev) -> ((last) = __switch_to((prev), (next)))...总结 主调度器可以说Linux内核进程管理中的核心组件,进程管理的其他部分如抢占、唤醒、睡眠等都是围绕它来运作。

    1.3K20
    领券