diff options
| -rw-r--r-- | defs.h | 5 | ||||
| -rw-r--r-- | kalloc.c | 89 | ||||
| -rw-r--r-- | main.c | 4 | ||||
| -rw-r--r-- | mmu.h | 2 | ||||
| -rw-r--r-- | param.h | 4 | ||||
| -rw-r--r-- | pipe.c | 6 | ||||
| -rw-r--r-- | proc.c | 6 | ||||
| -rw-r--r-- | umalloc.c | 4 | ||||
| -rw-r--r-- | vm.c | 17 | 
9 files changed, 46 insertions, 91 deletions
| @@ -60,9 +60,8 @@ extern uchar    ioapicid;  void            ioapicinit(void);  // kalloc.c -extern int      nfreemem; -char*           kalloc(int); -void            kfree(char*, int); +char*           kalloc(void); +void            kfree(char*);  void            kinit(char*,uint);  // kbd.c @@ -1,8 +1,6 @@  // Physical memory allocator, intended to allocate -// memory for user processes. Allocates in 4096-byte pages. -// Free list is kept sorted and combines adjacent pages into -// long runs, to make it easier to allocate big segments. -// This combining is not useful now that xv6 uses paging. +// memory for user processes, kernel stacks, page table pages, +// and pipe buffers. Allocates 4096-byte pages.  #include "types.h"  #include "defs.h" @@ -12,7 +10,6 @@  struct run {    struct run *next; -  int len; // bytes  };  struct { @@ -20,92 +17,52 @@ struct {    struct run *freelist;  } kmem; -int nfreemem; -  // Initialize free list of physical pages.  void  kinit(char *p, uint len)  {    initlock(&kmem.lock, "kmem"); -  nfreemem = 0; -  kfree(p, len); +  char *p1 = (char*)PGROUNDUP((uint)p); +  char *p2 = PGROUNDDOWN(p + len); +  for( ; p1 < p2; p1 += 4096) +    kfree(p1);  } -// Free the len bytes of memory pointed at by v, +// Free the page of physical memory pointed at by v,  // which normally should have been returned by a -// call to kalloc(len).  (The exception is when +// call to kalloc().  (The exception is when  // initializing the allocator; see kinit above.)  void -kfree(char *v, int len) +kfree(char *v)  { -  struct run *r, *rend, **rp, *p, *pend; +  struct run *r; -  if(len <= 0 || len % PGSIZE) +  if(((uint) v) % PGSIZE || (uint)v < 1024*1024 || (uint)v >= PHYSTOP)       panic("kfree");    // Fill with junk to catch dangling refs. -  memset(v, 1, len); +  memset(v, 1, PGSIZE);    acquire(&kmem.lock); -  nfreemem += len; -  p = (struct run*)v; -  pend = (struct run*)(v + len); -  for(rp=&kmem.freelist; (r=*rp) != 0 && r <= pend; rp=&r->next){ -    rend = (struct run*)((char*)r + r->len); -    if(r <= p && p < rend) { -      cprintf("freeing a free page: r = 0x%x p = 0x%x rend = 0x%x\n",  -	      r, p, rend); -      panic("freeing free page"); -    } -    if(rend == p){  // r before p: expand r to include p -      r->len += len; -      if(r->next && r->next == pend){  // r now next to r->next? -        r->len += r->next->len; -        r->next = r->next->next; -      } -      goto out; -    } -    if(pend == r){  // p before r: expand p to include, replace r -      p->len = len + r->len; -      p->next = r->next; -      *rp = p; -      goto out; -    } -  } -  // Insert p before r in list. -  p->len = len; -  p->next = r; -  *rp = p; - - out: +  r = (struct run *) v; +  r->next = kmem.freelist; +  kmem.freelist = r;    release(&kmem.lock);  } -// Allocate n bytes of physical memory. -// Returns a kernel-segment pointer. +// 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(int n) +kalloc()  { -  char *p; -  struct run *r, **rp; - -  if(n % PGSIZE || n <= 0) -    panic("kalloc"); +  struct run *r;    acquire(&kmem.lock); -  for(rp=&kmem.freelist; (r=*rp) != 0; rp=&r->next){ -    if(r->len >= n){ -      r->len -= n; -      p = (char*)r + r->len; -      if(r->len == 0) -        *rp = r->next; -      nfreemem -= n; -      release(&kmem.lock); -      return p; -    } -  } +  r = kmem.freelist; +  if(r) +    kmem.freelist = r->next;    release(&kmem.lock); -  return 0; +  return (char*) r;  } @@ -28,7 +28,7 @@ main(void)  void  jkstack(void)  { -  char *kstack = kalloc(PGSIZE); +  char *kstack = kalloc();    if (!kstack)      panic("jkstack\n");    char *top = kstack + PGSIZE; @@ -92,7 +92,7 @@ bootothers(void)        continue;      // Fill in %esp, %eip and start code on cpu. -    stack = kalloc(KSTACKSIZE); +    stack = kalloc();      *(void**)(code-4) = stack + KSTACKSIZE;      *(void**)(code-8) = mpmain;      lapicstartap(c->id, (uint)code); @@ -112,7 +112,7 @@ struct segdesc {  #define PDXSHIFT	22		// offset of PDX in a linear address  #define PGROUNDUP(sz)  (((sz)+PGSIZE-1) & ~(PGSIZE-1)) -#define PGROUNDDOWN(a) ((char*)((((unsigned int)a) & ~(PGSIZE-1)))) +#define PGROUNDDOWN(a) ((char*)((((unsigned int)(a)) & ~(PGSIZE-1))))  // Page table/directory entry flags.  #define PTE_P		0x001	// Present @@ -1,6 +1,5 @@  #define NPROC        64  // maximum number of processes -#define PAGE       4096  // conveniently chosen to be equal to PGSIZE -#define KSTACKSIZE PAGE  // size of per-process kernel stack +#define KSTACKSIZE 4096  // size of per-process kernel stack  #define NCPU          8  // maximum number of CPUs  #define NOFILE       16  // open files per process  #define NFILE       100  // open files per system @@ -8,3 +7,4 @@  #define NINODE       50  // maximum number of active i-nodes  #define NDEV         10  // maximum major device number  #define ROOTDEV       1  // device number of file system root disk +#define PHYSTOP  0x1000000 // use phys mem up to here as free pool @@ -27,7 +27,7 @@ pipealloc(struct file **f0, struct file **f1)    *f0 = *f1 = 0;    if((*f0 = filealloc()) == 0 || (*f1 = filealloc()) == 0)      goto bad; -  if((p = (struct pipe*)kalloc(PAGE)) == 0) +  if((p = (struct pipe*)kalloc()) == 0)      goto bad;    p->readopen = 1;    p->writeopen = 1; @@ -47,7 +47,7 @@ pipealloc(struct file **f0, struct file **f1)  //PAGEBREAK: 20   bad:    if(p) -    kfree((char*)p, PAGE); +    kfree((char*)p);    if(*f0)      fileclose(*f0);    if(*f1) @@ -68,7 +68,7 @@ pipeclose(struct pipe *p, int writable)    }    if(p->readopen == 0 && p->writeopen == 0) {      release(&p->lock); -    kfree((char*)p, PAGE); +    kfree((char*)p);    } else      release(&p->lock);  } @@ -84,7 +84,7 @@ found:    release(&ptable.lock);    // Allocate kernel stack if possible. -  if((p->kstack = kalloc(KSTACKSIZE)) == 0){ +  if((p->kstack = kalloc()) == 0){      p->state = UNUSED;      return 0;    } @@ -169,7 +169,7 @@ fork(void)    // Copy process state from p.    if (!(np->pgdir = copyuvm(proc->pgdir, proc->sz))) { -    kfree(np->kstack, KSTACKSIZE); +    kfree(np->kstack);      np->kstack = 0;      np->state = UNUSED;      return -1; @@ -418,7 +418,7 @@ wait(void)        if(p->state == ZOMBIE){          // Found one.          pid = p->pid; -        kfree(p->kstack, KSTACKSIZE); +        kfree(p->kstack);          p->kstack = 0;          freevm(p->pgdir);          p->state = UNUSED; @@ -49,8 +49,8 @@ morecore(uint nu)    char *p;    Header *hp; -  if(nu < PAGE) -    nu = PAGE; +  if(nu < 4096) +    nu = 4096;    p = sbrk(nu * sizeof(Header));    if(p == (char*) -1)      return 0; @@ -29,7 +29,6 @@  // (both in physical memory and in the kernel's virtual address  // space). -#define PHYSTOP  0x1000000  #define USERTOP  0xA0000  static uint kerntext;  // Linker starts kernel at 1MB @@ -53,7 +52,7 @@ walkpgdir(pde_t *pgdir, const void *va, int create)    pde = &pgdir[PDX(va)];    if (*pde & PTE_P) {      pgtab = (pte_t*) PTE_ADDR(*pde); -  } else if (!create || !(r = (uint) kalloc(PGSIZE))) +  } else if (!create || !(r = (uint) kalloc()))      return 0;    else {      pgtab = (pte_t*) r; @@ -156,7 +155,7 @@ setupkvm(void)    pde_t *pgdir;    // Allocate page directory -  if (!(pgdir = (pde_t *) kalloc(PGSIZE))) +  if (!(pgdir = (pde_t *) kalloc()))      return 0;    memset(pgdir, 0, PGSIZE);    // Map IO space from 640K to 1Mbyte @@ -206,7 +205,7 @@ allocuvm(pde_t *pgdir, char *addr, uint sz)    for(a = first; a <= last; a += PGSIZE){      pte_t *pte = walkpgdir(pgdir, a, 0);      if(pte == 0 || (*pte & PTE_P) == 0){ -      char *mem = kalloc(PGSIZE); +      char *mem = kalloc();        if(mem == 0){          // XXX clean up?          return 0; @@ -235,7 +234,7 @@ deallocuvm(pde_t *pgdir, char *addr, uint sz)        uint pa = PTE_ADDR(*pte);        if(pa == 0)          panic("deallocuvm"); -      kfree((void *) pa, PGSIZE); +      kfree((void *) pa);        *pte = 0;      }    } @@ -260,15 +259,15 @@ freevm(pde_t *pgdir)  	  uint pa = PTE_ADDR(pgtab[j]);  	  uint va = PGADDR(i, j, 0);  	  if (va < USERTOP)   // user memory -            kfree((void *) pa, PGSIZE); +            kfree((void *) pa);  	  pgtab[j] = 0;  	}        } -      kfree((void *) da, PGSIZE); +      kfree((void *) da);        pgdir[i] = 0;      }    } -  kfree((void *) pgdir, PGSIZE); +  kfree((void *) pgdir);  }  int @@ -324,7 +323,7 @@ copyuvm(pde_t *pgdir, uint sz)        panic("copyuvm: pte should exist\n");      if(*pte & PTE_P){        pa = PTE_ADDR(*pte); -      if (!(mem = kalloc(PGSIZE))) +      if (!(mem = kalloc()))          return 0;        memmove(mem, (char *)pa, PGSIZE);        if (!mappages(d, (void *)i, PGSIZE, PADDR(mem), PTE_W|PTE_U)) | 
