lab5 lazy

news2024/11/24 11:01:03

image-20230822182107448

文章目录

  • Eliminate allocation from sbrk()
  • Lazy allocation
    • task
    • hints
    • 实现
  • Lazytests and Usertests
    • task
    • hints
    • 实现

Eliminate allocation from sbrk()

第一个任务是去阻止sysproc.c中的sys_sbrk()函数真的分配内存,只需要增p->sz即可

一行代码+注释即可

uint64
sys_sbrk(void) {
    int addr;
    int n;

    if (argint(0, &n) < 0)
        return -1;
    addr = myproc()->sz;
    myproc()->sz += n;
    // if(growproc(n) < 0)
    //   return -1;
    return addr;
}

这时候会发生两个错误

image-20230822161829120

  1. usertrap的错误
    1. 页面错误是由硬件触发的,当硬件发现pte中的有效位为0时,就会陷入内核,并且设置r_scause为页错误相关的标志
  2. uvmunmap错误
    1. 有可能一个进程申请了一块内存,但是却没有真正使用,所以页表中是没有对应的一项的
    2. 结果在之后销毁这块内存的时候,还是会去页表中删除这一项,这一删就发现, 根本没有被mapped

Lazy allocation

task

  1. 修改trap.c中的代码,使其能够对用户空间的页错误进行反应

    通过映射一个新分配的物理内存页到出错的地址,并返回到用户空间使得进程继续执行

  2. 视情况修改其他的内核代码

hints

  1. 你可以通过检查r_scause是13还是15来判断是否是一个页错误
  2. r_stval()存储了引起错误的虚拟地址
  3. uvmalloc函数学习,你需要调用kallocmappages
  4. 使用PGROUNDDOWN(va)去得到虚拟页面的地址
  5. 修改uvmunmap()使其在碰到一个页面没有被mapped时不要panic
  6. 如果内核崩了,在汇编代码中查看sepc
  7. 使用你的vmprint函数去打印页表
  8. 如果出现incomplete type proc,去includespinlock.hproc.h

实现

usertrap中增加一个else if分支,关键操作就是kalloc和mappages,即申请一个操作,再增加一个映射

    } else if (r_scause() == 13 || r_scause() == 15) {
        uint64 va = r_stval();
        // 虚拟地址本来就不合法
        if (va >= p->sz) {
            p->killed = 1;
        } else {
            uint64 pa = (uint64)kalloc();
            // 内存用完了, 杀死进程
            if (pa == 0) {
                p->killed = 1;
            } else {
                va = PGROUNDDOWN(va);
                // 增加映射,如果失败了
                if (mappages(p->pagetable, va, PGSIZE, pa, PTE_W | PTE_X | PTE_R | PTE_U) != 0) {
                    kfree((void *)pa);
                    p->killed = 1;
                }
            }
        }
    } else {
        printf("usertrap(): unexpected scause %p pid=%d\n", r_scause(), p->pid);
        printf("            sepc=%p stval=%p\n", r_sepc(), r_stval());
        p->killed = 1;
    }

uvmunmap中修改为

        if ((*pte & PTE_V) == 0)
            continue;

就成功了

image-20230822163902501

Lazytests and Usertests

task

  1. 通过lazytestsusertests

hints

  1. 处理sbrk的参数为负数的情况
  2. 如果一个进程访问的虚拟地址超过了通过sbrk分配的
  3. 正确处理fork中父进程到子进程的内存拷贝
  4. 正确处理一个进程通过系统调用read或者write传递了一个合法的虚拟地址,但是对应的内存地址却没有被分配
  5. 正确处理内存用完的限制,即kalloc如果失败,则杀死进程
  6. 处理用户堆栈下面无用的页面错误,即guardpage

一个一个hins来

实现

第1个是参数为负数,特判一下就行,如果是负数,就按原来的方式处理

    if (n > 0) {
        myproc()->sz += n;
    } else {
        if (growproc(n) < 0)
            return -1;
    }

第2个和第6个通过这个判断就可以搞定

va >= p->sz || va < p->trapframe->sp

有个之前没搞清楚的点,那就是通过p->trapframe->sp取得的是栈顶指针,栈指针又是向下走的。而栈指针往下,除了一个guardpage是没有映射之外,其他的page都应该是有映射的,即pte的有效位为0。因此,如果引发了页故障并且地址还低于栈顶指针,说明肯定是碰到了guardpage的

第3个其实说的是uvmcopy函数,这个函数就是将父进程的页表原模原样的拷贝给子进程,但是有的虚拟页面连父节点自己都没有映射,子节点哪来的映射,因此碰到找不到pte或者pte有问题的情况,直接continue就行了

        if ((pte = walk(old, i, 0)) == 0)
            continue;
        // panic("uvmcopy: pte should exist");
        if ((*pte & PTE_V) == 0)
            continue;
        // panic("uvmcopy: page not present");

第4个的问题在于,如果是系统调用,那它会先在usertrap中进入syscall的处理流程,不会进入我们新添加的流程,所以会有问题

通过对write函数的不断追踪,可以发现,牵扯到的是walkaddr函数。其实就是现在需要使用这个地址了,但是原始的walkaddr不能正确返回一个物理地址,因为压根就没有。所以在walkaddr中增加创建映射的代码即可

    if ((*pte & PTE_V) == 0) {
        struct proc *p = myproc();
        // 地址不合法
        if (va >= p->sz || va < p->trapframe->sp) {
            return 0;
        }
        uint64 pa = (uint64)kalloc();
        if (pa == 0) {
            panic("memory run out\n");
            return 0;
        }
        if (mappages(p->pagetable, va, PGSIZE, pa, PTE_W | PTE_X | PTE_R | PTE_U) != 0) {
            kfree((void *)pa);
            return 0;
        }
        // *pte = PA2PTE(pa) | PTE_W | PTE_X | PTE_R | PTE_U | PTE_V;
    }

第5点,只要你用了kalloc后判断了它的返回值,然后panic就行

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

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

相关文章

mysql between and 和 大于小于的区别

1&#xff09;表达式 between 下界值 and 上界值 ——限定"表达式"的值介于"下界值"到"上界值"之间的所有值&#xff0c;并且包含"下界值"和"上界值"&#xff1b; 2&#xff09;表达式 >下界值 and 表达式<上界值 ——…

Win11点击鼠标右键,“新建”选项消失的解决方法

更新了Win11后&#xff0c;我发现当我想在桌面新建一个文件夹、文本文档或者Word、Excel的时候&#xff0c;却没有“新建”选项&#xff0c;很是苦恼&#xff0c;只能通过文件资源管理器进行新建操作。 试了很多方法&#xff0c;终于找到个有用的。 以管理员运行cmd&#xff…

电脑怎么设置智能提醒?如何让电脑自动提醒我?

对于大多数上班族来说&#xff0c;因为日常的工作任务比较繁琐&#xff0c;且和各种琐事交织在一起&#xff0c;非常容易造成日程安排的混乱&#xff0c;这时候容易忘记各种工作任务也就是司空见惯了。为了尽可能不遗漏重要的工作任务&#xff0c;把每天的工作日程安排的井井有…

运维作业6

1.安装docker服务&#xff0c;配置镜像加速器 1&#xff09;添加docker-ce源信息 [rootserver ~]# yum install yum-utils device-mapper-persistent-data lvm2 -y [rootserver ~]# yum-config-manager --add-repo https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/cento…

# Lua与C++交互(二)———— 交互

C 调用lua 基础调用 再来温习一下 myName “beauty girl” C想要获取myName的值&#xff0c;根据规则&#xff0c;它需要把myName压入栈中&#xff0c;这样lua就能看到&#xff1b;lua从堆栈中获取myName的值&#xff0c;此时栈顶为空&#xff1b;lua拿着myName去全局表中查…

经纬恒润再次入选教育部产学研合作协同育人企业

近日&#xff0c;教育部高等教育司组织的产学合作协同育人项目组公布了2023年度产学合作协同育人项目指南通过企业名单。经纬恒润再次入选&#xff0c;此次共获批37个项目&#xff0c;其中有25个师资培训项目&#xff0c;12个实践条件建设和实践基地建设项目。 产学合作协同育人…

【C++】UDP通信,实现文件的传输

目录 1 TCP与UDP比较 2 UDP 3 通信流程 4 实践 5 运行结果 1 TCP与UDP比较 2 UDP简介 UDP通信是无连接的,因此不需要

8-模板复用

一. 模板复用方法和前置条件 1. 语法: {% block 名字 %}{% endblock %} 2. 三种方法: (1). 模板继承 * (2). include (3). 宏 3. 前置条件: (1). 多个模板具有相同的顶部和底部 (2). 多个模板具有相同的模板内容,但是内容中部分不一样 (3). 多个模板具有完全…

MAYA粒子基础_发射器和粒子碰撞

创建nParticle泛向发射器 创建nParticle方向发射器 体积发射器 创建火花 曲面发射器 曲线发射 粒子碰撞 碰撞层 碰撞 碰撞层都是0 不碰撞 白0 红1 1 0

关于ros工作空间devel下setup.bash的理解

在创建了ros的工作空间之后 在工作空间的devel文件夹中存在几个setup.*sh形式的环境变量设置脚本 使用source命令运行这些脚本文件&#xff0c;则工作空间的环境变量设置可以生效&#xff08;如可以找到该工作空间内的项目&#xff09;。 source devel/setup.bash 设置环境变量…

为什么 Redis 中的事物很玄学,没人使用 ?

1.为什么不使用 Redis 中的事物 ? Redis 中的事物是 "弱事物"&#xff0c;它在操作的时候&#xff0c;是将多个命令全部加入到事物队列中&#xff0c;然后通过 exec 命令一次性执行所有命令。这样做的好处是可以减少网络往返的次数&#xff0c;提高效率。 它的使用…

Hadoop学习一(初识大数据)

目录 一 什么是大数据&#xff1f; 二 大数据特征 三 分布式计算 四 Hadoop是什么? 五 Hadoop发展及版本 六 为什么要使用Hadoop 七 Hadoop vs. RDBMS 八 Hadoop生态圈 九 Hadoop架构 一 什么是大数据&#xff1f; 大数据是指无法在一定时间内用常规软件工具对其内…

allegro gerber导出

allegro gerber导出 1、生产钻孔数据nc_param.txt钻孔参数文件生成2、生成钻孔图形3、放置钻孔图和钻孔表4、生产钻孔文件5、路板中使用了椭圆孔、矩形或者长条形的开槽孔&#xff0c;就需要出一个铣刀数据文件&#xff0c;单独生成NC Route文件&#xff1b;6、生成叠层截面图7…

森林生物量(蓄积量)估算全流程

python森林生物量&#xff08;蓄积量&#xff09;估算全流程 一.哨兵2号获取/去云处理/提取参数1.1 影像处理与下载1.2 导入2A级产品1.3导入我们在第1步生成的云掩膜文件1.4.SNAP掩膜操作1.5采用gdal计算各类植被指数1.6 纹理特征参数提取 二.哨兵1号获取/处理/提取数据2.1 纹理…

5G NR:协议 - PDCCH信道

1、基本概念 不同于LTE中的控制信道包括PCFICH、PHICH和PDCCH&#xff0c;在5G NR中&#xff0c;控制信道仅包括PDCCH&#xff08;Physical Downlink Control Channel&#xff09;&#xff0c;负责物理层各种关键控制信息的传递&#xff0c;PDCCH中传递的下行控制信息&#xff…

rainbond云原生应用管理平台部署

rainbond简介 rainbond 是 一个 开源的Kubernetes 云原生应用管理平台。 Rainbond 核心100%开源&#xff0c;Serverless体验&#xff0c;不需要懂K8s也能轻松管理容器化应用&#xff0c;平滑无缝过渡到K8s&#xff0c;是国内首个支持国产化信创、适合私有部署的一体化应用管理…

股票开户哪个券商进行炒股佣金最低手续费最低?万1融5!

股票交易的手续费最低金额取决于券商、地区、交易所以及具体的交易类型等因素。不同券商和地区的手续费政策会有所不同&#xff0c;因此无法给出一个通用的最低手续费金额。 一些券商可能会提供特定的交易活动或优惠&#xff0c;例如首次交易免费、低交易费等。此外&#xff0…

linux设备驱动模型:设备树

设备树诞生背景&#xff1a;硬件设备中种类逐年递增&#xff0c;板级platform平台设备文件越来越多。 设备树由根节点开始&#xff0c;可以包含若干个子节点&#xff1b;每个子节点又可以包含若干个子节点。 DTS&#xff08;device tree source&#xff09;&#xff1a;设备树…

人力资源管理难?看看这些大厂是怎么做的!附数据分析模板

组织管理的质量是影响企业运作效率的重要因素之一。今天&#xff0c;本文分享帆软自己是如何用简道云搭建HR系统的。 Tips&#xff1a;本文中的“同学”&#xff0c;是对帆软员工的称呼。本文由帆软人事同学提供。 最初&#xff0c;在帆软的快速成长期&#xff0c;公司聚焦发展…

景区气象站丨它的结构与功能是什么样的?

景区气象站是由传感器、数据采集系统、LED显示屏、供电系统、立杆和监控主机组成&#xff0c;能够同时监测大气温度、湿度、大气压、风速、风向、pm2.5 /pm10、二氧化碳、光照强度等气象参数&#xff0c;并将这些气象参数上传至环境监控平台&#xff0c;具有数据传输快、无需布…