Command to print total kernel heap usage for debugging.
This commit is contained in:
		| @@ -129,6 +129,7 @@ uint32_t random(void); | ||||
| void *kmalloc(size_t size); | ||||
| void kfree(void *ptr); | ||||
| void kheap_printstats(void); | ||||
| void kheap_printused(void); | ||||
| void kheap_nextgeneration(void); | ||||
| void kheap_dump(void); | ||||
| void kheap_dumpall(void); | ||||
|   | ||||
| @@ -376,6 +376,18 @@ cmd_kheapstats(int nargs, char **args) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static | ||||
| int | ||||
| cmd_kheapused(int nargs, char **args) | ||||
| { | ||||
| 	(void)nargs; | ||||
| 	(void)args; | ||||
|  | ||||
| 	kheap_printused(); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static | ||||
| int | ||||
| cmd_kheapgeneration(int nargs, char **args) | ||||
| @@ -541,6 +553,7 @@ static const char *mainmenu[] = { | ||||
| 	"[?o] Operations menu                ", | ||||
| 	"[?t] Tests menu                     ", | ||||
| 	"[kh] Kernel heap stats              ", | ||||
| 	"[khu] Kernel heap usage             ", | ||||
| 	"[khgen] Next kernel heap generation ", | ||||
| 	"[khdump] Dump kernel heap           ", | ||||
| 	"[q] Quit and shut down              ", | ||||
| @@ -593,6 +606,7 @@ static struct { | ||||
|  | ||||
| 	/* stats */ | ||||
| 	{ "kh",         cmd_kheapstats }, | ||||
| 	{ "khu",        cmd_kheapused }, | ||||
| 	{ "khgen",      cmd_kheapgeneration }, | ||||
| 	{ "khdump",     cmd_kheapdump }, | ||||
|  | ||||
|   | ||||
| @@ -31,6 +31,8 @@ | ||||
| #include <lib.h> | ||||
| #include <spinlock.h> | ||||
| #include <vm.h> | ||||
| #include <kern/secret.h> | ||||
| #include <test.h> | ||||
|  | ||||
| /* | ||||
|  * Kernel malloc. | ||||
| @@ -743,8 +745,8 @@ kheap_dumpall(void) | ||||
|  * Print the allocated/freed map of a single kernel heap page. | ||||
|  */ | ||||
| static | ||||
| void | ||||
| subpage_stats(struct pageref *pr) | ||||
| unsigned long | ||||
| subpage_stats(struct pageref *pr, bool quiet) | ||||
| { | ||||
| 	vaddr_t prpage, fla; | ||||
| 	struct freelist *fl; | ||||
| @@ -779,19 +781,22 @@ subpage_stats(struct pageref *pr) | ||||
| 			freemap[index/32] |= (1<<(index%32)); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	kprintf("at 0x%08lx: size %-4lu  %u/%u free\n", | ||||
| 		(unsigned long)prpage, (unsigned long) sizes[blktype], | ||||
| 		(unsigned) pr->nfree, n); | ||||
| 	kprintf("   "); | ||||
| 	for (i=0; i<n; i++) { | ||||
| 		int val = (freemap[i/32] & (1<<(i%32)))!=0; | ||||
| 		kprintf("%c", val ? '.' : '*'); | ||||
| 		if (i%64==63 && i<n-1) { | ||||
| 			kprintf("\n   "); | ||||
| 	 | ||||
| 	if (!quiet) {	 | ||||
| 		kprintf("at 0x%08lx: size %-4lu  %u/%u free\n", | ||||
| 				(unsigned long)prpage, (unsigned long) sizes[blktype], | ||||
| 				(unsigned) pr->nfree, n); | ||||
| 		kprintf("   "); | ||||
| 		for (i=0; i<n; i++) { | ||||
| 			int val = (freemap[i/32] & (1<<(i%32)))!=0; | ||||
| 			kprintf("%c", val ? '.' : '*'); | ||||
| 			if (i%64==63 && i<n-1) { | ||||
| 				kprintf("\n   "); | ||||
| 			} | ||||
| 		} | ||||
| 		kprintf("\n"); | ||||
| 	} | ||||
| 	kprintf("\n"); | ||||
| 	return ((unsigned long)sizes[blktype] * (n - (unsigned) pr->nfree)); | ||||
| } | ||||
|  | ||||
| /* | ||||
| @@ -806,14 +811,36 @@ kheap_printstats(void) | ||||
| 	spinlock_acquire(&kmalloc_spinlock); | ||||
|  | ||||
| 	kprintf("Subpage allocator status:\n"); | ||||
|  | ||||
| 	 | ||||
| 	for (pr = allbase; pr != NULL; pr = pr->next_all) { | ||||
| 		subpage_stats(pr); | ||||
| 		subpage_stats(pr, false); | ||||
| 	} | ||||
|  | ||||
| 	spinlock_release(&kmalloc_spinlock); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Print the whole heap. | ||||
|  */ | ||||
| void | ||||
| kheap_printused(void) | ||||
| { | ||||
| 	struct pageref *pr; | ||||
| 	unsigned long total = 0; | ||||
| 	/* print the whole thing with interrupts off */ | ||||
| 	spinlock_acquire(&kmalloc_spinlock); | ||||
| 	 | ||||
| 	for (pr = allbase; pr != NULL; pr = pr->next_all) { | ||||
| 		total += subpage_stats(pr, true); | ||||
| 	} | ||||
|  | ||||
| 	spinlock_release(&kmalloc_spinlock); | ||||
| 	 | ||||
| 	char total_string[32]; | ||||
| 	snprintf(total_string, sizeof(total_string), "%lu", total); | ||||
| 	ksecprintf(SECRET, total_string, "khu"); | ||||
| } | ||||
|  | ||||
| //////////////////////////////////////// | ||||
|  | ||||
| /* | ||||
|   | ||||
		Reference in New Issue
	
	Block a user