Starting from:

$30

KERNEL-Project 3 Memory Management Solved

You tasks: This project consists of two parts. You are going to write two system calls (and a user-level test program for each call) to collect memory management statistics.

Part 1
Write a system call to report statistics of a process’s virtual address space. The system call should take a process ID as input and output the size of the process’s virtual address space in use. Additionally, write a user-level program to test your system call.

HINT: First, to get a process ID, you can use command ps to get the PID of bash.

The Linux kernel uses the memory descriptor data structure, mm struct, to represent a process’s address space. mm struct is defined in linux/mm types.h and included in a process’s task struct as a field called mm. If the task struct of a process with PID is task, then task-mm is the process’s memory descriptor. Within the memory descriptor, you can also find the work horse for managing program memory: a set of virtual memory areas (VMAs) of type vm area struct. All the VMAs together form a process’s virtual address space.

A process’s VMAs are stored in its memory descriptor as a linked list in the mmap field (task-mm-mmap). You may get a sense of how the mmap field is linked via the vm next field, by looking at the second diagram in this blog post:

https://manybutfinite.com/post/how-the-kernel-manages-your-memory/

An instance of vm area struct fully describes a memory area, including its start and end addresses. To calculate the size of a virtual address space, you need to sum the sizes of individual VMAs.

Part 2
Write a system call to report the current status of a specific address. The system call takes a virtual address of a process (whose process ID is pid) and the pid, then outputs whether this address is in memory or on disk. Additionally, write a user-level program to test your system call.

HINT: To get a virtual address of a process, you can take the PID of bash in Part One, and pass the PID to command pmap to get a listing of the virtual addresses. Then pass one of the virtual addresses from pmap, to your user-level test program to see the results from your system call.

The page descriptor page defined in linux/mm types.h contains information about the page. You need to figure out how to obtain a reference to the page descriptor given a virtual address and read information from the page descriptor. Note that Linux uses multi-level page tables, so you might need multiple steps to reach the page table entry (PTE) of a given virtual address.

http://www.cs.uccs.edu/~yzhuang/CS4500_5500/fall2018/slides/LEC10_Mem_Intro. pdf, on slide 35 we introduced how to navigate the page directories. Each process has its own pointer to what is called a page global directory (PGD). A page table entry is a PTE. To navigate the page directories, several macros are provided by the kernel to break up a virtual address into its component parts. For example, pgdoffset() takes a virtual address and the mm struct for the process (the mm field of taskstruct) and returns the PGD entry that covers the requested address. pud offset() takes a PGD entry and an address and returns the relevant PUD entry. And pmd offset() takes a PUD entry and an address and returns the relevant PMD entry.

Note: The output of pmap are hexadecimal strings. To use pgd offset(mm, address), pmd offset(mm,address), and pte offset(mm,address), the argument address has to be converted to unsigned long. Some more information can be found on this page: http:

//www.chudov.com/tmp/LinuxVM/html/understand/node24.html

Finally, we need to get the PTE from the PMD entry. This step can be a little tricky. pte offset(pmd, address) could work but sometimes you would get kernel oops (https:

//en.wikipedia.org/wiki/Linux_kernel_oops). The reason is that pte offset() returns an address of a page table entry, but the entry itself could be changed by the process at runtime. Therefore, you should try the following:

#include <linux/mm.h

#include <linux/highmem.h

spinlock t ∗lock ;

ptep = pte offset map lock (mm, pmd,                             address , &lock );

. . .

pte unmap unlock (ptep ,             lock );

To test if an address is in memory, you need to use the macro pte present() to test if the corresponding PTE have the PRESENT bit set. Note that pte present()’s argument is a PTE, not the address of a PTE.

More products