BTW, there are a few places which currently do this:
if((alloc = kzmalloc(SIZE, 0)) == NULL)
error(ENOMEM, NULL);
This CL does not go and change them. I can do it here, or in a separate CL.
Let me know.
On Tue, Dec 8, 2015 at 12:04 PM, Davide Libenzi <[email protected]> wrote:
> This CL adds the new KMALLOC_ERROR flag we chatted about a few days ago.
>
>
> https://github.com/brho/akaros/compare/master...dlibenzi:kmalloc_error
>
>
> The following changes since commit
> 2fa42319139e4cc5ca853546363f84443d0ead00:
>
> Rename 'reallocarray' to 'kreallocarray'. (2015-11-25 18:02:04 -0500)
>
> are available in the git repository at:
>
> [email protected]:dlibenzi/akaros kmalloc_error
>
> for you to fetch changes up to 989a2b9a7bbd409e4c478dd8e31d738dc6f892fe:
>
> Added new kmalloc flag KMALLOC_ERROR (2015-12-08 11:58:57 -0800)
>
> ----------------------------------------------------------------
> Davide Libenzi (1):
> Added new kmalloc flag KMALLOC_ERROR
>
> kern/include/kmalloc.h | 3 ++-
> kern/src/page_alloc.c | 8 +++++++-
> kern/src/slab.c | 31 +++++++++++++++++++++++--------
> 3 files changed, 32 insertions(+), 10 deletions(-)
>
> diff --git a/kern/include/kmalloc.h b/kern/include/kmalloc.h
> index 268cf29..84c0275 100644
> --- a/kern/include/kmalloc.h
> +++ b/kern/include/kmalloc.h
> @@ -30,7 +30,8 @@ void *debug_canary;
>
> /* Flags to pass to kmalloc */
> /* Not implemented yet. Block until it is available. */
> -#define KMALLOC_WAIT 4
> +#define KMALLOC_WAIT (1 << 2)
> +#define KMALLOC_ERROR (1 << 3)
>
> /* Kmalloc tag flags looks like this:
> *
> diff --git a/kern/src/page_alloc.c b/kern/src/page_alloc.c
> index c2910c7..9e55457 100644
> --- a/kern/src/page_alloc.c
> +++ b/kern/src/page_alloc.c
> @@ -5,10 +5,12 @@
> * Kevin Klues <[email protected]>
> * Barret Rhoden <[email protected]> */
>
> +#include <ros/errno.h>
> #include <sys/queue.h>
> #include <bitmask.h>
> #include <page_alloc.h>
> #include <pmap.h>
> +#include <err.h>
> #include <string.h>
> #include <kmalloc.h>
> #include <blockdev.h>
> @@ -206,6 +208,8 @@ void *get_cont_pages(size_t order, int flags)
> //If we couldn't find them, return NULL
> if( first == -1 ) {
> spin_unlock_irqsave(&colored_page_free_list_lock);
> + if (flags & KMALLOC_ERROR)
> + error(ENOMEM, NULL);
> return NULL;
> }
>
> @@ -262,7 +266,9 @@ void *get_cont_phys_pages_at(size_t order, physaddr_t
> at, int flags)
> for (unsigned long i = first_pg_nr; i < first_pg_nr + nr_pgs; i++) {
> if (!page_is_free(i)) {
> spin_unlock_irqsave(&colored_page_free_list_lock);
> - return 0;
> + if (flags & KMALLOC_ERROR)
> + error(ENOMEM, NULL);
> + return NULL;
> }
> }
> for (unsigned long i = first_pg_nr; i < first_pg_nr + nr_pgs; i++)
> diff --git a/kern/src/slab.c b/kern/src/slab.c
> index 91d9137..e7e53ad 100644
> --- a/kern/src/slab.c
> +++ b/kern/src/slab.c
> @@ -15,13 +15,14 @@
> #include <stdio.h>
> #include <assert.h>
> #include <pmap.h>
> +#include <kmalloc.h>
>
> struct kmem_cache_list kmem_caches;
> spinlock_t kmem_caches_lock;
>
> /* Backend/internal functions, defined later. Grab the lock before
> calling
> * these. */
> -static void kmem_cache_grow(struct kmem_cache *cp);
> +static bool kmem_cache_grow(struct kmem_cache *cp);
>
> /* Cache of the kmem_cache objects, needed for bootstrapping */
> struct kmem_cache kmem_cache_cache;
> @@ -161,9 +162,15 @@ void *kmem_cache_alloc(struct kmem_cache *cp, int
> flags)
> 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) {
> - if (TAILQ_EMPTY(&cp->empty_slab_list))
> - // TODO: think about non-sleeping flags
> - kmem_cache_grow(cp);
> + // TODO: think about non-sleeping flags
> + if (TAILQ_EMPTY(&cp->empty_slab_list) &&
> + !kmem_cache_grow(cp)) {
> + spin_unlock_irqsave(&cp->cache_lock);
> + if (flags & KMALLOC_ERROR)
> + error(ENOMEM, NULL);
> + else
> + panic("[German Accent]: OOM for a small slab growth!!!");
> + }
> // move to partial list
> a_slab = TAILQ_FIRST(&cp->empty_slab_list);
> TAILQ_REMOVE(&cp->empty_slab_list, a_slab, link);
> @@ -242,15 +249,16 @@ void kmem_cache_free(struct kmem_cache *cp, void
> *buf)
> * Grab the cache lock before calling this.
> *
> * TODO: think about page colouring issues with kernel memory allocation.
> */
> -static void kmem_cache_grow(struct kmem_cache *cp)
> +static bool kmem_cache_grow(struct kmem_cache *cp)
> {
> struct kmem_slab *a_slab;
> struct kmem_bufctl *a_bufctl;
> if (cp->obj_size <= SLAB_LARGE_CUTOFF) {
> // Just get a single page for small slabs
> page_t *a_page;
> +
> if (kpage_alloc(&a_page))
> - panic("[German Accent]: OOM for a small slab growth!!!");
> + return FALSE;
> // the slab struct is stored at the end of the page
> a_slab = (struct kmem_slab*)(page2kva(a_page) + PGSIZE -
> sizeof(struct kmem_slab));
> @@ -274,6 +282,8 @@ static void kmem_cache_grow(struct kmem_cache *cp)
> *((uintptr_t**)(buf + cp->obj_size)) = NULL;
> } else {
> a_slab = kmem_cache_alloc(kmem_slab_cache, 0);
> + if (!a_slab)
> + return FALSE;
> // TODO: hash table for back reference (BUF)
> a_slab->obj_size = ROUNDUP(cp->obj_size + sizeof(uintptr_t), cp->align);
> /* Figure out how much memory we want. We need at least min_pgs. We'll
> @@ -282,8 +292,11 @@ static void kmem_cache_grow(struct kmem_cache *cp)
> PGSIZE;
> size_t order_pg_alloc = LOG2_UP(min_pgs);
> void *buf = get_cont_pages(order_pg_alloc, 0);
> - if (!buf)
> - panic("[German Accent]: OOM for a large slab growth!!!");
> +
> + if (!buf) {
> + kmem_slab_destroy(kmem_slab_cache, a_slab);
> + return FALSE;
> + }
> a_slab->num_busy_obj = 0;
> /* The number of objects is based on the rounded up amt requested. */
> a_slab->num_total_obj = ((1 << order_pg_alloc) * PGSIZE) /
> @@ -305,6 +318,8 @@ static void kmem_cache_grow(struct kmem_cache *cp)
> }
> // add a_slab to the empty_list
> TAILQ_INSERT_HEAD(&cp->empty_slab_list, a_slab, link);
> +
> + return TRUE;
> }
>
> /* This deallocs every slab from the empty list. TODO: think a bit more
> about
>
>
--
You received this message because you are subscribed to the Google Groups
"Akaros" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
For more options, visit https://groups.google.com/d/optout.