expose struct devicelist alldevs again.
This commit is contained in:
parent
3f6efeccf9
commit
3c4095155a
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: subr_autoconf.c,v 1.256 2018/01/26 22:58:09 pgoyette Exp $ */
|
||||
/* $NetBSD: subr_autoconf.c,v 1.257 2018/03/04 07:12:18 mlelstv Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 2000 Christopher G. Demetriou
|
||||
@ -77,7 +77,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.256 2018/01/26 22:58:09 pgoyette Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.257 2018/03/04 07:12:18 mlelstv Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_ddb.h"
|
||||
@ -217,20 +217,12 @@ static TAILQ_HEAD(, finalize_hook) config_finalize_list =
|
||||
static int config_finalize_done;
|
||||
|
||||
/* list of all devices */
|
||||
static struct {
|
||||
kmutex_t lock;
|
||||
struct devicelist list;
|
||||
devgen_t gen;
|
||||
int nread;
|
||||
int nwrite;
|
||||
bool garbage;
|
||||
} alldevs __cacheline_aligned = {
|
||||
.list = TAILQ_HEAD_INITIALIZER(alldevs.list),
|
||||
.gen = 1,
|
||||
.nread = 0,
|
||||
.nwrite = 0,
|
||||
.garbage = false,
|
||||
};
|
||||
static struct devicelist alldevs = TAILQ_HEAD_INITIALIZER(alldevs);
|
||||
static kmutex_t alldevs_lock __cacheline_aligned;
|
||||
static devgen_t alldevs_gen = 1;
|
||||
static int alldevs_nread = 0;
|
||||
static int alldevs_nwrite = 0;
|
||||
static bool alldevs_garbage = false;
|
||||
|
||||
static int config_pending; /* semaphore for mountroot */
|
||||
static kmutex_t config_misc_lock;
|
||||
@ -349,7 +341,7 @@ config_init(void)
|
||||
|
||||
KASSERT(config_initialized == false);
|
||||
|
||||
mutex_init(&alldevs.lock, MUTEX_DEFAULT, IPL_VM);
|
||||
mutex_init(&alldevs_lock, MUTEX_DEFAULT, IPL_VM);
|
||||
|
||||
mutex_init(&config_misc_lock, MUTEX_DEFAULT, IPL_NONE);
|
||||
cv_init(&config_misc_cv, "cfgmisc");
|
||||
@ -1163,9 +1155,9 @@ number(char *ep, int n)
|
||||
/*
|
||||
* Expand the size of the cd_devs array if necessary.
|
||||
*
|
||||
* The caller must hold alldevs.lock. config_makeroom() may release and
|
||||
* re-acquire alldevs.lock, so callers should re-check conditions such
|
||||
* as alldevs.nwrite == 0 and alldevs.nread == 0 when config_makeroom()
|
||||
* The caller must hold alldevs_lock. config_makeroom() may release and
|
||||
* re-acquire alldevs_lock, so callers should re-check conditions such
|
||||
* as alldevs_nwrite == 0 and alldevs_nread == 0 when config_makeroom()
|
||||
* returns.
|
||||
*/
|
||||
static void
|
||||
@ -1174,8 +1166,8 @@ config_makeroom(int n, struct cfdriver *cd)
|
||||
int ondevs, nndevs;
|
||||
device_t *osp, *nsp;
|
||||
|
||||
KASSERT(mutex_owned(&alldevs.lock));
|
||||
alldevs.nwrite++;
|
||||
KASSERT(mutex_owned(&alldevs_lock));
|
||||
alldevs_nwrite++;
|
||||
|
||||
for (nndevs = MAX(4, cd->cd_ndevs); nndevs <= n; nndevs += nndevs)
|
||||
;
|
||||
@ -1188,21 +1180,21 @@ config_makeroom(int n, struct cfdriver *cd)
|
||||
osp = cd->cd_devs;
|
||||
|
||||
/*
|
||||
* Release alldevs.lock around allocation, which may
|
||||
* Release alldevs_lock around allocation, which may
|
||||
* sleep.
|
||||
*/
|
||||
mutex_exit(&alldevs.lock);
|
||||
mutex_exit(&alldevs_lock);
|
||||
nsp = kmem_alloc(sizeof(device_t[nndevs]), KM_SLEEP);
|
||||
mutex_enter(&alldevs.lock);
|
||||
mutex_enter(&alldevs_lock);
|
||||
|
||||
/*
|
||||
* If another thread moved the array while we did
|
||||
* not hold alldevs.lock, try again.
|
||||
* not hold alldevs_lock, try again.
|
||||
*/
|
||||
if (cd->cd_devs != osp) {
|
||||
mutex_exit(&alldevs.lock);
|
||||
mutex_exit(&alldevs_lock);
|
||||
kmem_free(nsp, sizeof(device_t[nndevs]));
|
||||
mutex_enter(&alldevs.lock);
|
||||
mutex_enter(&alldevs_lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1213,13 +1205,13 @@ config_makeroom(int n, struct cfdriver *cd)
|
||||
cd->cd_ndevs = nndevs;
|
||||
cd->cd_devs = nsp;
|
||||
if (ondevs != 0) {
|
||||
mutex_exit(&alldevs.lock);
|
||||
mutex_exit(&alldevs_lock);
|
||||
kmem_free(osp, sizeof(device_t[ondevs]));
|
||||
mutex_enter(&alldevs.lock);
|
||||
mutex_enter(&alldevs_lock);
|
||||
}
|
||||
}
|
||||
KASSERT(mutex_owned(&alldevs.lock));
|
||||
alldevs.nwrite--;
|
||||
KASSERT(mutex_owned(&alldevs_lock));
|
||||
alldevs_nwrite--;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1229,16 +1221,16 @@ static void
|
||||
config_devlink(device_t dev)
|
||||
{
|
||||
|
||||
mutex_enter(&alldevs.lock);
|
||||
mutex_enter(&alldevs_lock);
|
||||
|
||||
KASSERT(device_cfdriver(dev)->cd_devs[dev->dv_unit] == dev);
|
||||
|
||||
dev->dv_add_gen = alldevs.gen;
|
||||
dev->dv_add_gen = alldevs_gen;
|
||||
/* It is safe to add a device to the tail of the list while
|
||||
* readers and writers are in the list.
|
||||
*/
|
||||
TAILQ_INSERT_TAIL(&alldevs.list, dev, dv_list);
|
||||
mutex_exit(&alldevs.lock);
|
||||
TAILQ_INSERT_TAIL(&alldevs, dev, dv_list);
|
||||
mutex_exit(&alldevs_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1253,7 +1245,7 @@ config_devfree(device_t dev)
|
||||
}
|
||||
|
||||
/*
|
||||
* Caller must hold alldevs.lock.
|
||||
* Caller must hold alldevs_lock.
|
||||
*/
|
||||
static void
|
||||
config_devunlink(device_t dev, struct devicelist *garbage)
|
||||
@ -1262,10 +1254,10 @@ config_devunlink(device_t dev, struct devicelist *garbage)
|
||||
cfdriver_t cd = device_cfdriver(dev);
|
||||
int i;
|
||||
|
||||
KASSERT(mutex_owned(&alldevs.lock));
|
||||
KASSERT(mutex_owned(&alldevs_lock));
|
||||
|
||||
/* Unlink from device list. Link to garbage list. */
|
||||
TAILQ_REMOVE(&alldevs.list, dev, dv_list);
|
||||
TAILQ_REMOVE(&alldevs, dev, dv_list);
|
||||
TAILQ_INSERT_TAIL(garbage, dev, dv_list);
|
||||
|
||||
/* Remove from cfdriver's array. */
|
||||
@ -1663,7 +1655,7 @@ config_attach_pseudo(cfdata_t cf)
|
||||
}
|
||||
|
||||
/*
|
||||
* Caller must hold alldevs.lock.
|
||||
* Caller must hold alldevs_lock.
|
||||
*/
|
||||
static void
|
||||
config_collect_garbage(struct devicelist *garbage)
|
||||
@ -1672,20 +1664,20 @@ config_collect_garbage(struct devicelist *garbage)
|
||||
|
||||
KASSERT(!cpu_intr_p());
|
||||
KASSERT(!cpu_softintr_p());
|
||||
KASSERT(mutex_owned(&alldevs.lock));
|
||||
KASSERT(mutex_owned(&alldevs_lock));
|
||||
|
||||
while (alldevs.nwrite == 0 && alldevs.nread == 0 && alldevs.garbage) {
|
||||
TAILQ_FOREACH(dv, &alldevs.list, dv_list) {
|
||||
while (alldevs_nwrite == 0 && alldevs_nread == 0 && alldevs_garbage) {
|
||||
TAILQ_FOREACH(dv, &alldevs, dv_list) {
|
||||
if (dv->dv_del_gen != 0)
|
||||
break;
|
||||
}
|
||||
if (dv == NULL) {
|
||||
alldevs.garbage = false;
|
||||
alldevs_garbage = false;
|
||||
break;
|
||||
}
|
||||
config_devunlink(dv, garbage);
|
||||
}
|
||||
KASSERT(mutex_owned(&alldevs.lock));
|
||||
KASSERT(mutex_owned(&alldevs_lock));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1731,17 +1723,17 @@ config_detach(device_t dev, int flags)
|
||||
ca = dev->dv_cfattach;
|
||||
KASSERT(ca != NULL);
|
||||
|
||||
mutex_enter(&alldevs.lock);
|
||||
mutex_enter(&alldevs_lock);
|
||||
if (dev->dv_del_gen != 0) {
|
||||
mutex_exit(&alldevs.lock);
|
||||
mutex_exit(&alldevs_lock);
|
||||
#ifdef DIAGNOSTIC
|
||||
printf("%s: %s is already detached\n", __func__,
|
||||
device_xname(dev));
|
||||
#endif /* DIAGNOSTIC */
|
||||
return ENOENT;
|
||||
}
|
||||
alldevs.nwrite++;
|
||||
mutex_exit(&alldevs.lock);
|
||||
alldevs_nwrite++;
|
||||
mutex_exit(&alldevs_lock);
|
||||
|
||||
if (!detachall &&
|
||||
(flags & (DETACH_SHUTDOWN|DETACH_FORCE)) == DETACH_SHUTDOWN &&
|
||||
@ -1818,14 +1810,14 @@ config_detach(device_t dev, int flags)
|
||||
|
||||
out:
|
||||
config_alldevs_enter(&af);
|
||||
KASSERT(alldevs.nwrite != 0);
|
||||
--alldevs.nwrite;
|
||||
KASSERT(alldevs_nwrite != 0);
|
||||
--alldevs_nwrite;
|
||||
if (rv == 0 && dev->dv_del_gen == 0) {
|
||||
if (alldevs.nwrite == 0 && alldevs.nread == 0)
|
||||
if (alldevs_nwrite == 0 && alldevs_nread == 0)
|
||||
config_devunlink(dev, &af.af_garbage);
|
||||
else {
|
||||
dev->dv_del_gen = alldevs.gen;
|
||||
alldevs.garbage = true;
|
||||
dev->dv_del_gen = alldevs_gen;
|
||||
alldevs_garbage = true;
|
||||
}
|
||||
}
|
||||
config_alldevs_exit(&af);
|
||||
@ -2203,14 +2195,14 @@ static void
|
||||
config_alldevs_enter(struct alldevs_foray *af)
|
||||
{
|
||||
TAILQ_INIT(&af->af_garbage);
|
||||
mutex_enter(&alldevs.lock);
|
||||
mutex_enter(&alldevs_lock);
|
||||
config_collect_garbage(&af->af_garbage);
|
||||
}
|
||||
|
||||
static void
|
||||
config_alldevs_exit(struct alldevs_foray *af)
|
||||
{
|
||||
mutex_exit(&alldevs.lock);
|
||||
mutex_exit(&alldevs_lock);
|
||||
config_dump_garbage(&af->af_garbage);
|
||||
}
|
||||
|
||||
@ -2224,12 +2216,12 @@ device_lookup(cfdriver_t cd, int unit)
|
||||
{
|
||||
device_t dv;
|
||||
|
||||
mutex_enter(&alldevs.lock);
|
||||
mutex_enter(&alldevs_lock);
|
||||
if (unit < 0 || unit >= cd->cd_ndevs)
|
||||
dv = NULL;
|
||||
else if ((dv = cd->cd_devs[unit]) != NULL && dv->dv_del_gen != 0)
|
||||
dv = NULL;
|
||||
mutex_exit(&alldevs.lock);
|
||||
mutex_exit(&alldevs_lock);
|
||||
|
||||
return dv;
|
||||
}
|
||||
@ -2774,24 +2766,24 @@ deviter_init(deviter_t *di, deviter_flags_t flags)
|
||||
if ((flags & DEVITER_F_SHUTDOWN) != 0)
|
||||
flags |= DEVITER_F_RW;
|
||||
|
||||
mutex_enter(&alldevs.lock);
|
||||
mutex_enter(&alldevs_lock);
|
||||
if ((flags & DEVITER_F_RW) != 0)
|
||||
alldevs.nwrite++;
|
||||
alldevs_nwrite++;
|
||||
else
|
||||
alldevs.nread++;
|
||||
di->di_gen = alldevs.gen++;
|
||||
alldevs_nread++;
|
||||
di->di_gen = alldevs_gen++;
|
||||
di->di_flags = flags;
|
||||
|
||||
switch (di->di_flags & (DEVITER_F_LEAVES_FIRST|DEVITER_F_ROOT_FIRST)) {
|
||||
case DEVITER_F_LEAVES_FIRST:
|
||||
TAILQ_FOREACH(dv, &alldevs.list, dv_list) {
|
||||
TAILQ_FOREACH(dv, &alldevs, dv_list) {
|
||||
if (!deviter_visits(di, dv))
|
||||
continue;
|
||||
di->di_curdepth = MAX(di->di_curdepth, dv->dv_depth);
|
||||
}
|
||||
break;
|
||||
case DEVITER_F_ROOT_FIRST:
|
||||
TAILQ_FOREACH(dv, &alldevs.list, dv_list) {
|
||||
TAILQ_FOREACH(dv, &alldevs, dv_list) {
|
||||
if (!deviter_visits(di, dv))
|
||||
continue;
|
||||
di->di_maxdepth = MAX(di->di_maxdepth, dv->dv_depth);
|
||||
@ -2802,18 +2794,18 @@ deviter_init(deviter_t *di, deviter_flags_t flags)
|
||||
}
|
||||
|
||||
deviter_reinit(di);
|
||||
mutex_exit(&alldevs.lock);
|
||||
mutex_exit(&alldevs_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
deviter_reinit(deviter_t *di)
|
||||
{
|
||||
|
||||
KASSERT(mutex_owned(&alldevs.lock));
|
||||
KASSERT(mutex_owned(&alldevs_lock));
|
||||
if ((di->di_flags & DEVITER_F_RW) != 0)
|
||||
di->di_prev = TAILQ_LAST(&alldevs.list, devicelist);
|
||||
di->di_prev = TAILQ_LAST(&alldevs, devicelist);
|
||||
else
|
||||
di->di_prev = TAILQ_FIRST(&alldevs.list);
|
||||
di->di_prev = TAILQ_FIRST(&alldevs);
|
||||
}
|
||||
|
||||
device_t
|
||||
@ -2829,7 +2821,7 @@ deviter_next2(deviter_t *di)
|
||||
{
|
||||
device_t dv;
|
||||
|
||||
KASSERT(mutex_owned(&alldevs.lock));
|
||||
KASSERT(mutex_owned(&alldevs_lock));
|
||||
|
||||
dv = di->di_prev;
|
||||
|
||||
@ -2849,7 +2841,7 @@ deviter_next1(deviter_t *di)
|
||||
{
|
||||
device_t dv;
|
||||
|
||||
KASSERT(mutex_owned(&alldevs.lock));
|
||||
KASSERT(mutex_owned(&alldevs_lock));
|
||||
|
||||
do {
|
||||
dv = deviter_next2(di);
|
||||
@ -2863,7 +2855,7 @@ deviter_next(deviter_t *di)
|
||||
{
|
||||
device_t dv = NULL;
|
||||
|
||||
mutex_enter(&alldevs.lock);
|
||||
mutex_enter(&alldevs_lock);
|
||||
switch (di->di_flags & (DEVITER_F_LEAVES_FIRST|DEVITER_F_ROOT_FIRST)) {
|
||||
case 0:
|
||||
dv = deviter_next1(di);
|
||||
@ -2889,7 +2881,7 @@ deviter_next(deviter_t *di)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mutex_exit(&alldevs.lock);
|
||||
mutex_exit(&alldevs_lock);
|
||||
|
||||
return dv;
|
||||
}
|
||||
@ -2899,13 +2891,13 @@ deviter_release(deviter_t *di)
|
||||
{
|
||||
bool rw = (di->di_flags & DEVITER_F_RW) != 0;
|
||||
|
||||
mutex_enter(&alldevs.lock);
|
||||
mutex_enter(&alldevs_lock);
|
||||
if (rw)
|
||||
--alldevs.nwrite;
|
||||
--alldevs_nwrite;
|
||||
else
|
||||
--alldevs.nread;
|
||||
--alldevs_nread;
|
||||
/* XXX wake a garbage-collection thread */
|
||||
mutex_exit(&alldevs.lock);
|
||||
mutex_exit(&alldevs_lock);
|
||||
}
|
||||
|
||||
const char *
|
||||
|
Loading…
Reference in New Issue
Block a user