summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2000-05-01 10:45:15 +0000
committerdfr <dfr@FreeBSD.org>2000-05-01 10:45:15 +0000
commit14185daa26ace1f11639608f6b655cf2c7cc4e27 (patch)
treea07a912eede7bd97ce3020b8d02e94959f5760fb /sys
parent4c69e0f4d7e4fad2294ba277c71c27ae4fb5534a (diff)
downloadFreeBSD-src-14185daa26ace1f11639608f6b655cf2c7cc4e27.zip
FreeBSD-src-14185daa26ace1f11639608f6b655cf2c7cc4e27.tar.gz
* Move the driver_t::refs field to kobj_t to replace kobj_t::instances.
* Back out a couple of workarounds for the confusion between kobj_t::instances and driver_t::refs.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/subr_bus.c11
-rw-r--r--sys/kern/subr_kobj.c6
-rw-r--r--sys/sys/bus.h1
-rw-r--r--sys/sys/kobj.h2
4 files changed, 8 insertions, 12 deletions
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 22ad812..de36141 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -162,7 +162,10 @@ devclass_add_driver(devclass_t dc, driver_t *driver)
bzero(dl, sizeof *dl);
/*
- * Compile the driver's methods.
+ * Compile the driver's methods. Also increase the reference count
+ * so that the class doesn't get freed when the last instance
+ * goes. This means we can safely use static methods and avoids a
+ * double-free in devclass_delete_driver.
*/
kobj_class_compile((kobj_class_t) driver);
@@ -986,7 +989,6 @@ device_set_driver(device_t dev, driver_t *driver)
return ENOMEM;
}
bzero(dev->softc, driver->size);
- driver->refs++;
} else
kobj_init((kobj_t) dev, &null_class);
return 0;
@@ -1843,11 +1845,6 @@ bus_generic_driver_added(device_t dev, driver_t *driver)
{
device_t child;
- /*
- * Make sure the class has a valid ops table.
- */
- kobj_class_compile((kobj_class_t) driver);
-
DEVICE_IDENTIFY(driver, dev);
for (child = TAILQ_FIRST(&dev->children);
child; child = TAILQ_NEXT(child, link))
diff --git a/sys/kern/subr_kobj.c b/sys/kern/subr_kobj.c
index 9a2eafb..6b95eb9 100644
--- a/sys/kern/subr_kobj.c
+++ b/sys/kern/subr_kobj.c
@@ -174,7 +174,7 @@ kobj_init(kobj_t obj, kobj_class_t cls)
kobj_class_compile(cls);
obj->ops = cls->ops;
- cls->instances++;
+ cls->refs++;
}
void
@@ -187,8 +187,8 @@ kobj_delete(kobj_t obj, struct malloc_type *mtype)
* after its last instance is deleted. As an optimisation, we
* should defer this for a short while to avoid thrashing.
*/
- cls->instances--;
- if (!cls->instances)
+ cls->refs--;
+ if (!cls->refs)
kobj_class_free(cls);
obj->ops = 0;
diff --git a/sys/sys/bus.h b/sys/sys/bus.h
index f1ed037..8ab2a13 100644
--- a/sys/sys/bus.h
+++ b/sys/sys/bus.h
@@ -65,7 +65,6 @@ typedef int (*devop_t)(void);
struct driver {
KOBJ_CLASS_FIELDS;
void *priv; /* driver private data */
- int refs; /* # devclasses containing driver */
};
typedef enum device_state {
diff --git a/sys/sys/kobj.h b/sys/sys/kobj.h
index 906cf5a..f8500d5 100644
--- a/sys/sys/kobj.h
+++ b/sys/sys/kobj.h
@@ -55,7 +55,7 @@ struct kobj_method {
const char *name; /* class name */ \
kobj_method_t *methods; /* method table */ \
size_t size; /* object size */ \
- u_int instances; /* instance count */ \
+ u_int refs; /* reference count */ \
kobj_ops_t ops /* compiled method table */
struct kobj_class {
OpenPOWER on IntegriCloud