use a reference count to avoid deleting psrefs still in use.

This commit is contained in:
christos 2017-11-27 00:25:46 +00:00
parent 4cbdc53564
commit dd0971df99
3 changed files with 24 additions and 16 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: defs.h,v 1.101 2017/11/18 18:44:20 christos Exp $ */ /* $NetBSD: defs.h,v 1.102 2017/11/27 00:25:46 christos Exp $ */
/* /*
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -234,9 +234,9 @@ struct pspec {
struct devbase *p_atdev; /* optional parent device base */ struct devbase *p_atdev; /* optional parent device base */
int p_atunit; /* optional parent device unit */ int p_atunit; /* optional parent device unit */
struct nvlist *p_devs; /* children using it */ struct nvlist *p_devs; /* children using it */
struct deva *p_deva; /* attribute */
int p_inst; /* parent spec instance */ int p_inst; /* parent spec instance */
int p_active; /* parent spec is actively used */ int p_active; /* parent spec is actively used */
int p_ref; /* refcount */
}; };
/* /*

View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.95 2017/11/24 23:42:36 christos Exp $ */ /* $NetBSD: main.c,v 1.96 2017/11/27 00:25:46 christos Exp $ */
/* /*
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -45,7 +45,7 @@
#endif #endif
#include <sys/cdefs.h> #include <sys/cdefs.h>
__RCSID("$NetBSD: main.c,v 1.95 2017/11/24 23:42:36 christos Exp $"); __RCSID("$NetBSD: main.c,v 1.96 2017/11/27 00:25:46 christos Exp $");
#ifndef MAKE_BOOTSTRAP #ifndef MAKE_BOOTSTRAP
#include <sys/cdefs.h> #include <sys/cdefs.h>
@ -1959,8 +1959,11 @@ do_kill_orphans(struct devbase *d, struct attr *at, struct devbase *parent,
continue; continue;
} }
j->i_active = active = state; j->i_active = active = state;
if (p != NULL) if (p != NULL) {
p->p_active = state; if (state == DEVI_ACTIVE ||
--p->p_ref == 0)
p->p_active = state;
}
if (state == DEVI_IGNORED) { if (state == DEVI_IGNORED) {
CFGDBG(5, CFGDBG(5,
"`%s' at '%s' ignored", "`%s' at '%s' ignored",

View File

@ -1,4 +1,4 @@
/* $NetBSD: sem.c,v 1.81 2017/11/24 18:45:59 christos Exp $ */ /* $NetBSD: sem.c,v 1.82 2017/11/27 00:25:46 christos Exp $ */
/* /*
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -45,7 +45,7 @@
#endif #endif
#include <sys/cdefs.h> #include <sys/cdefs.h>
__RCSID("$NetBSD: sem.c,v 1.81 2017/11/24 18:45:59 christos Exp $"); __RCSID("$NetBSD: sem.c,v 1.82 2017/11/27 00:25:46 christos Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <ctype.h> #include <ctype.h>
@ -79,8 +79,7 @@ static int has_errobj(struct attrlist *, struct attr *);
static struct nvlist *addtoattr(struct nvlist *, struct devbase *); static struct nvlist *addtoattr(struct nvlist *, struct devbase *);
static int resolve(struct nvlist **, const char *, const char *, static int resolve(struct nvlist **, const char *, const char *,
struct nvlist *, int); struct nvlist *, int);
static struct pspec *getpspec(struct attr *, struct devbase *, int, static struct pspec *getpspec(struct attr *, struct devbase *, int, int);
struct deva *);
static struct devi *newdevi(const char *, int, struct devbase *d); static struct devi *newdevi(const char *, int, struct devbase *d);
static struct devi *getdevi(const char *); static struct devi *getdevi(const char *);
static void remove_devi(struct devi *); static void remove_devi(struct devi *);
@ -1296,7 +1295,7 @@ adddev(const char *name, const char *at, struct loclist *loclist, int flags)
* XXX: This creates multiple pspecs that look the * XXX: This creates multiple pspecs that look the
* same in the config file and could be merged. * same in the config file and could be merged.
*/ */
p = getpspec(attr, ab, atunit, iba); p = getpspec(attr, ab, atunit, first);
p->p_devs = newnv(NULL, NULL, i, 0, p->p_devs); p->p_devs = newnv(NULL, NULL, i, 0, p->p_devs);
} else } else
p = NULL; p = NULL;
@ -1907,17 +1906,23 @@ fixdevis(void)
* Look up a parent spec, creating a new one if it does not exist. * Look up a parent spec, creating a new one if it does not exist.
*/ */
static struct pspec * static struct pspec *
getpspec(struct attr *attr, struct devbase *ab, int atunit, struct deva *da) getpspec(struct attr *attr, struct devbase *ab, int atunit, int first)
{ {
struct pspec *p; struct pspec *p;
int inst = npspecs; int inst = npspecs;
int ref = 1;
TAILQ_FOREACH(p, &allpspecs, p_list) { TAILQ_FOREACH(p, &allpspecs, p_list) {
if (p->p_iattr == attr && p->p_atdev == ab && if (p->p_iattr == attr && p->p_atdev == ab &&
p->p_atunit == atunit) { p->p_atunit == atunit) {
if (p->p_deva == da) p->p_ref++;
return (p); if (first)
inst = p->p_inst; return p;
else {
inst = p->p_inst;
ref = p->p_ref;
}
} }
} }
@ -1929,8 +1934,8 @@ getpspec(struct attr *attr, struct devbase *ab, int atunit, struct deva *da)
p->p_inst = inst; p->p_inst = inst;
if (inst == npspecs) if (inst == npspecs)
npspecs++; npspecs++;
p->p_deva = da;
p->p_active = 0; p->p_active = 0;
p->p_ref = ref;
TAILQ_INSERT_TAIL(&allpspecs, p, p_list); TAILQ_INSERT_TAIL(&allpspecs, p, p_list);