Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern comments. related to PR/44969
details: https://anonhg.NetBSD.org/src/rev/1bde6ba33b3b
branches: trunk
changeset: 767664:1bde6ba33b3b
user: yamt <yamt%NetBSD.org@localhost>
date: Tue Jul 26 13:09:11 2011 +0000
description:
comments. related to PR/44969
diffstat:
sys/kern/subr_vmem.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 47 insertions(+), 3 deletions(-)
diffs (116 lines):
diff -r 236b6e636572 -r 1bde6ba33b3b sys/kern/subr_vmem.c
--- a/sys/kern/subr_vmem.c Tue Jul 26 13:07:20 2011 +0000
+++ b/sys/kern/subr_vmem.c Tue Jul 26 13:09:11 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_vmem.c,v 1.58 2010/12/17 22:24:11 yamt Exp $ */
+/* $NetBSD: subr_vmem.c,v 1.59 2011/07/26 13:09:11 yamt Exp $ */
/*-
* Copyright (c)2006,2007,2008,2009 YAMAMOTO Takashi,
@@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_vmem.c,v 1.58 2010/12/17 22:24:11 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_vmem.c,v 1.59 2011/07/26 13:09:11 yamt Exp $");
#if defined(_KERNEL)
#include "opt_ddb.h"
@@ -289,6 +289,15 @@
return &vm->vm_freelist[idx];
}
+/*
+ * bt_freehead_toalloc: return the freelist for the given size and allocation
+ * strategy.
+ *
+ * for VM_INSTANTFIT, return the list in which any blocks are large enough
+ * for the requested size. otherwise, return the list which can have blocks
+ * large enough for the requested size.
+ */
+
static struct vmem_freelist *
bt_freehead_toalloc(vmem_t *vm, vmem_size_t size, vm_flag_t strat)
{
@@ -702,6 +711,9 @@
/*
* vmem_fit: check if a bt can satisfy the given restrictions.
+ *
+ * it's a caller's responsibility to ensure the region is big enough
+ * before calling us.
*/
static vmem_addr_t
@@ -711,7 +723,7 @@
vmem_addr_t start;
vmem_addr_t end;
- KASSERT(bt->bt_size >= size);
+ KASSERT(bt->bt_size >= size); /* caller's responsibility */
/*
* XXX assumption: vmem_addr_t and vmem_size_t are
@@ -912,6 +924,10 @@
if (align == 0) {
align = vm->vm_quantum_mask + 1;
}
+
+ /*
+ * allocate boundary tags before acquiring the vmem lock.
+ */
btnew = bt_alloc(vm, flags);
if (btnew == NULL) {
return VMEM_ADDR_NULL;
@@ -922,6 +938,9 @@
return VMEM_ADDR_NULL;
}
+ /*
+ * choose a free block from which we allocate.
+ */
retry_strat:
first = bt_freehead_toalloc(vm, size, strat);
end = &vm->vm_freelist[VMEM_MAXORDER];
@@ -930,6 +949,13 @@
VMEM_LOCK(vm);
vmem_check(vm);
if (strat == VM_INSTANTFIT) {
+ /*
+ * just choose the first block which satisfies our restrictions.
+ *
+ * note that we don't need to check the size of the blocks
+ * because any blocks found on these list should be larger than
+ * the given size.
+ */
for (list = first; list < end; list++) {
bt = LIST_FIRST(list);
if (bt != NULL) {
@@ -938,9 +964,27 @@
if (start != VMEM_ADDR_NULL) {
goto gotit;
}
+ /*
+ * don't bother to follow the bt_freelist link
+ * here. the list can be very long and we are
+ * told to run fast. blocks from the later free
+ * lists are larger and have better chances to
+ * satisfy our restrictions.
+ */
}
}
} else { /* VM_BESTFIT */
+ /*
+ * we assume that, for space efficiency, it's better to
+ * allocate from a smaller block. thus we will start searching
+ * from the lower-order list than VM_INSTANTFIT.
+ * however, don't bother to find the smallest block in a free
+ * list because the list can be very long. we can revisit it
+ * if/when it turns out to be a problem.
+ *
+ * note that the 'first' list can contain blocks smaller than
+ * the requested size. thus we need to check bt_size.
+ */
for (list = first; list < end; list++) {
LIST_FOREACH(bt, list, bt_freelist) {
if (bt->bt_size >= size) {
Home |
Main Index |
Thread Index |
Old Index