Slab Allocator is pointing to 0xfffffff???

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
RayanMargham
Member
Member
Posts: 59
Joined: Tue Jul 05, 2022 12:37 pm

Slab Allocator is pointing to 0xfffffff???

Post by RayanMargham »

hi im having a very weird issue that i cannot figure out, for some reason one of the slab->next fields is pointing to 0xffffffff??? i dont understand why and ive scanned through the code front and back and cannot figure this out

i might need an extra pair of eyes on this maybe im missing something

Code: Select all

#include "pmm.h"
#include "limine.h"
#include "mem/vmm.h"
#include "term/term.h"
#include "utils/basic.h"

#include <stdint.h>
result init_kmalloc();
typedef struct {
  struct pnode *next;
} __attribute__((packed)) pnode;
pnode head = {.next = NULL};
uint64_t get_free_pages();
spinlock_t pmmlock;
extern void *memset(void *s, int c, size_t n);
// minnium 16 cache size
typedef struct {
  struct slab *next;
  struct pnode *freelist;
  uint64_t obj_ammount
} __attribute__((packed)) slab;
typedef struct {
  uint64_t size;
  struct slab *slabs;
} cache;
cache caches[7];
result pmm_init() {
  spinlock_lock(&pmmlock);
  pnode *cur = &head;
  result ok = {.type = ERR, .err_msg = "pmm_init() failed"};
  kprintf("pmm_init(): entry count %d\n", memmap_request.response->entry_count);
  kprintf("%s(): The HHDM is 0x%lx\n", __FUNCTION__,
          hhdm_request.response->offset);
  for (uint64_t i = 0; i < memmap_request.response->entry_count; i++) {
    struct limine_memmap_entry *entry = memmap_request.response->entries[i];
    switch (entry->type) {
    case LIMINE_MEMMAP_USABLE:
      for (uint64_t i = 0; i < entry->length; i += 4096) {
        pnode *hi = (pnode *)(entry->base + i + hhdm_request.response->offset);
        memset(hi, 0, 4096);
        cur->next = (struct pnode *)hi;

        cur = hi;
      }
      break;
    }
  }
  kprintf("pmm_init(): FreeList Created\n");
  kprintf("pmm_init(): Free Pages %ju\n", get_free_pages());
  spinlock_unlock(&pmmlock);
  result ress = init_kmalloc();
  unwrap_or_panic(ress);
  ok.type = OKAY;
  ok.okay = true;
  return ok;
}
// i get the free pages
uint64_t get_free_pages() {
  pnode *cur = &head;
  uint64_t page = 0;
  while (cur != NULL) {
    page += 1;
    cur = (pnode *)cur->next;
  };
  return page;
}
// Returns a page with the hddm offset added
// remove to get physical address
void *pmm_alloc() {
  if (head.next == NULL) {
    return NULL;
  }
  pnode *him = (pnode *)head.next;
  head.next = (struct pnode *)him->next;
  memset(him, 0, 4096); // just in case :)
  return (void *)him;
}
// I expect to get a page phys + hhdm offset added
// if i dont my assert will fail
void pmm_dealloc(void *he) {
  if (he == NULL) {
    return;
  }
  assert((uint64_t)he >= hhdm_request.response->offset);
  memset(he, 0, 4096); // just in case :)
  pnode *convert = (pnode *)he;
  convert->next = head.next;
  head.next = (struct pnode *)convert;
}
slab *init_slab(uint64_t size) {
  assert(size > sizeof(pnode));
  void *page = pmm_alloc();
  uint64_t obj_amount = (4096 - sizeof(slab)) / size;
  slab *hdr = (slab *)page;
  hdr->obj_ammount = obj_amount;
  pnode *first = (pnode *)((uint64_t)page + sizeof(slab));
  pnode *cur = first;
  first->next = NULL;
  hdr->freelist = (struct pnode *)first;
  for (uint64_t i = 1; i < obj_amount; i++) {
    pnode *new = (pnode *)((uint64_t)first + (i * size));
    new->next = (struct pnode *)cur;
    cur = new;
  };
  return hdr;
}
void init_cache(cache *mod, uint64_t size) {
  mod->size = size;
  mod->slabs = (struct slab *)init_slab(size);
}
result init_kmalloc() {
  result ok = {.type = ERR, .err_msg = "init_kmalloc() failed"};
  init_cache(&caches[0], 16);
  init_cache(&caches[1], 32);
  init_cache(&caches[2], 64);
  init_cache(&caches[3], 128);
  init_cache(&caches[4], 256);
  init_cache(&caches[5], 512);
  init_cache(&caches[6], 1024);
  ok.type = OKAY;
  return ok;
}
void *slab_alloc(cache *mod) {
  if (mod->slabs == NULL || mod->size == 0) {
    return NULL;
  }
  slab *cur = (slab *)mod->slabs;
  while (true) {
    if (cur->freelist == NULL) {
      if (cur->next != NULL) {
        cur = (slab *)cur->next;
        continue;
      }
      break;
    }
    void *guy = cur->freelist;
    cur->freelist = ((pnode *)cur->freelist)->next;
    memset(guy, 0, mod->size);
    return guy;
  };
  cur->next = (struct slab *)init_slab(mod->size);
  cur = (slab *)cur->next;
  void *guy = cur->freelist;
  cur->freelist = ((pnode *)cur->freelist)->next;
  memset(guy, 0, mod->size);
  return guy;
}
void *slaballocate(uint64_t amount) {
  uint64_t olda = amount;
  amount = next_pow2(amount);
  assert(olda <= amount);
  for (int i = 0; i != 7; i++) {
    cache *c = &caches[i];
    assert(c->size != 0);
    return slab_alloc(c);
  }
  return NULL;
}
uint64_t cache_getmemoryused(cache *mod) {
  if (mod->slabs == NULL || mod->size == 0) {
    return 0;
  }
  uint64_t bytes = 0;
  slab *cur = (slab *)mod->slabs;
  while (true) {
    if (cur->freelist == NULL) {
      bytes += sizeof(slab) + (cur->obj_ammount * mod->size);
      if (cur->next != NULL) {
        cur = (slab *)cur->next;
        continue;
      }
      break;
    }
    bytes += sizeof(slab);
    pnode *n = (pnode *)cur->freelist;
    uint64_t free_nodes = 0;
    while (true) {
      if (n->next == NULL) {
        free_nodes += 1;
        break;
      }
      free_nodes += 1;
      n = (pnode *)n->next;
    }
    bytes += ((cur->obj_ammount - free_nodes) * mod->size) +
             (free_nodes * sizeof(pnode));
    if (cur->next != NULL) {
      cur = (slab *)cur->next;
      continue;
    }
    break;
  };
  return bytes;
}
void free_unused_slabs(cache *mod) {
  if (mod->slabs == NULL || mod->size == 0) {
    return;
  }
  slab *cur = (slab *)mod->slabs;
  slab *prev = NULL;
  while (true) {
    if (cur->freelist == NULL) {
      if (cur->next != NULL) {
        prev = cur;
        cur = (slab *)cur->next;
        continue;
      }
      break;
    }
    pnode *n = (pnode *)cur->freelist;
    uint64_t free_nodes = 0;
    while (true) {
      if (n->next == NULL) {
        free_nodes += 1;
        break;
      }
      free_nodes += 1;
      n = (pnode *)n->next;
    }
    kprintf(
        "free_unused_slabs(): free nodes in this slab %lu, obj ammount %lu\n",
        free_nodes, cur->obj_ammount);
    if (free_nodes == cur->obj_ammount) {
      if (prev != NULL) {
        prev->next = cur->next;
      }
      memset(cur, 0, 4096);
      pmm_dealloc((void *)cur);
    }
    if (cur->next != NULL) {
      prev = cur;
      cur = (slab *)cur->next;
      continue;
    } else {
    }
    break;
  };
}
void free_unused_slabcaches() {
  for (int i = 0; i != 7; i++) {
    cache *c = &caches[i];
    free_unused_slabs(c);
  }
}
uint64_t total_memory() {
  uint64_t total_bytes = 0;
  for (int i = 0; i != 7; i++) {
    cache *c = &caches[i];
    total_bytes += cache_getmemoryused(c);
  }
  total_bytes += kvmm_region_bytesused();
  return total_bytes;
}
void slabfree(void *addr) {
  uint64_t real_addr = (uint64_t)addr;
  if (real_addr == 0) {
    return;
  }
  slab *guy = (slab *)(real_addr & ~0xFFF);
  memset(addr, 0, sizeof(pnode));
  pnode *node = (pnode *)addr;

  pnode *old = (pnode *)guy->freelist;

  node->next = (struct pnode *)old;
  guy->freelist = (struct pnode *)node;
  pnode *counter = (pnode *)guy->freelist;
  unsigned int howmanynodes = 0;
  while (counter != NULL) {
    howmanynodes += 1;
    kprintf("counter: %p\n", (void *)counter);
    counter = (pnode *)counter->next;
  }
  if (howmanynodes == guy->obj_ammount) {
    kprintf("USELESS SLAB\n");
  }
}
this is the github for further context
https://github.com/rayanmargham/NyauxKC
RayanMargham
Member
Member
Posts: 59
Joined: Tue Jul 05, 2022 12:37 pm

Re: Slab Allocator is pointing to 0xfffffff???

Post by RayanMargham »

I really don't understand what im doing wrong here. here is the github though for extra context

https://github.com/rayanmargham/NyauxKC
RayanMargham
Member
Member
Posts: 59
Joined: Tue Jul 05, 2022 12:37 pm

Re: Slab Allocator is pointing to 0xfffffff???

Post by RayanMargham »

please someone help
RayanMargham
Member
Member
Posts: 59
Joined: Tue Jul 05, 2022 12:37 pm

Re: Slab Allocator is pointing to 0xfffffff???

Post by RayanMargham »

Ive gotten closer it seems but well, i dont understand whats going on
Image
Image
why is uacpi giving me garbage sizes and uacpi gave me a vmm region address and told me its 10 bytes wtf
RayanMargham
Member
Member
Posts: 59
Joined: Tue Jul 05, 2022 12:37 pm

Re: Slab Allocator is pointing to 0xfffffff???

Post by RayanMargham »

its memory corruption and idk how to solve it
MichaelPetch
Member
Member
Posts: 797
Joined: Fri Aug 26, 2016 1:41 pm
Libera.chat IRC: mpetch

Re: Slab Allocator is pointing to 0xfffffff???

Post by MichaelPetch »

I haven't had time to spend any time on this. I just found this post. Try printing those sizes out in hex. I noticed that 18446744071562176816
is FFFFFFFF8001A930 and that looks awfully like a virtual memory address. Now why that happened who knows. Stack corruption? Memory corruption? I just don't think the values you are seeing are random garbage.
RayanMargham
Member
Member
Posts: 59
Joined: Tue Jul 05, 2022 12:37 pm

Re: Slab Allocator is pointing to 0xfffffff???

Post by RayanMargham »

UACPI_SIZED_FREES was not defined in all translation units.

also llvm bug with the cc runtime

i fixed it look at this :D
Image
Post Reply