 Okay, hi everybody. So today is our 10th recitation. We're going to go over the TLB and other space management. As usual we're going to just like review what we covered last week. So last week we've covered the physical memory management and we've said that in order for you the first step for implementing the physical memory management is to define your core map. And core map is basically a data structure that keeps track of the physical pages and formation. We've also went through when should we initialize the core map and we've said that the best place to initialize it is before the very first K-malc call. We went through all the bootstrap functions and main.c and we know that the first K-malc call is located in proc bootstrap. So you need to initialize your core map before that and after the RAM bootstrap. Since core map is required for the K-malc then allocating a memory for your core map should be done manually. So you cannot use K-malc for it. So you should end up with such a physical memory where you don't have leaked memory. You have the exception handler first that comes first and then the kernel. Once we reach the RAM bootstrap we have these two regions in the physical memory. Then we need to initialize our core map the way we've presented. So previously some people used to just like use the dump VM way just like or postpone the core map initialization into the VM bootstrap and that's too late. Which means from the time that you start the RAM bootstrap to the point where you call the VM bootstrap you're going to leak memory because K-malc going to call allocK pages. AllocK page is going to call the RAM steel memory which leaks memory and there is no way for you to retrieve such a memory in between the kernel and core map that's going to be allocated. So the best way to initialize the core map as we said is before the very first K-malc call. We've also presented the core map structure and we said that the core map basically should have entries equal to the number of pages that you have in the physical memory. So this for example, this is how it should map. So for example the first three entries let's say should be reserved for the exception handler kernel and core map and the remaining should be the free memory that the user can use. So we've also mentioned that so yeah so they compute the number of physical pages in memory and you need to note that the number of physical pages in memory it is fixed but it is not known at the compile time it should be retrieved or the RAM size should be retrieved at the runtime and that means you need to initialize your core map later on. It shouldn't be just like of a fixed size at the compile time. How you should compute the core map size basically you just like see what is the size of your core map structure and then you multiply it by the number of pages. So as we said if we have a 4 megabyte of memory that given 4k pages we're going to use that mean we're going to have 1000 pages which mean 1000 core map entries. So you identify the size of each of these core map entries and then you multiply it by 1000 you'll get the core map size and then you can allocate it manually. How should you allocate manually if you go through the RAM. Let's see you will see all these first physical address pointer and last physical address pointer. How does the core basically so as we said the dump VM steals memory. So we don't want that if you do not initialize your core map and so once we call RAM bootstrap up until VM bootstrap if you put your core map initialization in the VM bootstrap that's what we don't want because the dump VM will basically steal all that memory while it is initializing all the data structures used in these bootstraps but later on when you want to really allocate memory for your core map you're going to do it the same way dump VM do it which is you're going to again steal memory but it is not a stolen memory because you have a track of this memory. So you're going to just like adjust the first address and make it point to the point where the core map ends and from the first physical address to that last physical address this is with the free memory that you're going to manage through the core map. What information do we need to keep in core map we said that you need to keep the page estate for now those you only need the states of free or used later on when we go into the swapping you need to know you need for example mark the kernel pages as fixed that mean you should not swap them out and the free pages those are the ones that you need to just like having other states like dirty or clean but for now up until the second checkpoint so you can use just like free or used because there is no swapping and you do need synchronization for your core map we've also discussed the how MIPS MMU works or how the physical address space versus the physical memory so we've mentioned that for the physical address space we have three or four regions defines first we have the k usag which is the user segment we have the kernel segment zero kernel segment one and kernel segment two we know that the user segment is TLB mapped and cached we also know that the kernel segment zero is a kernel memory that is cached and it is direct mapped so there is no TLB involved here and to translate basically you just need to subtract the ox 80 million from the given virtual address while for ksig one is again the same it's a kernel memory that is directly mapped but it is uncached why because it is a read only memory ksig two this is not used but it is TLB mapped not used in OS 161 but it is a TLB mapped and cached so what you're really concerned with is ksig zero kernel segment zero you don't really need to worry about kernel segment one and two the last thing we presented is after presenting this picture we know that why we shouldn't swap out kernel pages because there is no TLB that mean we cannot keep track of these pages if we swap them out there is no way for us to know that where do they exist and why allocate pages has to allocate and contiguous physical pages is basically this function is called by the kernel again there is no TLB involved or TLB fault so this is why the contiguous kernel virtual addresses has to just like map to physical addresses so in the user segment since you have a TLB that mean so for the user segment when we allocate pages it's going to be contiguous in the address space but for the physical memory it could be just like sparse or just like allocated in different regions in the physical memory why is that because we can't keep track of them through the TLB but with kernel pages since there is no TLB then we cannot keep track of them and that mean whatever contiguous virtual pages that we allocate for the kernel it has to be contiguous on the physical page otherwise we don't know we really don't know where each page is located in the physical memory so we only get the starting address and we know the size and things will go on so this is what we've discussed last time any questions on core map okay so today we're going to discuss the page table and user address space and TLB management and fault how to handle the TLB fault and VM fault so currently we are we should be everybody should be implementing the second part which is address space and TLB management the user paging and our next deadline going to be Friday after this one April 22nd so next week most probably going to be our last recitation but I'll confirm that through the discourse so as an introduction to the page table so let's just start by step by step to understand what really page table is so we know that every page is 4k and we also now that every virtual address is 32 bit so how should the translation happen basically for the virtual address we need to divide the virtual address into several parts one part going to be the virtual page number this is the VPN what we call a VPN and the remainder the remainder is the offset into that page also we should know that every virtual page should map to physical page and all addresses within a single physical page should map to the same physical page so sorry every all address in the same virtual pages should map to the same addresses and or in the same physical page so if we how should we divide the virtual address we know it is 32 bits so we're going to use the top 20 bits as the VPN and the low or bottom 12 bits as the at the offset so we're going to use the VPN to just like translate and get the the physical page number once we get that we can add the offset to it and we'll get the physical address so now what is a page table page table is the data structure that quickly maps a physical page number into page table entry what is a page table entry page table entry is just like a structure keeping track of all the virtual pages so you can think of virtual page sorry page table entry as an equivalent to a core map core map handles the physical page physical pages while the page table entry the PTE handles the virtual pages so since it is equivalent to the core map that mean or a core map entry so page table is equivalent to a core map page table entry is equivalent to core map entry that means so since the core map entry has all information that tracks all information about the physical pages that mean our page table entry has should also have information for tracking the formation about the virtual pages so every process should have its own page table and there is only one page table per process why because the virtual address could be translated differently for each process and how should we compare page table so per table as I said equivalent to core map it is also equivalent to similar data structures that we've gone through which is file table so file table maps file descriptor into file handle while for example process table also maps a PID into process structure the same thing goes with page table page table maps virtual page number into page table entry which is again kind of structure so what's the requirement for a page table so this data structure what should its functionality be so when I give that page table an address and an operation it should tell me whether this address is valid or not or if the operation on this address is valid or not and then it will retrieve it should retrieve if it's valid then it should retrieve the physical address for that virtual address any question on the page table so page table entry page table entry as we said is a single entry storing information about the virtual pages what information do we need to maintain in a page table entry so this is depending on your data structure that you're using for your page table for example if you're using flat table or flat page table then you don't need a virtual page number inside your PTE why because the virtual page number should be the index into that flat page table while if you use list for your page table then you do need to maintain the virtual page number because whenever you want to just like retrieve a page table entry you should go through the whole list and compare the virtual page number with the one that you have so if it's a list you do need to maintain the virtual page number in your PTE structure you also need to maintain physical page number or location on this so the physical page number is nothing but so since pages 4k aligned that mean the physical page number is also the physical base for or the starting address of a page and once you retrieve that you need to add the offset you get the address inside that page so this is so physical page it could be a physical page number or location on disk for the second entry that you need into the PTE structure yes so yeah it's going to be one page but the physical page number is equivalent to the physical page base which is the starting address of the page and once you retrieve that you add the offset to it and you'll get to your address yes the same thing goes with the virtual page number so again this is the base of the virtual page it's not just like a regular virtual address you also need to maintain the permission which whether that page the permission of this page is read write execute you need to maintain the state of this page so here is a lot of questions pops up because this year we're requiring on demand paging which means that whenever you define a region I'm going to go through with more more details but whenever you define a region you should not allocate the whole physical pages for that region you should allocate only the virtual pages for it but you shouldn't allocate the physical whenever the VM fault happens the allocation should happens at the same time and that's going to save a lot of memory and this is what we call on demand allocation sorry it's not on demand paging the more correct word should be on demand allocation so that mean what you need to just like maintain in the state is first of all is that page so what sort of so is that page valid so whether that means if the page is valid it has a physical page entry just forgot the okay I'm gonna do you know the states of the pages I just forgot them just like it got confused no no no it's I think uh is the page located so oh yeah sorry I yeah yeah no no no I got it yeah oh sorry because with on demand allocation I get confused so there are two states that you need to maintain first of all is that page in memory or on disc there's the first one so you should know the state should maintain this whether the page is on memory or on the disc and also it should maintain that if the virtual page is allocated is it valid or not that mean does that page has an physical page or not allocated for it or not so this is the state the reference basically this is what you need to later on extend for the third checkpoint which is the swapping depending on how you need to handle the pages and page evictions and stuff like this so for example the reference will tell you has the page been read or written to recently or not and this is how you should decide whether to swap out a page or not but for now what you need to really be concerned with is before the virtual page number physical page number and permissions and the state but keep in mind that you're going to extend your structure or the page table entry later on so let's go through any questions on the page table entry yes oh so I think so yes you do need permissions just don't try to implement based on the checkpoints because that's not yeah but if I were you before I would prefer just like implementing this because later on you don't want to just like don't implement it and you run the test it doesn't go through and then you're just like you have two days left and you're still not doing so it could have some dependencies or stuff like this so any other questions on the page table entry sorry okay there is no no no so that's different so page being in memory that means you have the page in memory but if you don't have the page in memory a page fault would happen that means the page is allocated but it's on disk the the valid thing is so let's say once you allocate a region or you define a region and then you load the region so previously dump vm will just like if I just like allocate the data region I will also allocate all the physical pages for it so just like once you allocate the virtual pages you allocate the physical pages at the same time but what we're requiring this time is on-demand allocation which means when I define a region then you only define it in the or allocate it in the virtual part but you do not allocate the physical part for it why is this for example let's say in your code you have an array that is really big and that your memory couldn't handle or let's say you define an array that the user doesn't use throughout the the program so that means you're allocating or wasting memory why should I allocate pages physical pages for that array that is not never been used so I'm just going to define that region whenever a hit happens on that array then I'm going to vm fault will be will happen and then I'm going to allocate the physical part yeah well this is one of the problems yeah and segment yeah yeah you cannot you don't have a variable number of segments and this is what you need to implement this time okay so any other questions okay so let's go through the page table designs so you have several options for your page table one of the options you shouldn't use because you're going to run out of memory which is flat page table flat page table basically you allocate an array that holds all the pte's for each process and that means so you have the virtual address which is 32 bit we're gonna just like dedicate the 20 as we said the top 20 bits for the virtual page number that mean you're gonna have two to the power of 20 virtual pages and that's what means if you compute two to the power of 20 means one million 48 pages so that means if you use a page table a flat page table then even though you're not going to use all these pages but you're going to allocate memory for that and in os 161 you're going to run out of memory so you shouldn't use the flat page table and in flat page table as we said the vpn gonna be the index into the array that means in your page table entry you shouldn't define a vpn this is just i'm giving i know you shouldn't use this but i'm just giving you information so we can compare them and since it's an array and the vpn is an index into that array then we can retrieve in big o one or constant time we can retrieve the page table entry and as we said that most of the entries could be unused in the flat page table the other option is using a link list for the page table so that means you're going to define every page table whenever you need it and that means you're going to have exactly the number of pages that you're using you're not wasting memory but the problem with the link list page table is just like whenever you want to retrieve pte you need to go through the whole list and that means big o n time searching for each time you want to just like retrieve a pte but at the same time all entries are used in the link list yes sorry i didn't understand sorry yes so does that matter with what you want? so that's what i was going to say it doesn't matter okay you can use it so the easiest way to implement a page table is going with uh link list uh while you also have the more advanced one that is you could use it later on maybe uh depends some students uh i took to some student that uh did four level not even two levels so i'm gonna explain the two level yeah that's gonna be a difference because because it's still it's a constant time retrieve so it's four level that means four big o of four so that's constant time yeah so the in terms of space the link list gonna do better but in terms of time retrieving it's gonna do worse than the page table the two level page table okay no for always 161 no for always 161 uh link list is totally fine recommended if you really don't want to get too much complications uh yes just do what you're gonna save time maybe for me i would just like if you ask me what should i choose i would go with list for now once i'm done maybe i'm gonna i want to just like consider improving the performance of my kernel by implementing the two level page table but yeah for now since you have two weeks uh if you prefer just go with the link list and it's much easier so we have another uh third implementation for the page table which is a tree like uh page table so we're going to discuss the two level page table while some people would do more just like multiple levels so this means you're gonna build a tree like data structure mapping vpn to the pte so what what happens let's consider the two level page table then that means as i said the virtual address is 32 bit we're gonna we divided it into 20 bits for the vpn while 12 bits for the offset then we're gonna do again divide that 20 bits into 10 bits and 10 bits and each one of them uh each 10 bits gonna just like point to each level so since we have two level page tables the first the top or the first uh 10 bits gonna point to our first level uh page table and then the next 10 bits gonna point to the uh uh second level page table so what does that mean that means so i'm gonna explain how the implementation goes for this so this is how the two level uh page table should look like so as you can see here we have the virtual address so the first uh 10 bits we call it directory second 10 bits gonna be the table the third 12 bits gonna be the offset i'm gonna explain why directory and table so this first level page table you need to allocate it so this has to be allocated and since it is 10 bits then mean two to the power of 10 that means 1024 entries for that table that's what i need to allocate at the beginning so whenever i'm gonna just like for each entry into these uh page table uh so this is gonna be just like an array of pointers pointing to another level of page tables so for each entry that points to another level of page table it only will point to the base of that uh page table and then from the second 10 bits we're gonna get the index so for example if this 10 bits points to this entry then this entry should have a pointer to the second level page table which is the base uh it should be the base physical uh or virtual address of that second page table of or the base of that page table and then uh using the second 10 bits in the virtual address we can uh we can allocate or uh know which index into that table should we uh retrieve so and since we have two level page tables so we're gonna keep the uh page table entry structure at the leaves because it looks like three that means the first level page table should be array of pointer while the second level page table should be array of structures of pte structures and here where you should have all these information about the virtual page which is uh you should have the physical page uh uh number and permissions state and everything else so once we retrieve the physical page number that will point to the base of the physical page in the physical memory that mean the the beginning of the physical page how we retrieve the address that we want in that physical page is by adding the physical page number with the offset which is the 12 bits in the virtual address and we'll get into the address the physical we'll get the physical address of that page of that virtual address so this is how the uh two level page table uh works so what are we saving by using two level page tables what we're saving is basically so this page table the first level page table we do need as i said we do need to allocate it so that's fine uh but for any other pages so if the page is used at that point we're going to allocate another page table for that entry if it's not used uh we're not going to allocate uh uh a page table for that entry that mean we're going to save a lot of memory so we're going to allocate the second level only if the entry in the first page uh in the first level uh page table is used otherwise we shouldn't allocate the second level page table so whenever a vm fault happen on this you're going to allocate the second level of uh virtual base uh the second level page table and then uh you need to using the second the second 10 bits uh and the virtual address you need to allocate that index in that array and then let it point to the physical page so this is how the two level page table should work uh so as we said each page table is two to the power of 10 and if we multiply it with four bytes because it's holding addresses or pointers then we're going to get a 4k which is still saving a lot of space and retrieving going to be in constant time so constant number of lookups going to happen uh first translation um yeah so space usage depends on the sparsity of address space but better than flat page table and worse than link list so this is all about the page table and page table entry any questions okay so let's go to the user address space so we should be familiar with this user address space basically have several regions we have code we have data heap stack we could have more regions uh that we could just like load from the l file so the code and data the heap should come somewhere uh so as we know that the heap should grow upward while stack should grow downward and where should the heap be is basically uh you should keep in mind that the heap should be after all of these regions uh why because why because if we allocate the heap somewhere let's say between code and data they will hit each other since the code and data are fixed regions but the heap and stack are not fixed regions the size could change so we know uh the stack where should it be located for the heap we need to just like you need to make the calculations by just like figuring out where's the last region that you defined and then you define the heap over that yes during or after yes you still yeah after because you need to just like yeah you need to load all the regions and then you can initialize the yes but you still need to call as defined region for the heap because you still need to set permissions and all of these stuff so it should be it should call be as defined adder space structure so it is defined in adder space dot h the header file what information do we need to keep in the adder space structure so first of all you need to keep information regarding the regions so where does each region start what's the size of each region what are the permission of each region whether it's read only write only or read write or execute sorry for the stack and heap region so these are special regions why because the size is not fixed may change so you need to just like handle those after you load all the regions of formation from the alpha and also you need to keep a page table pointer so this is where you keep the so if you see here there is a pointer which is a page table base you need to keep that pointer into your address piece structure and this should be your page table pointer so through the physical address you can just like using that pointer and the physical page number or sorry virtual page number you could allocate which index you need into that page table or the if you did it into just like to if you used the two level page table as your data structure so for adder space interfaces so we've gone through the interfaces several times but these are the ones that are important so regions setup how should we set up regions using the as defined so if you remember in the last lasso station or the one before we went through the load elf dot c so the load elf basically first of all it will call let's go through it okay so if you can see here and the load elf function first we're going to loop through the regions go through the list of segments and set up the address space so here we're going to go through the regions read the regions from the elf file and then call as defined region so what will what will that read give us is basically at what address should that region start what is the size of the address so this is the address where the region should start this is the size of the region and these are all the flags which are set for every region so for data heap stack we know that it's all read write but for the the only difference going to be with the code region which should be only read only it shouldn't be right so this is the as defined that you need to implement so please remember that now that your vm should replace the dump vm that mean after you implement all the other space interfaces if you run if you're done with the assignment to then if you retest your assignment to using your vm it should pass you shouldn't get errors so that mean you need to re-implement all these functions or interfaces either re-implement or really implementing them because some of them are just like do nothing in the dump vm so we're going to call the as defined region to set up the region and then to load the region we're going to use as a prepared load as complete load why what are the what are important about these functions so for the code region when you define the code region you're going to set the permission as read only that means later on if you want to load the content from the oil file you're going to need to write into that segment but since you set it as a read only then you're going to get a vm fault so what are so these two functions solve the problem for you which is and these two functions or as we said previously that all the as function are only called by the kernel the user has no access to these functions so whenever as a prepared load is called that mean you need to reset all your permissions for all the regions as writable so that means you can write into these pages you should also not only overwrite but also you need to keep a backup of what was the permission before you make the permission as write so once you call as complete load you need to just like restore the permission to what it was previously so this is why these two functions are important and what they should do yes load this is the only place no so after you define the segment so so yeah after we as define region as you can see now the next step is as load and what will happen next now actually load each segment so it will keep loading using the load segment once i'm done loading so it's a for loop that means it will load all the content for every region once i'm done then i'm going to call as complete that mean you're going to restore the permissions to what it was before i think so yes so so yeah you need to restore the permissions to what it was and this is why we use as a prepared load and as complete load and so now you should know what you should have into these two functions the last function which is as activate so whenever a process is using a cpu then the tlb gonna have the virtual translation for that process from so it's going to have translation for that process virtual address to physical addresses so what does as activate do is basically it should just like clear the tlb for you so you could do it some other way just like if you want a more advanced way of doing it is just like you can keep just like a backup if you want of what was the tlb entry because if you just only clear the tlb that mean next time that process a context works happen and that context comes back to the to the cpu then all the vmful is going to happen for all entries so the basic way is just like clear the tlb you want a more advanced way just like try to have a backup or think of an algorithm for just like how should i manage these the tlb and make the performance of the process better so this is what the as activate should do basically handle the context switching by clearing the tlb now any questions on the address space okay so the last thing we have is the tlb which is translation like a side buffer so this is a cache that is used by the hardware which is the mmu which is part of the cpu so it has we do have only 64 entry per core and each entry is 64 bit size so this is how it should look which is the first 32 bit so we have two 32 bits the first one the first 20 bits is the virtual page number and the remaining 12 bits are unused the second 32 bits basically is the translation of that virtual page which is the physical page number and we have some unused bits while we have three flags here first the first one is no cache you don't need to worry about that the second one is tlb low dirty and that doesn't have the meaning of dirty which is just like as we have it in the for the swapping what dirty mean just like is this page writable or not so if the that flag is zero that mean this page is read only while if it's one that means it is also writable read write the valid is basically will tell you if that entry is valid or not or if this page is valid or not no it tells you if so yes I think so I believe yes should tell you but I need to I need to double check this if it's really the same as the one yeah so the valid that I told you you need to have it in the state of the just like when you define your page table entry you have that state you should have the valid which means if you have the page table allocated or sorry if you have the physical page allocated that is equivalent to your virtual page but that one I need to check if that one is also the same as the one that we have in the page table entry so you have a three types of okay we have two minutes left so we have three types of tlb we have vm fault read and vm fault write and then vm fault read only so the read and write will basically tells you okay you have an entry you have the tlb entry oh sorry there is no tlb entry for yes there is no tlb entry for that page if the vm fault read and write happens um but for vm fault read only so keep the difference in mind that for vm fault read only you have the tlb entry in the tlb but the dirty bit is set to zero that means you're trying to write into a page that is read only so let's just like summarize what should a vm fault basically does or do is check if the fault address is valid so we have all these regions in the address space so we have a lot of undefined regions here so this is what we mean if the page if that page address is valid or not so if the page address doesn't fall in a defined region that means the page address is not valid then you need to check the page permission so if the page address is valid you need to check the permission so am i trying to write into a page that is read only or not for example um check if uh it is page fault so this is another thing the next thing you need to do was you need to check if there is a page fault or not that means if the page is allocated then is it in memory or on disk if it's not allocated then you need to uh allocate it as needed so and once you do all of this you need to update the tlb entry with the with the with that with these addresses so few points just go through we have a lot a set of functions that is vm or tlb read tlb write you can find them in kern include arc maps i think arc maps include tlb.h you have a set of functions that you can use to manage the tlb which is tlb read write prop uh also um what else i think that's pretty much it pretty much it so yes so this is it also for the slides please once i whenever i post the slides the slides gonna not gonna be this exactly the same i'm gonna i'm gonna update it because these slides i just made them when every week i just just like on monday or tuesday i start creating these slides so check them when i post them because it's gonna have an updated information or more information so thanks for coming and good luck with the second checkpoint and see you next week