patch-pre2.0.14-final2.0 linux/mm/kmalloc.c
Next file: linux/net/core/sock.c
Previous file: linux/kernel/sysctl.c
Back to the patch index
Back to the overall index
- Lines: 120
- Date:
Sat Jun 8 18:12:33 1996
- Orig file:
pre2.0.14/linux/mm/kmalloc.c
- Orig date:
Mon Jun 3 16:46:59 1996
diff -u --recursive --new-file pre2.0.14/linux/mm/kmalloc.c linux/mm/kmalloc.c
@@ -375,69 +375,78 @@
return NULL;
}
-void kfree(void *ptr)
+void kfree(void *__ptr)
{
- int size, dma;
+ int dma;
unsigned long flags;
- int order;
- register struct block_header *p;
+ unsigned int order;
struct page_descriptor *page, **pg;
+ struct size_descriptor *bucket;
- if (!ptr)
- return;
- p = ((struct block_header *) ptr) - 1;
- dma = 0;
- page = PAGE_DESC(p);
+ if (!__ptr)
+ goto null_kfree;
+#define ptr ((struct block_header *) __ptr)
+ page = PAGE_DESC(ptr);
+ __ptr = ptr - 1;
+ if (~PAGE_MASK & (unsigned long)page->next)
+ goto bad_order;
order = page->order;
- pg = &sizes[order].firstfree;
- if (p->bh_flags == MF_DMA) {
+ if (order >= sizeof(sizes) / sizeof(sizes[0]))
+ goto bad_order;
+ bucket = sizes + order;
+ dma = 0;
+ pg = &bucket->firstfree;
+ if (ptr->bh_flags == MF_DMA) {
dma = 1;
- p->bh_flags = MF_USED;
- pg = &sizes[order].dmafree;
- }
-
- if ((order < 0) ||
- (order >= sizeof(sizes) / sizeof(sizes[0])) ||
- (((long) (page->next)) & ~PAGE_MASK) ||
- (p->bh_flags != MF_USED)) {
- printk("kfree of non-kmalloced memory: %p, next= %p, order=%d\n",
- p, page->next, page->order);
- return;
+ ptr->bh_flags = MF_USED;
+ pg = &bucket->dmafree;
}
- size = p->bh_length;
- p->bh_flags = MF_FREE; /* As of now this block is officially free */
+ if (ptr->bh_flags != MF_USED)
+ goto bad_order;
+ ptr->bh_flags = MF_FREE; /* As of now this block is officially free */
#ifdef SADISTIC_KMALLOC
- memset(p+1, 0xe0, size);
+ memset(ptr+1, 0xe0, ptr->bh_length);
#endif
save_flags(flags);
cli();
- p->bh_next = page->firstfree;
- page->firstfree = p;
- page->nfree++;
- if (page->nfree == 1) {
+ bucket->nfrees++;
+ bucket->nbytesmalloced -= ptr->bh_length;
+
+ ptr->bh_next = page->firstfree;
+ page->firstfree = ptr;
+ if (!page->nfree++) {
/* Page went from full to one free block: put it on the freelist. */
+ if (bucket->nblocks == 1)
+ goto free_page;
page->next = *pg;
*pg = page;
}
/* If page is completely free, free it */
- if (page->nfree == NBLOCKS(order)) {
+ if (page->nfree == bucket->nblocks) {
for (;;) {
struct page_descriptor *tmp = *pg;
- if (!tmp) {
- printk("Ooops. page %p doesn't show on freelist.\n", page);
- break;
- }
- if (tmp == page) {
- *pg = page->next;
+ if (!tmp)
+ goto not_on_freelist;
+ if (tmp == page)
break;
- }
pg = &tmp->next;
}
- sizes[order].npages--;
- free_kmalloc_pages(page, sizes[order].gfporder, dma);
+ *pg = page->next;
+free_page:
+ bucket->npages--;
+ free_kmalloc_pages(page, bucket->gfporder, dma);
}
- sizes[order].nfrees++;
- sizes[order].nbytesmalloced -= size;
+ restore_flags(flags);
+null_kfree:
+ return;
+
+bad_order:
+ printk("kfree of non-kmalloced memory: %p, next= %p, order=%d\n",
+ ptr+1, page->next, page->order);
+ return;
+
+not_on_freelist:
+ printk("Ooops. page %p doesn't show on freelist.\n", page);
restore_flags(flags);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this