九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
【原創(chuàng)】(三)Linux進程調(diào)度器-進程切換

背景

  • Read the fucking source code! --By 魯迅
  • A picture is worth a thousand words. --By 高爾基

說明:

  1. Kernel版本:4.14
  2. ARM64處理器,Contex-A53,雙核
  3. 使用工具:Source Insight 3.5, Visio

1. 概述

進程切換:內(nèi)核將CPU上正在運行的進程掛起,選擇下一個進程來運行。
ARM架構(gòu)中,CPU上一次只能運行一個任務(wù),內(nèi)核需要為任務(wù)分配運行時間來進行調(diào)度,以便同時能處理多個任務(wù)請求。
如下圖所示:

當進行任務(wù)切換的時候,思考下兩個問題:

  1. 怎樣通過搶占來實現(xiàn)進程的切換?
  2. 當進程切換的時候,到底切換的什么,是怎么實現(xiàn)的?

這兩個問題,也是本文探討的主題了。

2. 搶占

2.1 用戶搶占

2.1.1 搶占觸發(fā)點

  • 可以觸發(fā)搶占的情況很多,比如進程的時間片耗盡、進程等待在某些資源上被喚醒時、進程優(yōu)先級改變等。Linux內(nèi)核是通過設(shè)置TIF_NEED_RESCHED標志來對進程進行標記的,設(shè)置該位則表明需要進行調(diào)度切換,而實際的切換將在搶占執(zhí)行點來完成。

不看代碼來講結(jié)論,那都是耍流氓。先看一下兩個關(guān)鍵結(jié)構(gòu)體:struct task_structstruct thread_info。我們在前邊的文章中也講過struct task_struct用于描述任務(wù),該結(jié)構(gòu)體的首個字段放置的正是struct thread_info,struct thread_info結(jié)構(gòu)體中flag字段就可用于設(shè)置TIF_NEED_RESCHED,此外該結(jié)構(gòu)體中的preempt_count也與搶占相關(guān)。

struct task_struct {#ifdef CONFIG_THREAD_INFO_IN_TASK/* * For reasons of header soup (see current_thread_info()), this * must be the first element of task_struct. */struct thread_infothread_info;#endif        ...}/* * low level task data that entry.S needs immediate access to. */struct thread_info {unsigned longflags;/* low level flags */mm_segment_taddr_limit;/* address limit */#ifdef CONFIG_ARM64_SW_TTBR0_PANu64ttbr0;/* saved TTBR0_EL1 */#endifintpreempt_count;/* 0 => preemptable, <0 => bug */};#include <asm/current.h>#define current_thread_info() ((struct thread_info *)current)   //通過該宏可以直接獲取thread_info的信息#endif

看看具體哪些函數(shù)過程中,設(shè)置了TIF_NEED_RESCHED標志吧:

  • 內(nèi)核提供了set_tsk_need_resched函數(shù)來將thread_infoflag字段設(shè)置成TIF_NEED_RESCHED;
  • 設(shè)置了TIF_NEED_RESCHED標志,表明需要發(fā)生搶占調(diào)度;

2.1.2 搶占執(zhí)行點

用戶搶占:搶占執(zhí)行發(fā)生在進程處于用戶態(tài)。
搶占的執(zhí)行,最明顯的標志就是調(diào)用了schedule()函數(shù),來完成任務(wù)的切換。
具體來說,在用戶態(tài)執(zhí)行搶占在以下幾種情況:

  • 異常處理后返回到用戶態(tài);
  • 中斷處理后返回到用戶態(tài);
  • 系統(tǒng)調(diào)用后返回到用戶態(tài);

如下圖:

  • ARMv8有4個Exception Level,其中用戶程序運行在EL0,OS運行在EL1,Hypervisor運行在EL2,Secure monitor運行在EL3;
  • 用戶程序在執(zhí)行過程中,遇到異常或中斷后,將會跳到ENTRY(vectors)向量表處開始執(zhí)行;
  • 返回用戶空間時進行標志位判斷,設(shè)置了TIF_NEED_RESCHED則需要進行調(diào)度切換,沒有設(shè)置該標志,則檢查是否有收到信號,有信號未處理的話,還需要進行信號的處理操作;

2.2 內(nèi)核搶占

Linux內(nèi)核有三種內(nèi)核搶占模型,先上圖:

  • CONFIG_PREEMPT_NONE:不支持搶占,中斷退出后,需要等到低優(yōu)先級任務(wù)主動讓出CPU才發(fā)生搶占切換;
  • CONFIG_PREEMPT_VOLUNTARY:自愿搶占,代碼中增加搶占點,在中斷退出后遇到搶占點時進行搶占切換;
  • CONFIG_PREEMPT:搶占,當中斷退出后,如果遇到了更高優(yōu)先級的任務(wù),立即進行任務(wù)搶占;

2.2.1 搶占觸發(fā)點

  • 在內(nèi)核中搶占觸發(fā)點,也是設(shè)置struct thread_infoflag字段,設(shè)置TIF_NEED_RESCHED表明需要請求重新調(diào)度。
  • 搶占觸發(fā)點的幾種情況,在用戶搶占中已經(jīng)分析過,不管是用戶搶占還是內(nèi)核搶占,觸發(fā)點都是一致的;

2.2.2 搶占執(zhí)行點

內(nèi)核搶占:搶占執(zhí)行發(fā)生在進程處于內(nèi)核態(tài)。

總體而言,內(nèi)核搶占執(zhí)行點可以歸屬于兩大類:

  • 中斷執(zhí)行完畢后進行搶占調(diào)度;
  • 主動調(diào)用preemp_enableschedule等接口的地方進行搶占調(diào)度;

2.3 preempt_count

  • Linux內(nèi)核中使用struct thread_info中的preempt_count字段來控制搶占。
  • preempt_count的低8位用于控制搶占,當大于0時表示不可搶占,等于0表示可搶占。
  • preempt_enable()會將preempt_count值減1,并判斷是否需要進行調(diào)度,在條件滿足時進行切換;
  • preempt_disable()會將preempt_count值加1;

此外,preemt_count字段還用于判斷進程處于各類上下文以及開關(guān)控制等,如圖:

3. 上下文切換

  • 進程上下文:包含CPU的所有寄存器值、進程的運行狀態(tài)、堆棧中的內(nèi)容等,相當于進程某一時刻的快照,包含了所有的軟硬件信息;
  • 進程切換時,完成的就是上下文的切換,進程上下文的信息會保存在每個struct task_struct結(jié)構(gòu)體中,以便在切換時能完成恢復(fù)工作;

進程上下文切換的入口就是__schedule(),分析也圍繞這函數(shù)展開。

3.1 __schedule()

__schedule()函數(shù)調(diào)用分析如下:

主要的邏輯:

  • 根據(jù)CPU獲取運行隊列,進而得到運行隊列當前的task,也就是切換前的prev;
  • 根據(jù)prev的狀態(tài)進行處理,比如pending信號的處理等,如果該任務(wù)是一個worker線程還需要將其睡眠,并喚醒同CPU上的另一個worker線程;
  • 根據(jù)調(diào)度類來選擇需要切換過去的下一個task,也就是next;
  • context_switch完成進程的切換;

3.2 context_switch()

context_switch()的調(diào)用分析如下:

核心的邏輯有兩部分:

  • 進程的地址空間切換:切換的時候要判斷切入的進程是否為內(nèi)核線程,1)所有的用戶進程都共用一個內(nèi)核地址空間,而擁有不同的用戶地址空間;2)內(nèi)核線程本身沒有用戶地址空間。在進程在切換的過程中就需要對這些因素來考慮,涉及到頁表的切換,以及cache/tlb的刷新等操作。
  • 寄存器的切換:包括CPU的通用寄存器切換、浮點寄存器切換,以及ARM處理器相關(guān)的其他一些寄存器的切換;

進程的切換,帶來的開銷不僅是頁表切換和硬件上下文的切換,還包含了Cache/TLB刷新后帶來的miss的開銷。在實際的開發(fā)中,也需要去評估新增進程帶來的調(diào)度開銷。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Linux內(nèi)核搶占機制(preempt)
內(nèi)核搶占
內(nèi)核同步spin_lock
談?wù)勥M程上下文、中斷上下文及原子上下文的一些概念
進程切換分析(3):同步處理
內(nèi)核隨記(二)
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服