BUAA OS 2025 SWAP 挑战性任务 总结

希望能帮到一些人

前言

这个任务和其他的任务相比,是比较简单的,对于lab6的涉及主要是处理权限位和处理duppage,如果最初的设计架构很好的化,唯一要注意的就是对于swap_out出去的page,我们也要duppage。剩下的内容主要在于lab2的内存管理部分。

更新后的指导书,已经把要考虑的大部分东西都提出了,对于其他的一些问题页给了暗示,至于指导书没有提到的要注意的问题,只要打印出详细的日志然后进行分析,也可以注意到。

作者水平有限,本文充满主观臆断,欢迎在评论区讨论

对于指导书的分析

最重要的一句

以下内容所指的页面为syscall_mem_alloc分配的页面

这意味着什么呢?意味着我们要用某种方式把这种页面和其他的页面区分开,比如使用新的权限位。

数据结构

按照指导书添加数据结构是没有问题的。至于如何维护两个list,完全可以直接使用原来的pp_link

page_swapblock_map其实意义不大,主要作为磁盘是否被使用的标记数组存在。因为注意事项已经明确告诉我们了

事实上只需要维护换出物理页向磁盘块的单向映射关系,一种实现方法是当swap out时,将对应磁盘块编号代替该换出页对应的所有页表项中的物理页号部分,并利用页表项标记为换出页以便访问时能够识别出为换出页从而进行swap in。
而考虑磁盘号的唯一性,可以让page_state_set的下标就是磁盘号。

schedule刷新TLB

这个很好处理,在schedule加入flush_all_tlb就可以。

新增TLB重填逻辑

可以按照指导书来实现,也可以自己发明/借鉴一些其他的实现,只要保证你的实现不会导致效率极低TLE即可。

维护Page结构体状态

很直白的链表操作,至于什么时候是分配和取消映射,后面会进行讲解。

实现swap_out

按照指导书的流程进行是没有问题的。
在修改页表项的时候,一定要注意在合适的时候以合适的方式刷新tlb,也要注意以合适的方式保存权限位。否则会出现权限位丢失,pte未更新等bug,而这个bug在fork中将会狠狠地体现出来。
如何标记为换出页面呢?当然是新的权限位。

至于作为page_alloc的结果并执行剩余流程,一种理解方式为把swap_out的页面放到free_page_list里然后继续进行page_alloc,毕竟触发的原因就是page_alloc找不到空页面。

实现swap_in

实际上_do_tlb_miss中肯定是要执行swap_in的,但是也有其他的地方需要执行swap_in,因为有的地方发现PTE_V为0就直接失败,但实际上可能只是换出去了,swap_in进来即可。

实现替换算法

可以按照指导书来实现,也可以自己发明/借鉴一些其他的实现,只要保证你的实现不会导致效率极低TLE即可。

实现shrink_active_list

可以按照指导书来实现,也可以自己发明/借鉴一些其他的实现,只要保证你的实现不会导致效率极低TLE即可。

定期更新inactive_list

可以按照指导书来实现,也可以自己发明/借鉴一些其他的实现,只要保证你的实现不会导致效率极低TLE即可。

分析到这里,你会注意到和链表有关的操作只要合理即可,当然,指导书肯定是一种合理的写法。
在什么时候插入,什么时候删除,合理即可,也可能正是因为如此,指导书没有细写。

注意事项

由于MIPS使用软件处理TLB,当修改页表项时需要密切注意TLB的管理。

如果遇到和页表项有关的问题,一定要检查是不是没有在修改之后及时的刷新tlb,或者尝试在可疑的地方刷新tlb

MOS内核中处理页面映射的代码路径主要包括page_insert与page_remove,分别表示添加映射关系与减少映射关系,对应的页可能在或不在内存中,需要分别并准确地追踪页面的使用情况。

这就是我们提到的,其他可能需要swap_in的地方之一,这些地方也要注意对pte链表的管理和对于active_list的管理,如果你的实现比较奇怪的话,也许page_loopup也要注意?

PIIX4 简介

这个把之前的磁盘关系换一下常量即可。

SWAP挑战性任务内容汇总

助教这里的提示很有用

MIPS TLB采用奇偶页设计,当访问奇页或偶页时,会同时填充剩余的一页对应的TLB。为了实现通过TLB对页面访问进行检测,一种做法是在TLB填充时同时尝试处理奇页和偶页,判断是否换出并根据页面标志位进行访问信息的更新。

如果不处理,很可能导致list的维护出现bug,只要进行同样的操作即可,吗?

QEMU中使用的 MIPS R4K Malta TLB大小为128,因此通过以下代码可以刷新所有TLB;且一旦有更新PTE的行为,请密切注意对应TLB项的刷新:

void flush_all_tlb(void) {
    uint32_t tlb_size = 128;
    uint32_t index;

    uint32_t sr;
    __asm__ volatile("mfc0 %0, $12" : "=r"(sr));
    __asm__ volatile("mtc0 $0, $12");

    for (index = 0; index < tlb_size; index++) {
        __asm__ volatile("mtc0 $0, $10\n\t"
                 "mtc0 $0, $2\n\t"
                 "mtc0 $0, $3\n\t"
                 "mtc0 %0, $0\n\t"
                 "tlbwi\n\t"
                 :
                 : "r"(index));
    }

    __asm__ volatile("mtc0 %0, $12" : : "r"(sr));
}

抄就完了。

评测初始化分支时给定了测试环境:SWAP文件大小为64MB,内存大小为64MB,评测内容已在评测说明中给出。

实际上用不完64MB,不过不要定义太大的静态数组,我使用了三个160000的struct数组。

实现SWAP需要考虑规定哪些页面能够被换入换出,对于一些特殊的页面,内核会以内核虚拟地址访问,这时候是不会经过TLB重填的,因此如果这些页面被换出,在内核中不经检查就会访问出错误的内容。

正如前面所提到的,使用权限位解决。

页面结构体中需要存储映射该页面的页表项,一种方法是使用链表进行存储,对应的链表节点不妨利用内核保留使用的页面进行划分,节点中存放对应页表项地址以便后续直接进行修改。

定义静态数组即可

内核中主要通过page_insert与page_remove处理页表项,使用的va对应的页面可能被换出或不存在映射,需要进行判断并处理,比如page_remove若对应va的页面已被换出,则需要利用页表项中存储的磁盘块编号找到磁盘块更新页面信息。

所以你要进行swap_in

用户态主要通过syscall_mem_alloc,syscall_mem_map以及syscall_mem_unmap,在对应的内核态系统调用实现中同样需要对所涉及的页面进行额外的判断和处理,根据其是否换出维护页面映射关系与信息

这些系统调用都会使用page_insert等函数,对于映射信息,在page_insert里维护的很好的话是可以不额外处理的。但是要注意标记为可以换出的页面。

其他

关于COW

如果你对于权限位的保存和恢复处理的很好的话,并没有特殊处理的必要。

关于运行时间

如果你不想探究评测机运行时间上限的话,请不要滥用flush_tlb_all,而且请不要输出太多东西。

关于fork

其实duppage才是真正要考虑的东西,毕竟换出的页面也是某种意义上的有效页面。

关于调试

使用重定向输出到一个日志文件里,如果找不到可疑的部分,可以让LLM辅助分析,但是LLM终归是辅助,最后的决策必须由你来做出。如果不知道要输出啥,可以让大模型帮你在每一个地方都输出一下。

本人遇到的一些典型bug

因为其他课程原因本任务时间跨度比较长,有一些bug的出现已经忘了。
写一些目前印象深刻的bug。
对于三个测试用例,实际上是先过了第一个,然后过了第三个,然后过了第二个。
第一个测试用例的各种错误主要是没有理解什么样的页面应该被换出导致的,对于page_* 相关函数的处理不够全面(虽然也不复杂),主要输出详细的日志就能够找到。
第三个测试样例的错误主要在于没有处理page_lookup寻找的页面被换出了的问题。在这种情况下page_lookup会正确设置ppte,但是页面是NULL。而仅仅看ppte的话会觉得一切都很对
第二个测试样例的错误主要在于前期对于list的维护有问题,当fork时就会被复杂的关系hack掉。
同时,遇到了child阅读500000000页面时候进行了passive_alloc而不是阅读father的共享页面,这实际上就是因为页面被swap_out了但没有处理duppage。
遇到了COW权限位丢失问题,因为没有及时flush,同时也遇到了TLE问题,因为滥用了flush

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇