Add EX_EARLY flag for extent_create, which skips locking. Required for
using extent subsystem in early bootstrap code, before caches are enabled. From skrll@
This commit is contained in:
parent
7bdf8d594a
commit
7de85ed29e
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fdt_machdep.c,v 1.12 2017/08/20 21:00:01 jakllsch Exp $ */
|
||||
/* $NetBSD: fdt_machdep.c,v 1.13 2017/08/24 11:33:28 jmcneill Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015-2017 Jared McNeill <jmcneill@invisible.ca>
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.12 2017/08/20 21:00:01 jakllsch Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.13 2017/08/24 11:33:28 jmcneill Exp $");
|
||||
|
||||
#include "opt_machdep.h"
|
||||
#include "opt_ddb.h"
|
||||
|
@ -230,7 +230,7 @@ fdt_build_bootconfig(uint64_t mem_addr, uint64_t mem_size)
|
|||
int index, error;
|
||||
|
||||
fdt_memory_ext = extent_create("FDT Memory", mem_addr, max_addr,
|
||||
fdt_memory_ext_storage, sizeof(fdt_memory_ext_storage), 0);
|
||||
fdt_memory_ext_storage, sizeof(fdt_memory_ext_storage), EX_EARLY);
|
||||
|
||||
for (index = 0;
|
||||
fdtbus_get_reg64(memory, index, &addr, &size) == 0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: subr_extent.c,v 1.81 2017/07/24 19:56:07 skrll Exp $ */
|
||||
/* $NetBSD: subr_extent.c,v 1.82 2017/08/24 11:33:28 jmcneill Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996, 1998, 2007 The NetBSD Foundation, Inc.
|
||||
|
@ -34,7 +34,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_extent.c,v 1.81 2017/07/24 19:56:07 skrll Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_extent.c,v 1.82 2017/08/24 11:33:28 jmcneill Exp $");
|
||||
|
||||
#ifdef _KERNEL
|
||||
#ifdef _KERNEL_OPT
|
||||
|
@ -131,6 +131,7 @@ extent_alloc_region_descriptor(struct extent *ex, int flags)
|
|||
if (ex->ex_flags & EXF_FIXED) {
|
||||
struct extent_fixed *fex = (struct extent_fixed *)ex;
|
||||
|
||||
if (!(ex->ex_flags & EXF_EARLY))
|
||||
mutex_enter(&ex->ex_lock);
|
||||
for (;;) {
|
||||
if ((rp = LIST_FIRST(&fex->fex_freelist)) != NULL) {
|
||||
|
@ -141,17 +142,21 @@ extent_alloc_region_descriptor(struct extent *ex, int flags)
|
|||
* need to remember that information.
|
||||
*/
|
||||
LIST_REMOVE(rp, er_link);
|
||||
mutex_exit(&ex->ex_lock);
|
||||
if (!(ex->ex_flags & EXF_EARLY))
|
||||
mutex_exit(&ex->ex_lock);
|
||||
return (rp);
|
||||
}
|
||||
if (flags & EX_MALLOCOK) {
|
||||
mutex_exit(&ex->ex_lock);
|
||||
if (!(ex->ex_flags & EXF_EARLY))
|
||||
mutex_exit(&ex->ex_lock);
|
||||
goto alloc;
|
||||
}
|
||||
if ((flags & EX_WAITOK) == 0) {
|
||||
mutex_exit(&ex->ex_lock);
|
||||
if (!(ex->ex_flags & EXF_EARLY))
|
||||
mutex_exit(&ex->ex_lock);
|
||||
return (NULL);
|
||||
}
|
||||
KASSERT(mutex_owned(&ex->ex_lock));
|
||||
ex->ex_flwanted = true;
|
||||
if ((flags & EX_CATCH) != 0)
|
||||
error = cv_wait_sig(&ex->ex_cv, &ex->ex_lock);
|
||||
|
@ -206,8 +211,10 @@ extent_free_region_descriptor(struct extent *ex, struct extent_region *rp)
|
|||
}
|
||||
|
||||
wake_em_up:
|
||||
ex->ex_flwanted = false;
|
||||
cv_broadcast(&ex->ex_cv);
|
||||
if (!(ex->ex_flags & EXF_EARLY)) {
|
||||
ex->ex_flwanted = false;
|
||||
cv_broadcast(&ex->ex_cv);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -297,6 +304,8 @@ extent_create(const char *name, u_long start, u_long end,
|
|||
ex->ex_flags |= EXF_FIXED;
|
||||
if (flags & EX_NOCOALESCE)
|
||||
ex->ex_flags |= EXF_NOCOALESCE;
|
||||
if (flags & EX_EARLY)
|
||||
ex->ex_flags |= EXF_EARLY;
|
||||
return (ex);
|
||||
}
|
||||
|
||||
|
@ -507,7 +516,8 @@ extent_alloc_region(struct extent *ex, u_long start, u_long size, int flags)
|
|||
return (ENOMEM);
|
||||
}
|
||||
|
||||
mutex_enter(&ex->ex_lock);
|
||||
if (!(ex->ex_flags & EXF_EARLY))
|
||||
mutex_enter(&ex->ex_lock);
|
||||
alloc_start:
|
||||
|
||||
/*
|
||||
|
@ -545,6 +555,7 @@ extent_alloc_region(struct extent *ex, u_long start, u_long size, int flags)
|
|||
* do so.
|
||||
*/
|
||||
if (flags & EX_WAITSPACE) {
|
||||
KASSERT(!(ex->ex_flags & EXF_EARLY));
|
||||
if ((flags & EX_CATCH) != 0)
|
||||
error = cv_wait_sig(&ex->ex_cv,
|
||||
&ex->ex_lock);
|
||||
|
@ -556,7 +567,8 @@ extent_alloc_region(struct extent *ex, u_long start, u_long size, int flags)
|
|||
goto alloc_start;
|
||||
mutex_exit(&ex->ex_lock);
|
||||
} else {
|
||||
mutex_exit(&ex->ex_lock);
|
||||
if (!(ex->ex_flags & EXF_EARLY))
|
||||
mutex_exit(&ex->ex_lock);
|
||||
error = EAGAIN;
|
||||
}
|
||||
extent_free_region_descriptor(ex, myrp);
|
||||
|
@ -576,7 +588,8 @@ extent_alloc_region(struct extent *ex, u_long start, u_long size, int flags)
|
|||
* at the beginning of the region list. Insert ourselves.
|
||||
*/
|
||||
extent_insert_and_optimize(ex, start, size, flags, last, myrp);
|
||||
mutex_exit(&ex->ex_lock);
|
||||
if (!(ex->ex_flags & EXF_EARLY))
|
||||
mutex_exit(&ex->ex_lock);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -1042,7 +1055,8 @@ extent_free(struct extent *ex, u_long start, u_long size, int flags)
|
|||
return (ENOMEM);
|
||||
}
|
||||
|
||||
mutex_enter(&ex->ex_lock);
|
||||
if (!(ex->ex_flags & EXF_EARLY))
|
||||
mutex_enter(&ex->ex_lock);
|
||||
|
||||
/*
|
||||
* Find region and deallocate. Several possibilities:
|
||||
|
@ -1125,7 +1139,8 @@ extent_free(struct extent *ex, u_long start, u_long size, int flags)
|
|||
}
|
||||
|
||||
/* Region not found, or request otherwise invalid. */
|
||||
mutex_exit(&ex->ex_lock);
|
||||
if (!(ex->ex_flags & EXF_EARLY))
|
||||
mutex_exit(&ex->ex_lock);
|
||||
extent_print(ex);
|
||||
printf("extent_free: start 0x%lx, end 0x%lx\n", start, end);
|
||||
panic("extent_free: region not found");
|
||||
|
@ -1133,8 +1148,10 @@ extent_free(struct extent *ex, u_long start, u_long size, int flags)
|
|||
done:
|
||||
if (nrp != NULL)
|
||||
extent_free_region_descriptor(ex, nrp);
|
||||
cv_broadcast(&ex->ex_cv);
|
||||
mutex_exit(&ex->ex_lock);
|
||||
if (!(ex->ex_flags & EXF_EARLY)) {
|
||||
cv_broadcast(&ex->ex_cv);
|
||||
mutex_exit(&ex->ex_lock);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: extent.h,v 1.25 2017/07/27 10:04:28 skrll Exp $ */
|
||||
/* $NetBSD: extent.h,v 1.26 2017/08/24 11:33:28 jmcneill Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996, 1998 The NetBSD Foundation, Inc.
|
||||
|
@ -73,8 +73,9 @@ struct extent_fixed {
|
|||
/* ex_flags; for internal use only */
|
||||
#define EXF_FIXED __BIT(0) /* extent uses fixed storage */
|
||||
#define EXF_NOCOALESCE __BIT(1) /* coalescing of regions not allowed */
|
||||
#define EXF_EARLY __BIT(2) /* no need to lock */
|
||||
|
||||
#define EXF_BITS "\20\2NOCOALESCE\1FIXED"
|
||||
#define EXF_BITS "\20\3EARLY\2NOCOALESCE\1FIXED"
|
||||
|
||||
/* misc. flags passed to extent functions */
|
||||
#define EX_NOWAIT 0 /* not safe to sleep */
|
||||
|
@ -85,6 +86,7 @@ struct extent_fixed {
|
|||
#define EX_MALLOCOK __BIT(4) /* safe to call kmem_alloc() */
|
||||
#define EX_WAITSPACE __BIT(5) /* wait for space to become free */
|
||||
#define EX_BOUNDZERO __BIT(6) /* boundary lines start at 0 */
|
||||
#define EX_EARLY __BIT(7) /* safe for early kernel bootstrap */
|
||||
|
||||
/*
|
||||
* Special place holders for "alignment" and "boundary" arguments,
|
||||
|
|
Loading…
Reference in New Issue