提交 7846c203 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

Add a kstack allocator, bump kstack size to 8K.

上级 7edb9fbd
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "cpu.h" #include "cpu.h"
struct kmem kmems[NCPU]; struct kmem kmems[NCPU];
struct kmem kstacks[NCPU];
extern char end[]; // first address after kernel loaded from ELF file extern char end[]; // first address after kernel loaded from ELF file
char *newend; char *newend;
...@@ -46,7 +47,7 @@ kfree_pool(struct kmem *m, char *v) ...@@ -46,7 +47,7 @@ kfree_pool(struct kmem *m, char *v)
// Fill with junk to catch dangling refs. // Fill with junk to catch dangling refs.
if (kinited && kalloc_memset) if (kinited && kalloc_memset)
memset(v, 1, PGSIZE); memset(v, 1, m->size);
acquire(&m->lock); acquire(&m->lock);
r = (struct run*)v; r = (struct run*)v;
...@@ -75,20 +76,16 @@ kmemprint(void) ...@@ -75,20 +76,16 @@ kmemprint(void)
cprintf("]\n"); cprintf("]\n");
} }
// Allocate one 4096-byte page of physical memory. static char*
// Returns a pointer that the kernel can use. kmemalloc(struct kmem *km)
// Returns 0 if the memory cannot be allocated.
char*
kalloc(void)
{ {
struct run *r = 0; struct run *r = 0;
struct kmem *m;
// cprintf("%d: kalloc 0x%x 0x%x 0x%x 0x%x 0%x\n", cpu->id, kmem, &kmems[cpu->id], kmem->freelist, PHYSTOP, kmems[1].freelist);
u32 startcpu = mycpu()->id; u32 startcpu = mycpu()->id;
for (u32 i = 0; r == 0 && i < NCPU; i++) { for (u32 i = 0; r == 0 && i < NCPU; i++) {
int cn = (i + startcpu) % NCPU; int cn = (i + startcpu) % NCPU;
struct kmem *m = &kmems[cn]; m = &km[cn];
acquire(&m->lock); acquire(&m->lock);
r = m->freelist; r = m->freelist;
if (r) { if (r) {
...@@ -106,16 +103,32 @@ kalloc(void) ...@@ -106,16 +103,32 @@ kalloc(void)
mtrace_label_register(mtrace_label_block, mtrace_label_register(mtrace_label_block,
r, r,
4096, m->size,
"kalloc", "kalloc",
sizeof("kalloc"), sizeof("kalloc"),
RET_EIP()); RET_EIP());
if (kalloc_memset) if (kalloc_memset)
memset(r, 2, PGSIZE); memset(r, 2, m->size);
return (char*)r; return (char*)r;
} }
// Allocate one 4096-byte page of physical memory.
// Returns a pointer that the kernel can use.
// Returns 0 if the memory cannot be allocated.
char*
kalloc(void)
{
return kmemalloc(kmems);
}
// Allocate KSTACKSIZE bytes.
char *
ksalloc(void)
{
return kmemalloc(kstacks);
}
// Memory allocator by Kernighan and Ritchie, // Memory allocator by Kernighan and Ritchie,
// The C programming Language, 2nd ed. Section 8.7. // The C programming Language, 2nd ed. Section 8.7.
...@@ -146,16 +159,36 @@ void ...@@ -146,16 +159,36 @@ void
initkalloc(void) initkalloc(void)
{ {
char *p; char *p;
char *e;
for (int c = 0; c < NCPU; c++) { for (int c = 0; c < NCPU; c++) {
kmems[c].name[0] = (char) c + '0'; kmems[c].name[0] = (char) c + '0';
safestrcpy(kmems[c].name+1, "kmem", MAXNAME-1); safestrcpy(kmems[c].name+1, "kmem", MAXNAME-1);
initlock(&kmems[c].lock, kmems[c].name); initlock(&kmems[c].lock, kmems[c].name);
kmems[c].size = PGSIZE;
}
for (int c = 0; c < NCPU; c++) {
kstacks[c].name[0] = (char) c + '0';
safestrcpy(kstacks[c].name+1, "kstack", MAXNAME-1);
initlock(&kstacks[c].lock, kstacks[c].name);
kstacks[c].size = KSTACKSIZE;
} }
p = (char*)PGROUNDUP((uptr)newend); p = (char*)PGROUNDUP((uptr)newend);
for(; p + PGSIZE <= (char*)KBASE + PHYSTOP; p += PGSIZE) e = (char*)KBASE;
kfree_pool(&kmems[((uptr) v2p(p)) / (PHYSTOP/NCPU)], p); for (int c = 0; c < NCPU; c++) {
char *sp = p + CPUKSTACKS*KSTACKSIZE;
char *ep = e + (PHYSTOP/NCPU);
if (sp >= ep)
panic("Too many stacks");
for (; p < sp; p += KSTACKSIZE)
kfree_pool(&kstacks[c], p);
for (; p < ep; p += PGSIZE)
kfree_pool(&kmems[c], p);
e = p;
}
kminit(); kminit();
kinited = 1; kinited = 1;
} }
......
...@@ -6,7 +6,8 @@ struct kmem { ...@@ -6,7 +6,8 @@ struct kmem {
char name[MAXNAME]; char name[MAXNAME];
struct spinlock lock; struct spinlock lock;
struct run *freelist; struct run *freelist;
u64 size;
u64 nfree; u64 nfree;
} __attribute__ ((aligned (CACHELINE))); } __mpalign__;
extern struct kmem kmems[NCPU]; extern struct kmem kmems[NCPU];
...@@ -57,6 +57,7 @@ void iderw(struct buf*); ...@@ -57,6 +57,7 @@ void iderw(struct buf*);
// kalloc.c // kalloc.c
char* kalloc(void); char* kalloc(void);
char* ksalloc(void);
void kfree(void *); void kfree(void *);
void* kmalloc(u64); void* kmalloc(u64);
void kmfree(void*); void kmfree(void*);
......
...@@ -65,7 +65,7 @@ bootothers(void) ...@@ -65,7 +65,7 @@ bootothers(void)
// Tell bootother.S what stack to use and the address of apstart; // Tell bootother.S what stack to use and the address of apstart;
// it expects to find these two addresses stored just before // it expects to find these two addresses stored just before
// its first instruction. // its first instruction.
stack = kalloc(); stack = ksalloc();
*(u32*)(code-4) = (u32)v2p(&apstart); *(u32*)(code-4) = (u32)v2p(&apstart);
*(u64*)(code-12) = (u64)stack + KSTACKSIZE; *(u64*)(code-12) = (u64)stack + KSTACKSIZE;
......
#define NPROC 64 // maximum number of processes #define NPROC 64 // maximum number of processes
#define KSTACKSIZE 4096 // size of per-process kernel stack #define KSTACKSIZE 8192 // size of per-process kernel stack
#define NCPU 2 // maximum number of CPUs #define NCPU 2 // maximum number of CPUs
#define NOFILE 16 // open files per process #define NOFILE 16 // open files per process
#define NFILE 100 // open files per system #define NFILE 100 // open files per system
...@@ -14,3 +14,4 @@ ...@@ -14,3 +14,4 @@
#define CACHELINE 64 // cache line size #define CACHELINE 64 // cache line size
#define MTRACE 0 #define MTRACE 0
#define PHYSTOP 0xE000000 // use phys mem up to here as free pool #define PHYSTOP 0xE000000 // use phys mem up to here as free pool
#define CPUKSTACKS (NPROC + NCPU)
...@@ -134,7 +134,7 @@ allocproc(void) ...@@ -134,7 +134,7 @@ allocproc(void)
panic("allocproc: ns_insert"); panic("allocproc: ns_insert");
// Allocate kernel stack if possible. // Allocate kernel stack if possible.
if((p->kstack = kalloc()) == 0){ if((p->kstack = ksalloc()) == 0){
if (ns_remove(nspid, KI(p->pid), p) == 0) if (ns_remove(nspid, KI(p->pid), p) == 0)
panic("allocproc: ns_remove"); panic("allocproc: ns_remove");
rcu_delayed(p, kmfree); rcu_delayed(p, kmfree);
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论