kernel/vm/page.c
/*
 * Allocate a 4k, 16k or 64k page, splitting larger slabs into smaller sizes if
 * needed. Could eventually do some page movement to make contiguous memory.
 */
Allocate a 4k, 16k or 64k page, splitting larger slabs into smaller sizes if
needed. Could eventually do some page movement to make contiguous memory.
Allocate a 4k 16k or 64k page splitting larger slabs into smaller sizes if needed . Could eventually do some page movement to make contiguous memory .
struct Pageframe *AllocPageframe(vm_size size) {
  struct Pageframe *head = NULL;
  int t;
  if (size == 4096) {
    head = LIST_HEAD(&free_4k_pf_list);
    if (head != NULL) {
      LIST_REM_HEAD(&free_4k_pf_list, link);
    }
  }
  if (head == NULL && size == 16384) {
    head = LIST_HEAD(&free_16k_pf_list);
    if (head != NULL) {
      LIST_REM_HEAD(&free_16k_pf_list, link);
    }
  }
  if (head == NULL && size <= 65536) {
    head = LIST_HEAD(&free_64k_pf_list);
    if (head != NULL) {
      LIST_REM_HEAD(&free_64k_pf_list, link);
    }
  }
  if (head == NULL) {
    return NULL;
  }
  if (head->flags & PGF_INUSE) {
    Warn("**** Alloc Pageframe in-use");
  }
  if (head->size == 65536 && size == 16384) {
    for (t = 3; t > 0; t--) {
      head[(t * 16384) / PAGE_SIZE].size = 16384;
      head[(t * 16384) / PAGE_SIZE].flags = 0;
      LIST_ADD_HEAD(&free_16k_pf_list, head + t * (16384 / PAGE_SIZE), link);
    }
  } else if (head->size == 65536 && size == 4096) {
    for (t = 15; t > 0; t--) {
      head[(t * 4096) / PAGE_SIZE].size = 4096;
      head[(t * 4096) / PAGE_SIZE].flags = 0;
      LIST_ADD_HEAD(&free_4k_pf_list, head + t * (4096 / PAGE_SIZE), link);
    }
  }
  head->size = size;
  head->flags = PGF_INUSE;
  head->reference_cnt = 0;
  KASSERT(head->physical_addr < (128 * 1024 * 1024));
  PmapPageframeInit(&head->pmap_pageframe);
  vm_addr va = PmapPaToVa(head->physical_addr);
  memset((void *)va, 0, size);
  return head;
}
struct Pageframe * AllocPageframe ( vm_size size ) { struct Pageframe * head = NULL ; int t ; if ( size == 4096 ) { head = LIST_HEAD ( & free_4k_pf_list ) ; if ( head != NULL ) { LIST_REM_HEAD ( & free_4k_pf_list , link ) ; } } if ( head == NULL && size == 16384 ) { head = LIST_HEAD ( & free_16k_pf_list ) ; if ( head != NULL ) { LIST_REM_HEAD ( & free_16k_pf_list , link ) ; } } if ( head == NULL && size <= 65536 ) { head = LIST_HEAD ( & free_64k_pf_list ) ; if ( head != NULL ) { LIST_REM_HEAD ( & free_64k_pf_list , link ) ; } } if ( head == NULL ) { return NULL ; } if ( head -> flags & PGF_INUSE ) { Warn ( " " ) ; } if ( head -> size == 65536 && size == 16384 ) { for ( t = 3 ; t > 0 ; t -- ) { head [ ( t * 16384 ) / PAGE_SIZE ] . size = 16384 ; head [ ( t * 16384 ) / PAGE_SIZE ] . flags = 0 ; LIST_ADD_HEAD ( & free_16k_pf_list , head + t * ( 16384 / PAGE_SIZE ) , link ) ; } } else if ( head -> size == 65536 && size == 4096 ) { for ( t = 15 ; t > 0 ; t -- ) { head [ ( t * 4096 ) / PAGE_SIZE ] . size = 4096 ; head [ ( t * 4096 ) / PAGE_SIZE ] . flags = 0 ; LIST_ADD_HEAD ( & free_4k_pf_list , head + t * ( 4096 / PAGE_SIZE ) , link ) ; } } head -> size = size ; head -> flags = PGF_INUSE ; head -> reference_cnt = 0 ; KASSERT ( head -> physical_addr < ( 128 * 1024 * 1024 ) ) ; PmapPageframeInit ( & head -> pmap_pageframe ) ; vm_addr va = PmapPaToVa ( head -> physical_addr ) ; memset ( ( void * ) va , 0 , size ) ; return head ; }
Allocate a 4k, 16k or 64k page, splitting larger slabs into smaller sizes if
 needed.
Allocate a 4k 16k or 64k page splitting larger slabs into smaller sizes if needed .
// Split 64k slabs if needed into 4k or 16k allocations. // Ahh, this might be because root pages aren't all reserved?