xv6实验课程--xv6的写时复制fork(2023)

news2024/11/26 18:37:21

7. xv6实验课程--xv6的写时拷贝(COW)(2021)

7. xv6实验课程--xv6懒惰分页分配(lazy)(2020)

本文来源:

https://mp.weixin.qq.com/s/XJkhjrlP232ZDsRyXd0oHQ

已完成的实验代码可以从下列网站获取:

git clone https://gitee.com/lhwhit1966/xv6-labs-2023.git

注:在2020年秋季课程中有一个懒惰分页分配的实验(Lab:  xv6 lazy page allocation),在2021年秋季课程中没有这个实验,想了解该实验的读者可以阅读本公众号中的文章:xv6实验课程--xv6懒惰分配

虚拟内存提供了一个间接层(a level of indirection):内核可以通过将PTE标记为无效或只读来拦截内存引用,从而导致页面错误,并可以通过修改PTE来更改地址的含义。在计算机系统中有一种说法,任何系统问题都可以使用间接层来解决。本实验探索了一个例子:写时复制fork。

开始实验,请切换到cow分支:

$git fetch

$git checkout cow

$make clean

建议按以下方法操作。

删除xv6-labs-2023目录,然后

$ git clone git://g.csail.mit.edu/xv6-labs-2023

$ cd xv6-labs-2023

$ git checkout  cow

注:写时复制(copy-on-write,COW)这个想法至少可以回溯到TENEX操作系统[1],它很简单:如果操作系统需要将一个页面从一个地址空间复制到另一个地址空间,不是实际复制它,而是将其映射到目标地址空间,并在两个地址空间中将其标记为只读。如果两个地址空间都只读页面,则不会采取进一步的操作,因此操作系统已经实现了快速复制而不实际移动任何数据。但是,如果其中一个地址空间确实尝试写入页面,就会陷入操作系统。操作系统会注意到该页面是一个COW 页面,因此(懒惰地)分配一个新页,用数据填充该页,并将该新页映射到出错进程的地址空间。该过程随后继续,现在有了自己的页面私有副本。

COW之所以有用是有很多原因的。当然,任何类型的共享库都可以在写入时复制映射到许多进程的地址空间,从而节省宝贵的内存空间。在UNIX系统中,由于fork()和exec()的语义,COW 更加关键。fork()会创建调用者地址空间的精确副本。对于大的地址空间,这样的复制过程很慢,并且是数据密集的。更糟糕的是,大部分地址空间会被随后的exec()调用立即覆盖,它用即将执行的程序覆盖调用进程的地址空间。通过改为执行写操作时才进行复制的fork(),操作系统避免了大量不必要的复制,这不但保留了正确的语义,还提高了系统的性能。

问题

xv6中的fork()系统调用将父进程的所有用户空间存储的内容复制到子进程中。如果父进程的用户空间很大,复制可能需要很长时间。更糟糕的是,这项工作的大部分往往被浪费了,例如,fork()后的子进程紧接着执行exec()函数,这将导致子进程丢弃复制的内容,也就是说,这些复制的内容根本就没有被用到。另一方面,当父进程和子进程使用同一个页面时,若其中的一个或两个进程要对页面进行写操作,此时确实需要一个副本。

解决方案

本实验的目标是推迟由fork()创建的子进程分配和复制物理内存页,直到实际需要时才复制(如果需要的话)。

COW fork()只为子进程创建一个页表,用户内存的PTE指向父进程的物理页。COW fork()将父子进程中的所有用户PTE标记为不可写。当父子进程中的任一个试图写入其中一个COW页时,将强制CPU执行页错误。内核页错误处理程序检测到这种情况,为出错进程分配一页物理内存,将原始页复制到新页中,并修改出错进程中的相关PTE以引用新页,并标记父子进程相应的PTE对应的页为可写。当页面错误处理程序返回时,用户进程将能够写入其页面副本。

COW fork()使得释放用户内存的物理页变得有点复杂。给定的物理页可以由多个进程的页表引用,并且只有在最后一个引用去除时才能释放。在像xv6这样的简单内核中,其日志相当简单,但是在实际产品的内核中,做到正确通常是很难的,参看文章Patching until the COWs come home[7]

实验:实现写时复制(难度:困难)

任务:在xv6内核中实现写时复制fork。如果修改后的内核能同时通过cowtest和"usertests -q"的测试,那就算完成任务了。

为了帮助你测试,我们提供了一个名为cowtest的xv6程序(user/cowtest.c)。cowtest进行各种测试,但在未修改的xv6上,即使是第一个测试也会失败。因此,最初,你将看到:

$cowtest

simple: fork() failed

$

“简单”测试分配了一半以上的可用物理内存,然后fork()。fork失败,因为没有足够的空闲物理内存,无法为子进程提供父进程内存的完整副本。

当你完成任务后,内核应该通过cowtest和usertest -q中的所有测试。即:

图片

一个合理的实验步骤如下:

1. 修改uvmcopy()将父进程的物理页映射到子进程的物理页,而不是分配新页面。清除父子进程PTE的PTE_W位。

2. 修改usertrap()以识别页面错误。当COW页面出现页面错误时,使用kalloc()分配一个新页面,将旧页面复制到新页面,然后将新页面设置到PTE中并设置PTE_W位。原本是只读的页面(没有映射PTE_W,像文本段中的页面)应该保持只读并在父和子之间共享,试图写这样一个页面的进程应该被杀死。

3. 确保每个物理页在最后一个对它的PTE引用移除时被释放。一个好的解决方案是设置一个“引用计数器”,记录每个物理页被引用的用户页表数。当kalloc()分配页时,将页的引用计数器设置为1。当fork导致子进程共享页时,增加页的引用计数,每当任何进程从其页表中删除页时,减少页的计数。kfree()只应在引用计数为零时将页放回空闲列表。可以将这些计数器保存在一个固定大小的整数数组中。你必须制定一个如何索引数组以及如何选择数组大小的方案。例如,可以用页面的物理地址除以4096作为数组的索引,并为数组提供若干元素,这些元素等于kalloc.c中的kinit()放置在空闲列表中的任意页面的最高物理地址。你可以随意修改kalloc.c(例如,kalloc()和kfree())来维护引用计数。

4. 修改copyout(),使其在遇到COW页面时使用与页面错误相同的方案。

提示

● 有一种方法可以记录每个PTE是否是COW映射,这可能很有用。你可以使用RISC-V PTE中的RSW位(保留给软件使用)来实现此目的。

● usertests -q探索了cowtest无法测试的场景,所以不要忘记检查所有测试是否都通过了这两个测试。

● kernel/riscv.h的末尾有一些有用的宏和页表标志的定义。

● 如果出现COW页错误并且没有可用内存,则应终止进程。

实验步骤

准备步骤:(1)在kernel/kalloc.c中kmem结构中增加物理内存引用计数器char ref_count[],并对该计数器定义互斥锁struct spinlock reflock,在freerange函数中对其进行初始化。

kinit函数用来初始化内存分配器。对系统中的每个物理页面以链表的形式进行管理,空闲链表保存了内核和PHYSTOP之间的每个物理页面。初始化kmem.ref_count如下。

图片

图片

问:为什么在初始化时设置引用计数器为1?提示:在freerange函数中调用了kfree(p), kfree(p)会减去1。

(2)修改kerbel/kalloc函数,使其在分配页面时将引用计数器设置为1。

图片

(3)修改kernel/kfree函数,释放内存时查看引用计数是否为0,若是则释放内存,否则返回,由其他进程继续使用。

图片

(4)增加一些辅助函数(kernel/kalloc.c)。

图片

注意,要在defs.h中说明这些函数的原型。

图片

(5)增加COW标志位。

在页表项中预留了2位给操作系统,这里用第8位,即#define PTE_COW (1L << 8))

图片

kernel/riscv.h

图片

步骤1:修改uvmcopy()。对fork函数进行修改,使其不对地址空间进行复制。fork函数会调用kernel/vm.c里的uvmcopy进行复制,因此只需要修改uvmcopy函数即可:删去uvmcopy中的kalloc函数,将子进程页表映射到父进程的物理地址,清除父子进程PTE的PTE_W位,增加COW标志位,增加物理内存引用计数。

图片

步骤2:在usertrap函数(kernel/trap.c)中增加页面错误的处理,需判断是否是COW。这里只需要处理scause==15的情况,因为13是页面读错误,而COW是不会引起读错误的。

在这段程序数中先判断COW标志位,当该页面是COW页面时,就可以根据引用计数来进行处理。如果计数大于1,那么就需要通过kalloc申请一个新页面,然后复制内容,之后对该页面进行映射,映射的时候清除COW标志位,设置PTE_W标志位;而如果引用计数等于1,那么就不需要申请新页面,只需要对这个页面的标志位进行修改就可以了。

注:r_stval() 返回寄存器 staval 的值, 该寄存器存放引起缺页的虚拟地址。

图片

70判断是否超出进程的地址空间,74行判断虚拟地址是否小于PGSIZE,因为在用户进程空间中,低地址端存放的是代码,此处不可修改。注:用户代码段占用多少页,如何判断?没有相关资料,但最低端的一页肯定会占用。

图片

函数cowhandler()实现COW页处理。

图片

注:如果把256行换成ksubref(),在测试时提示FAILED -- lost some free pages 31943 (out of 31944),看来不能替换。

步骤3:最后在copyout(kernel/vm.c)中也要增加页面错误处理,因为copyout是在内核中调用的,缺页不会进入usertrap。

某些系统调用会往COW页上写数据,因为COW页的PTE_W没有设置,就会引发缺页错误。在trap.c中规定了如果异常是从系统调用发生的,就会直接 panic。所以在copyout()的时候,如果发现了当前页是COW 页,就直接给他分配一个新的页。

图片

图片

在mappages函数中会触发一个remap的panic,注释掉这条语句即可,因为COW就是要对页面进行重新映射的。

图片

测试:

图片

图片

现在运行make grade,看能得多少分。

图片

参考文献:

[1]Bobrow D G, Burchfiel J D, Murphy D L, et al. TENEX, a paged time sharing system for the PDP-10[J]. Communications of the ACM, 1972, 15(3): 135-143.

[2]https://pdos.csail.mit.edu/6.1810/2023/labs/cow.html

[3]https://blog.csdn.net/pige666/article/details/108741723

[4]https://www.cnblogs.com/weijunji/p/xv6-study-9.html

[5]https://blog.csdn.net/u013577996/article/details/111972075

[6]https://blog.csdn.net/weixin_44465434/article/details/111566139

[7]https://lwn.net/Articles/849638/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1175715.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C语言基础教程】函数指针与指针大小

文章目录 前言一、函数指针1.1 函数指针的概念1.2 三个示例代码示例1: 使用函数指针调用不同的函数示例 2: 使用函数指针实现回调函数示例 3: 使用函数指针数组 二、指针的大小2.1 前述2.2 指针大小如何决定&#xff1f;两方面理解 总结 前言 在C语言中&#xff0c;指针是一项…

腾讯云香港服务器购买多少钱一年?288元

香港云服务器可以选择腾讯云香港地域的轻量应用服务器&#xff0c;轻量2核2G配置、20M峰值带宽、40G SSD系统盘&#xff0c;优惠价格24元一个月&#xff0c;Linux系统是288元一年&#xff0c;Windows系统是360元一年&#xff0c;腾讯云百科txybk.com分享腾讯云香港轻量应用服务…

Android打造一个高性能无限层级显示的树形控件(Android树形控件)

Android使用ListView实现一个高性能无限层级显示的树形控件&#xff1a; 最近公司的Android项目里有一个地方需要选择某公司的所有部门&#xff0c;因为手机屏幕有限所以并不能像网页那样显示树状结构&#xff0c;但是如果只是用列表依次显示所有的部门又会让用户很难找到想要…

Weblogic ssrf漏洞复现

文章目录 一、漏洞描述二、漏洞特征1.查看uddiexplorer应用2.漏洞点 三、漏洞复现1.获取容器内网ip2.VULHUB Weblogic SSRF漏洞 docker中 centos6 无法启动的解决办法3.准备payload4.反弹shell 一、漏洞描述 SSRF 服务端请求伪造(Server-Side Request Forgery),是一种由攻击者…

想要制作一本简单的电子画册,应该怎么做?

随着移动互联网的快速发展&#xff0c;越来越多人开始想要制作电子画册并利用电子画册实现营销宣传。0基础如何制作电子画册&#xff0c;教你一个简单制作的方法。 利用FLBOOK在线电子画册制作平台就可轻松制作&#xff0c;比PPT更简单&#xff0c;迅速上手使用。下面是详细的制…

2023年app拉新地推接单平台有哪些?十大地推团队接单平台必备

地推和网推拉新行业在步入2023年以后&#xff0c;有了长足的进步&#xff0c;因此也有很多互联网团队开始转型从事地推app拉新和网推app拉新作业。那么对于地推团队和网推团队而言&#xff0c;应该去哪里接单&#xff1f;换言之&#xff0c;2023年地推团队和网推团队的接单平台…

岩土工程公路隧道监测中智能振弦传感器的应用方案

岩土工程公路隧道监测中智能振弦传感器的应用方案 隧道建设是现代城市发展中不可或缺的一部分。但隧道工程建设与维护过程中需要考虑诸多风险。地质环境复杂&#xff0c;地下水位、地震等因素可能导致隧道构造物的沉降、变形等问题。为此&#xff0c;在隧道建设和运营过程中&a…

钉钉企业微应用开发C#+VUE

钉钉相信很多人都用过或听过&#xff0c;企业OA审批&#xff0c;考勤&#xff0c;沟通方方面面都支持。但是有的需求自定义表单的无法满足&#xff0c;例如带有业务特性的数据来源&#xff0c;可能是内部其他系统&#xff0c;以及数据筛选分析没有那么方便&#xff0c;钉钉官方…

精品小站

今天分享几个精品小站&#xff0c;换换心情&#xff0c;您的在看、转发、点赞 就是对tuonioooo最大的支持&#xff01; xodo在线PDF工具 网址&#xff1a;https://xodo.com/ 一个国外的网站提供免费的PDF转换、在线阅读、编辑和多人协作工具。这个网站支持对PDF进行编辑&…

08 叉积的标准介绍

叉积的标准介绍 基本概念几何解释 这是关于3Blue1Brown "线性代数的本质"的学习笔记。 基本概念 向量 v ⃗ \vec{v} v 叉乘向量 w ⃗ \vec{w} w 的结果大小是这两个向量围成的平行四边形的面积&#xff0c;方向由右手定则确定。 v ⃗ w ⃗ \vec{v}\vec{w} v w - …

爱德华的台灯真的好用?爱德华、书客、好视力护眼台灯对比测评

如今孩子近视的比例越来越大&#xff0c;而且时间越来越提前&#xff0c;一些上小学的孩子开始近视佩戴眼镜。其实造成近视的原因不外乎作业坐姿不标准&#xff0c;学业时间太长缺少户外的运动&#xff0c;也包括可能灯光光源的问题造成对于视力的影响。如果希望孩子有一个较好…

awk精确筛选

awk精确筛选: $(><):用于对比数值 $n~"字符串"代表第n个字段包括某个字符 $n!~"字符串"代表第n个字段不包括某个字符 $n"字符串"代表第n个字段为某个字符 $n!"字符串"代表第n个字段不为某个字符 $NF:最后一个字段 awk -F…

Linux文件系统(操作系统的文件管理)

文章目录 一.内存中的文件管理(文件与进程)二 .Linux系统视角下的计算机外设三.磁盘上的文件管理 参考Linux内核源码版本------linux-2.4.3 一.内存中的文件管理(文件与进程) 操作系统之下,进程是计算机系统执行计算任务的基本单位,进程访问文件执行数据读写之前,操作系统会从…

C++ 代码实例:并查集简单创建工具

文章目录 前言代码仓库代码说明main.cppMakefile 结果总结参考资料作者的话 前言 C 代码实例&#xff1a;并查集简单创建工具。 代码仓库 yezhening/Programming-examples: 编程实例 (github.com)Programming-examples: 编程实例 (gitee.com) 代码 说明 简单地创建并查集注…

MATLAB - Gazebo 联合仿真 —— 使用 UR10 机械臂检测和采摘水果

系列文章目录 文章目录 系列文章目录前言一、设置 Gazebo 仿真环境二、在 Gazebo 中模拟和控制机器人2.1 概述2.2 任务调度器2.3 感知和目标生成系统2.4 运动规划2.5 机械臂和关节控制系统 三、分配用于控制机器人的参数3.1 定义机器人模型和运动规划参数&#xff0c;3.2 定义机…

基于野马算法的无人机航迹规划-附代码

基于野马算法的无人机航迹规划 文章目录 基于野马算法的无人机航迹规划1.野马搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用野马算法来优化无人机航迹规划。 1.野马搜索算法 …

基于向量加权平均算法的无人机航迹规划-附代码

基于向量加权平均算法的无人机航迹规划 文章目录 基于向量加权平均算法的无人机航迹规划1.向量加权平均搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用向量加权平均算法来优化无…

CSS 滚动捕获 Scroll Snap

CSS 滚动捕获 Scroll Snap CSS 滚动捕获允许开发者通过声明一些位置(或叫作捕获位置)来创建精准控制的滚动体验. 通常来说轮播图就是这种体验的例子, 在轮播图中, 用户只能停在图 A 或者图 B, 而不能停在 A 和 B 的中间. 比如平时用淘宝或小红书, 当你上滑到下一个推荐内容时…

分享90个节日庆典PPT,总有一款适合您

分享90个节日庆典PPT&#xff0c;总有一款适合您 PPT下载链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整理更不易。知识付费甚欢喜&#xff0c;为咱码农谋福利…

浅析C/C++的内存分段

这部分是计算机系统相关的知识&#xff0c;碍于本人才疏学浅&#xff0c;如本文存在疏漏或者错误&#xff0c;还望大佬能帮忙指出&#xff0c;感激不尽。 内存分段 从狭义上讲内存的分段可以分为堆、栈、数据段以及代码段&#xff08;内存映射区比较复杂&#xff0c;暂不涉及…