svn commit: r343914 - stable/12/sys/kern
Mark Johnston
markj at FreeBSD.org
Fri Feb 8 16:38:31 UTC 2019
Author: markj
Date: Fri Feb 8 16:38:30 2019
New Revision: 343914
URL: https://svnweb.freebsd.org/changeset/base/343914
Log:
MFC r343626:
Prevent some kobj memory allocation failures from panicking the system.
Modified:
stable/12/sys/kern/subr_kobj.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/sys/kern/subr_kobj.c
==============================================================================
--- stable/12/sys/kern/subr_kobj.c Fri Feb 8 16:18:17 2019 (r343913)
+++ stable/12/sys/kern/subr_kobj.c Fri Feb 8 16:38:30 2019 (r343914)
@@ -125,38 +125,43 @@ kobj_class_compile_common(kobj_class_t cls, kobj_ops_t
cls->ops = ops;
}
-void
-kobj_class_compile(kobj_class_t cls)
+static int
+kobj_class_compile1(kobj_class_t cls, int mflags)
{
kobj_ops_t ops;
KOBJ_ASSERT(MA_NOTOWNED);
- /*
- * Allocate space for the compiled ops table.
- */
- ops = malloc(sizeof(struct kobj_ops), M_KOBJ, M_NOWAIT);
- if (!ops)
- panic("%s: out of memory", __func__);
+ ops = malloc(sizeof(struct kobj_ops), M_KOBJ, mflags);
+ if (ops == NULL)
+ return (ENOMEM);
- KOBJ_LOCK();
-
/*
* We may have lost a race for kobj_class_compile here - check
* to make sure someone else hasn't already compiled this
* class.
*/
+ KOBJ_LOCK();
if (cls->ops) {
KOBJ_UNLOCK();
free(ops, M_KOBJ);
- return;
+ return (0);
}
-
kobj_class_compile_common(cls, ops);
KOBJ_UNLOCK();
+ return (0);
}
void
+kobj_class_compile(kobj_class_t cls)
+{
+ int error;
+
+ error = kobj_class_compile1(cls, M_WAITOK);
+ KASSERT(error == 0, ("kobj_class_compile1 returned %d", error));
+}
+
+void
kobj_class_compile_static(kobj_class_t cls, kobj_ops_t ops)
{
@@ -254,24 +259,6 @@ kobj_class_free(kobj_class_t cls)
free(ops, M_KOBJ);
}
-kobj_t
-kobj_create(kobj_class_t cls,
- struct malloc_type *mtype,
- int mflags)
-{
- kobj_t obj;
-
- /*
- * Allocate and initialise the new object.
- */
- obj = malloc(cls->size, mtype, mflags | M_ZERO);
- if (!obj)
- return NULL;
- kobj_init(obj, cls);
-
- return obj;
-}
-
static void
kobj_init_common(kobj_t obj, kobj_class_t cls)
{
@@ -280,30 +267,52 @@ kobj_init_common(kobj_t obj, kobj_class_t cls)
cls->refs++;
}
-void
-kobj_init(kobj_t obj, kobj_class_t cls)
+static int
+kobj_init1(kobj_t obj, kobj_class_t cls, int mflags)
{
- KOBJ_ASSERT(MA_NOTOWNED);
- retry:
- KOBJ_LOCK();
+ int error;
- /*
- * Consider compiling the class' method table.
- */
- if (!cls->ops) {
+ KOBJ_LOCK();
+ while (cls->ops == NULL) {
/*
* kobj_class_compile doesn't want the lock held
* because of the call to malloc - we drop the lock
* and re-try.
*/
KOBJ_UNLOCK();
- kobj_class_compile(cls);
- goto retry;
+ error = kobj_class_compile1(cls, mflags);
+ if (error != 0)
+ return (error);
+ KOBJ_LOCK();
}
-
kobj_init_common(obj, cls);
-
KOBJ_UNLOCK();
+ return (0);
+}
+
+kobj_t
+kobj_create(kobj_class_t cls, struct malloc_type *mtype, int mflags)
+{
+ kobj_t obj;
+
+ obj = malloc(cls->size, mtype, mflags | M_ZERO);
+ if (obj == NULL)
+ return (NULL);
+ if (kobj_init1(obj, cls, mflags) != 0) {
+ free(obj, mtype);
+ return (NULL);
+ }
+ return (obj);
+}
+
+void
+kobj_init(kobj_t obj, kobj_class_t cls)
+{
+ int error;
+
+ error = kobj_init1(obj, cls, M_NOWAIT);
+ if (error != 0)
+ panic("kobj_init1 failed: error %d", error);
}
void
More information about the svn-src-all
mailing list