slab: trigger allocation failure for failed ctors
We were just returning NULL, which would have MEM_WAIT allocs return
NULL. It'd usually panic immediately - this way we catch it a little
earlier in a common path.
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
diff --git a/kern/src/slab.c b/kern/src/slab.c
index eba20b5..be6b89a 100644
--- a/kern/src/slab.c
+++ b/kern/src/slab.c
@@ -594,21 +594,16 @@
/* Alloc, bypassing the magazines and depot */
static void *__kmem_alloc_from_slab(struct kmem_cache *cp, int flags)
{
- void *retval = NULL;
+ void *retval;
spin_lock_irqsave(&cp->cache_lock);
// look at partial list
struct kmem_slab *a_slab = TAILQ_FIRST(&cp->partial_slab_list);
// if none, go to empty list and get an empty and make it partial
if (!a_slab) {
- // TODO: think about non-sleeping flags
- if (TAILQ_EMPTY(&cp->empty_slab_list) &&
- !kmem_cache_grow(cp)) {
+ if (TAILQ_EMPTY(&cp->empty_slab_list) && !kmem_cache_grow(cp)) {
spin_unlock_irqsave(&cp->cache_lock);
- if (flags & MEM_ERROR)
- error(ENOMEM, ERROR_FIXME);
- else
- panic("[German Accent]: OOM for a small slab growth!!!");
+ goto out_oom;
}
// move to partial list
a_slab = TAILQ_FIRST(&cp->empty_slab_list);
@@ -643,10 +638,20 @@
if (cp->ctor(retval, cp->priv, flags)) {
warn("Ctor %p failed, probably a bug!");
__kmem_free_to_slab(cp, retval);
- return NULL;
+ goto out_oom;
}
}
return retval;
+out_oom:
+ if (flags & MEM_ATOMIC)
+ return NULL;
+ /* Old code didn't set any MEM_ flag. Typically '0' for MEM_ATOMIC. */
+ if (!(flags & MEM_FLAGS))
+ return NULL;
+ if (flags & MEM_ERROR)
+ error(ENOMEM, ERROR_FIXME);
+ else
+ panic("[German Accent]: OOM for a small slab growth!!!");
}
void *kmem_cache_alloc(struct kmem_cache *kc, int flags)