33MALLOC_DEFINE(M_RINGBUF,
"ring-buffer",
"ringbuffer structure");
37MALLOC_DEFINE(M_HASHMAP_NODE,
"hashmap-node",
"hashmap node structure");
40#define KVMEM_GUARD PAGE_SIZE
59 M_QNODE.qnode = (
void *) 0xDEADBEEF;
63 panic(
"kvmem: no memory for its arena");
112 return (
void *)
seg->base;
161 printk(
"kfree: %p isn't an object kmalloc() gave\n", ptr);
162 panic(
"kfree of something kmalloc() didn't give");
181MALLOC_DEFINE(M_KVMEM_TEST,
"kvmem-test",
"kvmem self-test object");
208 for (
int round = 0; round < 2; ++round) {
215 if (!(obj[i] =
kmalloc(size[i], &M_KVMEM_TEST, 0)))
216 return "an allocation failed";
219 return "an object isn't on a page";
222 return "a guard page is mapped";
224 memset(obj[i], i + 1, size[i]);
228 for (
size_t b = 0; obj[i] && b < size[i]; b += 97)
229 if (obj[i][b] != (
uint8_t) (i + 1))
230 return "an object was overwritten";
233 for (
int i = round; i <
TEST_OBJS; i += 3 - round) {
240 return "the type's count is wrong";
243 for (
int i =
TEST_OBJS - 1; i >= 0; --i) {
248 if (M_KVMEM_TEST.nr || M_KVMEM_TEST.total)
249 return "the type still counts objects";
252 return "the arena isn't as it was";
255 return "free segments didn't merge";
269 printk(
"kvmem: self-test failed: %s\n", err);
271 printk(
"kvmem: self-test passed\n");
280 volatile char *buf =
kmalloc(3000, &M_KVMEM_TEST, 0);
283 printk(
"kvmem: writing past %p's end, at %p\n", buf, past);
286 printk(
"kvmem: the guard page didn't fault\n");
struct vm_page * mm_page_alloc(void)
Allocates a free page of physical memory.
void mm_page_dealloc(paddr_t paddr)
Frees a page of physical memory, back to the zone it came from.
void slab_free(void *ptr)
Frees an object of a slab.
static const char * kvmem_selftest_run(void)
Allocates objects of many sizes and checks that each is on pages of its own, that its guard page isn'...
static void kvmem_unmap(vaddr_t base, size_t size)
Unmaps the pages of an object at base, and gives them back to the buddy allocator.
static size_t kvmem_segs(void)
Returns how many segments, used and free, the arena has.
int slab_owns(void *ptr)
Says whether an object is a slab's, for kfree().
void * slab_alloc(size_t size, struct malloc_type *type)
Allocates a small object, from a slab of its malloc type and size class, making a new slab if none ha...
struct queue * malloc_types
static void * kvmem_alloc(size_t size, struct malloc_type *type)
Allocates an object of whole pages, with its guard page after it.
#define MALLOC_DEFINE(type, _name, _desc)
void * kmalloc(size_t size, struct malloc_type *type, int flags)
Allocates memory for one of the kernel's structures.
void kfree(void *)
Frees an object that kmalloc() gave.
void * memset(void *dst, int c, size_t n)
Sets n bytes to c.
int pmap_add(struct pmap *pmap, vaddr_t va, paddr_t pa, uint32_t flags)
Maps a page in an address space, replacing what was mapped there.
paddr_t arch_page_get_mapping(struct pmap *pmap, vaddr_t vaddr)
Finds the page mapped at a virtual address of an address space.
void pmap_remove(struct pmap *pmap, vaddr_t sva, vaddr_t eva)
Unmaps the pages of a range of an address space, and flushes them from the TLBs that may have them.
int printk(const char *fmt,...)
Writes a kernel message, to the message buffer and the consoles.
A malloc type: what an allocation is for, which /proc/kvmem counts by.
A received segment, with its header in host byte order.
A page of physical memory (pages[] has one for every page of RAM).
paddr_t paddr
its physical address
struct pmap * pmap
its page tables (the architecture's)
A segment of an arena: a range that is either free or allocated.
An arena: a range, and its segments.
void kvmem_selftest(void)
Runs the allocator's self-test, for the kvmem.test kernel argument, and prints whether it passed.
void kvmem_setup(void)
Sets up the kernel's allocator at boot, once physical memory and the page tables are ready.
void kvmem_guardtest(void)
Writes one byte past the end of an object, for the kvmem.guard kernel argument: the guard page should...
struct vm_space kvm_space
#define VM_KRW
kernel read/write
int vmem_init(struct vmem *vm, const char *name, uintptr_t base, size_t size, size_t quantum)
Sets up an arena: the range [base, base + size), all free.
struct vmem_seg * vmem_alloc(struct vmem *vm, size_t size)
Allocates a range from an arena.
void vmem_free(struct vmem *vm, struct vmem_seg *seg)
Frees an allocated segment.
struct vmem_seg * vmem_find(struct vmem *vm, uintptr_t base)
Finds the allocated segment that starts at an address.