CS350 COS
COS
Loading...
Searching...
No Matches
palloc.c File Reference
#include <stdbool.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <sys/cdefs.h>
#include <sys/kassert.h>
#include <sys/kdebug.h>
#include <sys/kmem.h>
#include <sys/queue.h>
#include <sys/spinlock.h>
#include <machine/amd64.h>
#include <machine/pmap.h>
Include dependency graph for palloc.c:

Go to the source code of this file.

Data Structures

struct  FreePage
 
struct  PageInfo
 

Macros

#define FREEPAGE_MAGIC_FREE   0x4652454550414745ULL
 
#define FREEPAGE_MAGIC_INUSE   0x414c4c4f43415445ULL
 

Typedefs

typedef struct FreePage FreePage
 
typedef struct PageInfo PageInfo
 

Functions

 LIST_HEAD (FreeListHead, FreePage)
 
void PAlloc_LateInit ()
 
void PAlloc_AddRegion (uintptr_t start, uintptr_t len)
 
static PageInfoPAllocGetInfo (void *pg)
 
void * PAlloc_AllocPage ()
 
static void PAllocFreePage (void *region)
 
void PAlloc_Retain (void *pg)
 
void PAlloc_Release (void *pg)
 
static void Debug_PAllocStats (int argc, const char *argv[])
 
 REGISTER_DBGCMD (pallocstats, "Page allocator statistics", Debug_PAllocStats)
 
static void Debug_PAllocDump (int argc, const char *argv[])
 
 REGISTER_DBGCMD (pallocdump, "Dump page allocator's free list", Debug_PAllocDump)
 

Variables

Spinlock pallocLock
 
uint64_t totalPages
 
uint64_t freePages
 
XMempageInfoXMem
 
PageInfopageInfoTable
 
uint64_t pageInfoLength
 

Data Structure Documentation

◆ FreePage

struct FreePage

Definition at line 31 of file palloc.c.

Collaboration diagram for FreePage:
[legend]
Data Fields
uint64_t magic

◆ PageInfo

struct PageInfo

Definition at line 37 of file palloc.c.

Collaboration diagram for PageInfo:
[legend]
Data Fields
uint64_t refCount

Macro Definition Documentation

◆ FREEPAGE_MAGIC_FREE

#define FREEPAGE_MAGIC_FREE   0x4652454550414745ULL

Definition at line 23 of file palloc.c.

◆ FREEPAGE_MAGIC_INUSE

#define FREEPAGE_MAGIC_INUSE   0x414c4c4f43415445ULL

Definition at line 25 of file palloc.c.

Typedef Documentation

◆ FreePage

typedef struct FreePage FreePage

◆ PageInfo

typedef struct PageInfo PageInfo

Function Documentation

◆ Debug_PAllocDump()

static void Debug_PAllocDump ( int  argc,
const char *  argv[] 
)
static

Definition at line 288 of file palloc.c.

289{
290 struct FreePage *it;
291
292 LIST_FOREACH(it, &freeList, entries) {
293 if (it->magic != FREEPAGE_MAGIC_FREE)
294 kprintf("Magic Corrupted! (%lx)\n", it->magic);
295 kprintf("Free %lx\n", (uintptr_t)it);
296 }
297}
int kprintf(const char *fmt,...)
Definition: printf.c:210
#define FREEPAGE_MAGIC_FREE
Definition: palloc.c:23
uint64_t magic
Definition: palloc.c:33
#define LIST_FOREACH(var, head, field)
Definition: queue.h:410
uint64_t uintptr_t
Definition: types.h:16
Here is the call graph for this function:

◆ Debug_PAllocStats()

static void Debug_PAllocStats ( int  argc,
const char *  argv[] 
)
static

Definition at line 278 of file palloc.c.

279{
280 kprintf("Total Pages: %llu\n", totalPages);
281 kprintf("Allocated Pages: %llu\n", totalPages - freePages);
282 kprintf("Free Pages: %llu\n", freePages);
283}
uint64_t totalPages
Definition: palloc.c:28
uint64_t freePages
Definition: palloc.c:29
Here is the call graph for this function:

◆ LIST_HEAD()

LIST_HEAD ( FreeListHead  ,
FreePage   
)

Definition at line 45 of file palloc.c.

52{
53 totalPages = 0;
54 freePages = 0;
55
57
58 LIST_INIT(&freeList);
61}
PageInfo * pageInfoTable
Definition: palloc.c:43
XMem * pageInfoXMem
Definition: palloc.c:42
Spinlock pallocLock
Definition: palloc.c:27
#define LIST_INIT(head)
Definition: queue.h:430
#define SPINLOCK_TYPE_NORMAL
Definition: spinlock.h:12
void Spinlock_Init(Spinlock *lock, const char *name, uint64_t type)
Definition: spinlock.c:43
#define NULL
Definition: stddef.h:6
Here is the call graph for this function:

◆ PAlloc_AddRegion()

void PAlloc_AddRegion ( uintptr_t  start,
uintptr_t  len 
)

PAlloc_AddRegion –

Add a physical memory region to the page allocator.

Definition at line 92 of file palloc.c.

93{
94 uintptr_t i;
95 FreePage *pg;
96
97 if ((start % PGSIZE) != 0)
98 Panic("Region start is not page aligned!");
99 if ((len % PGSIZE) != 0)
100 Panic("Region length is not page aligned!");
101
102 /*
103 * PageInfo table isn't initialized on the first call to this function. We
104 * must allocate a temporary table that will be copied into the XMem region
105 * inside PAlloc_LateInit.
106 *
107 * Note that the PageInfo table is invalid for regions that are not added
108 * to the free list such as MMIO regions.
109 */
110 if (pageInfoTable == NULL) {
111 // Physical Address Offsets
113 uintptr_t end = base + len;
114
115 pageInfoLength = ROUNDUP(end / PGSIZE * sizeof(PageInfo), PGSIZE);
116 pageInfoTable = (PageInfo *)start;
117
118 start += pageInfoLength;
120
121 for (i = 0; i < (base / PGSIZE); i++) {
122 pageInfoTable[i].refCount = 1;
123 }
124 for (i = (base / PGSIZE); i < (end / PGSIZE); i++) {
125 pageInfoTable[i].refCount = 0;
126 }
127 for (i = 0; i < (pageInfoLength / PGSIZE); i++) {
128 pageInfoTable[i + (base / PGSIZE)].refCount = 1;
129 }
130 } else {
131 /*
132 * Only the first call to AddRegion should occur before the XMem region
133 * is initialized.
134 */
135
137
139 uintptr_t end = base + len;
140
141 uintptr_t newLength = ROUNDUP(end / PGSIZE * sizeof(PageInfo), PGSIZE);
142
143 if (!XMem_Allocate(pageInfoXMem, newLength))
144 Panic("Cannot allocate XMem region!");
145
146 // Initialize new pages
147 for (i = (base / PGSIZE); i < (end / PGSIZE); i++) {
148 pageInfoTable[i].refCount = 0;
149 }
150 }
151
153 for (i = 0; i < len; i += PGSIZE)
154 {
155 pg = (void *)(start + i);
157
158 totalPages++;
159 freePages++;
160
161 LIST_INSERT_HEAD(&freeList, pg, entries);
162 }
164}
#define ASSERT(_x)
Definition: kassert.h:8
#define ROUNDUP(_x, _n)
Definition: malloc.c:32
#define PGSIZE
Definition: malloc.c:21
uint64_t len
Definition: multiboot.h:2
uint64_t refCount
Definition: palloc.c:39
uint64_t pageInfoLength
Definition: palloc.c:44
#define DMVA2PA(dmva)
Definition: pmap.h:47
#define LIST_INSERT_HEAD(head, elm, field)
Definition: queue.h:451
static uint16_t base
Definition: sercons.c:37
void Spinlock_Unlock(Spinlock *lock) __UNLOCK_EX(*lock)
Definition: spinlock.c:109
void Spinlock_Lock(Spinlock *lock) __LOCK_EX(*lock)
Definition: spinlock.c:75
void Panic(const char *str)
Definition: vgacons.c:164
bool XMem_Allocate(XMem *xmem, uintptr_t length)
Definition: xmem.c:92
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PAlloc_AllocPage()

void * PAlloc_AllocPage ( )

PAlloc_AllocPage –

Allocate a physical page and return the page's address in the Kernel's ident mapped memory region.

Return values
NULLif no memory is available.
Returns
Newly allocated physical page.

Definition at line 188 of file palloc.c.

189{
190 PageInfo *info;
191 FreePage *pg;
192
194 pg = LIST_FIRST(&freeList);
195 ASSERT(pg != NULL);
196 LIST_REMOVE(pg, entries);
197
199
200 info = PAllocGetInfo(pg);
201 ASSERT(info != NULL);
202 ASSERT(info->refCount == 0);
203 info->refCount++;
204
206
207 freePages--;
209
210 memset(pg, 0, PGSIZE);
211
212 return (void *)pg;
213}
static PageInfo * PAllocGetInfo(void *pg)
Definition: palloc.c:172
#define FREEPAGE_MAGIC_INUSE
Definition: palloc.c:25
#define LIST_REMOVE(elm, field)
Definition: queue.h:465
#define LIST_FIRST(head)
Definition: queue.h:408
void * memset(void *dst, int c, size_t len)
Definition: string.c:164
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PAlloc_LateInit()

void PAlloc_LateInit ( )

PAlloc_LateInit –

The late init call is made after the page tables are initialized using a small boot memory region (2nd 16MBs). This is where initialize the XMem region that represents the PageInfo array, and map memory into it.

Definition at line 71 of file palloc.c.

72{
73 void *pageInfoOld = pageInfoTable;
74
77 Panic("Cannot back pageInfoTable!");
78 }
79
81 memcpy(pageInfoTable, pageInfoOld, pageInfoLength);
82
83 // Free old pages
84}
void * memcpy(void *dst, const void *src, size_t len)
Definition: string.c:177
XMem * XMem_New()
Definition: xmem.c:47
uintptr_t XMem_GetBase(XMem *xmem)
Definition: xmem.c:80
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PAlloc_Release()

void PAlloc_Release ( void *  pg)

PAlloc_Release –

Deccrement the reference count for a physical page. If the reference count is zero the page will be freed.

Definition at line 265 of file palloc.c.

266{
267 PageInfo *info = PAllocGetInfo(pg);
268
270 ASSERT(info->refCount != 0);
271 info->refCount--;
272 if (info->refCount == 0)
273 PAllocFreePage(pg);
275}
static void PAllocFreePage(void *region)
Definition: palloc.c:221
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PAlloc_Retain()

void PAlloc_Retain ( void *  pg)

PAlloc_Retain –

Increment the reference count for a physical page.

Definition at line 248 of file palloc.c.

249{
250 PageInfo *info = PAllocGetInfo(pg);
251
253 ASSERT(info->refCount != 0);
254 info->refCount++;
256}
Here is the call graph for this function:

◆ PAllocFreePage()

static void PAllocFreePage ( void *  region)
static

PAllocFreePage –

Free a page.

Definition at line 221 of file palloc.c.

222{
223 FreePage *pg = (FreePage *)region;
224
225 ASSERT(((uintptr_t)region % PGSIZE) == 0);
226
227 LIST_INSERT_HEAD(&freeList, pg, entries);
228
229#ifndef NDEBUG
230 // Application can write this magic, but for
231 // debug builds we can use this as a double free check.
233
234 PageInfo *info = PAllocGetInfo(pg);
235 ASSERT(info->refCount == 0);
236#endif
237
239 freePages++;
240}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PAllocGetInfo()

static PageInfo * PAllocGetInfo ( void *  pg)
inlinestatic

PAllocGetInfo –

Lookup the PageInfo structure for a given physical address.

Definition at line 172 of file palloc.c.

173{
174 uintptr_t entry = (uintptr_t)DMVA2PA(pg) / PGSIZE;
175 return &pageInfoTable[entry];
176}
Here is the caller graph for this function:

◆ REGISTER_DBGCMD() [1/2]

REGISTER_DBGCMD ( pallocdump  ,
"Dump page allocator's free list"  ,
Debug_PAllocDump   
)

◆ REGISTER_DBGCMD() [2/2]

REGISTER_DBGCMD ( pallocstats  ,
"Page allocator statistics"  ,
Debug_PAllocStats   
)

Variable Documentation

◆ freePages

uint64_t freePages

Definition at line 29 of file palloc.c.

◆ pageInfoLength

uint64_t pageInfoLength

Definition at line 44 of file palloc.c.

◆ pageInfoTable

PageInfo* pageInfoTable

Definition at line 43 of file palloc.c.

◆ pageInfoXMem

XMem* pageInfoXMem

Definition at line 42 of file palloc.c.

◆ pallocLock

Spinlock pallocLock

Definition at line 27 of file palloc.c.

◆ totalPages

uint64_t totalPages

Definition at line 28 of file palloc.c.