Module: xenomai-forge
Branch: next
Commit: d2664050795295c26a297c0043fb412f7866ed2f
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=d2664050795295c26a297c0043fb412f7866ed2f

Author: Philippe Gerum <r...@xenomai.org>
Date:   Mon Sep  8 16:58:35 2014 +0200

cobalt/heap: drop error return from xnheap_free()

Since we only don't have application-level code using our heap-based
allocator anymore, any invalid block pointer passed to xnheap_free()
would mean that some core code is definitely broken.

In response to such event, we now bluntly freak out and panic upon
detection of a bad pointer if CONFIG_XENO_OPT_DEBUG_COBALT is
enabled. Otherwise, xnheap_free() silently returns ignoring the
request.

As a consequence of this, xnheap_test_and_free() is dropped in the
same move, since a block pointer should always be valid at this
interface level, or the Cobalt kernel will pull the break if asked to.

---

 include/cobalt/kernel/heap.h |    6 +--
 kernel/cobalt/heap.c         |  106 ++++++++----------------------------------
 kernel/cobalt/posix/memory.h |    4 +-
 3 files changed, 23 insertions(+), 93 deletions(-)

diff --git a/include/cobalt/kernel/heap.h b/include/cobalt/kernel/heap.h
index 863fe88..4bc514e 100644
--- a/include/cobalt/kernel/heap.h
+++ b/include/cobalt/kernel/heap.h
@@ -145,11 +145,7 @@ void xnheap_destroy(struct xnheap *heap,
 void *xnheap_alloc(struct xnheap *heap,
                   unsigned long size);
 
-int xnheap_test_and_free(struct xnheap *heap,
-                        void *block,
-                        int (*ckfn)(void *block));
-
-int xnheap_free(struct xnheap *heap,
+void xnheap_free(struct xnheap *heap,
                void *block);
 
 int xnheap_check_block(struct xnheap *heap,
diff --git a/kernel/cobalt/heap.c b/kernel/cobalt/heap.c
index 7841664..e32c014 100644
--- a/kernel/cobalt/heap.c
+++ b/kernel/cobalt/heap.c
@@ -170,8 +170,7 @@ static void init_freelist(struct xnheap *heap)
  * Initializes a memory heap suitable for time-bounded allocation
  * requests of dynamic memory.
  *
- * @param heap The address of a heap descriptor which is used to store
- * the meta-data.
+ * @param heap The address of a heap descriptor to initialize.
  *
  * @param membase The address of the storage area.
  *
@@ -490,47 +489,28 @@ out:
 EXPORT_SYMBOL_GPL(xnheap_alloc);
 
 /**
- * @fn int xnheap_test_and_free(struct xnheap *heap,void *block,int 
(*ckfn)(void *block))
- * @brief Test and release a memory block to a memory heap.
+ * @fn void xnheap_free(struct xnheap *heap, void *block)
+ * @brief Release a block to a memory heap.
  *
- * Releases a memory region to the memory heap it was previously
- * allocated from. Before the actual release is performed, an optional
- * user-defined can be invoked to check for additional criteria with
- * respect to the request consistency.
+ * Releases a memory block to a heap.
  *
- * @param heap The descriptor address of the heap to release memory
- * to.
+ * @param heap The heap descriptor.
  *
- * @param block The address of the region to be returned to the heap.
- *
- * @param ckfn The address of a user-supplied verification routine
- * which is to be called after the memory address specified by @a
- * block has been checked for validity. The routine is expected to
- * proceed to further consistency checks, and either return zero upon
- * success, or non-zero upon error. In the latter case, the release
- * process is aborted, and @a ckfn's return value is passed back to
- * the caller of this service as its error return code.
- *
- * @warning @a ckfn must not reschedule either directly or indirectly.
- *
- * @return 0 is returned upon success, or -EINVAL is returned whenever
- * the block is not a valid region of the specified heap. Additional
- * return codes can also be defined locally by the @a ckfn routine.
+ * @param block The block to be returned to the heap.
  *
  * @coretags{unrestricted}
  */
-int xnheap_test_and_free(struct xnheap *heap, void *block, int (*ckfn) (void 
*block))
+void xnheap_free(struct xnheap *heap, void *block)
 {
        caddr_t freepage, lastpage, nextpage, tailpage, freeptr, *tailptr;
-       int log2size, npages, ret, nblocks, xpage, ilog;
        unsigned long pagenum, pagecont, boffset, bsize;
+       int log2size, npages, nblocks, xpage, ilog;
        spl_t s;
 
        xnlock_get_irqsave(&heap->lock, s);
 
-       ret = -EFAULT;
        if ((caddr_t)block < heap->membase || (caddr_t)block >= heap->memlim)
-               goto unlock_and_fail;
+               goto bad_block;
 
        /* Compute the heading page number in the page map. */
        pagenum = ((caddr_t)block - heap->membase) / XNHEAP_PAGESZ;
@@ -540,18 +520,12 @@ int xnheap_test_and_free(struct xnheap *heap, void 
*block, int (*ckfn) (void *bl
        case XNHEAP_PFREE:      /* Unallocated page? */
        case XNHEAP_PCONT:      /* Not a range heading page? */
        bad_block:
-               ret = -EINVAL;
-       unlock_and_fail:
                xnlock_put_irqrestore(&heap->lock, s);
-               return ret;
+               XENO_BUG(COBALT);
+               return;
 
        case XNHEAP_PLIST:
-
-               if (ckfn && (ret = ckfn(block)) != 0)
-                       goto unlock_and_fail;
-
                npages = 1;
-
                while (npages < heap->npages &&
                       heap->pagemap[pagenum + npages].type == XNHEAP_PCONT)
                        npages++;
@@ -559,18 +533,14 @@ int xnheap_test_and_free(struct xnheap *heap, void 
*block, int (*ckfn) (void *bl
                bsize = npages * XNHEAP_PAGESZ;
 
        free_page_list:
-
                /* Link all freed pages in a single sub-list. */
-
                for (freepage = (caddr_t) block,
                     tailpage = (caddr_t) block + bsize - XNHEAP_PAGESZ;
                     freepage < tailpage; freepage += XNHEAP_PAGESZ)
                        *((caddr_t *) freepage) = freepage + XNHEAP_PAGESZ;
 
        free_pages:
-
                /* Mark the released pages as free. */
-
                for (pagecont = 0; pagecont < npages; pagecont++)
                        heap->pagemap[pagenum + pagecont].type = XNHEAP_PFREE;
 
@@ -597,9 +567,6 @@ int xnheap_test_and_free(struct xnheap *heap, void *block, 
int (*ckfn) (void *bl
                if ((boffset & (bsize - 1)) != 0) /* Not a block start? */
                        goto bad_block;
 
-               if (ckfn && (ret = ckfn(block)) != 0)
-                       goto unlock_and_fail;
-
                /*
                 * Return the page to the free list if we've just
                 * freed its last busy block. Pages from multi-page
@@ -616,15 +583,14 @@ int xnheap_test_and_free(struct xnheap *heap, void 
*block, int (*ckfn) (void *bl
                        break;
                }
 
+               /*
+                * In the simplest case, we only have a single block
+                * to deal with, which spans multiple pages. We just
+                * need to release it as a list of pages, without
+                * caring about the consistency of the bucket.
+                */
                npages = bsize / XNHEAP_PAGESZ;
                if (unlikely(npages > 1))
-                       /*
-                        * The simplest case: we only have a single
-                        * block to deal with, which spans multiple
-                        * pages. We just need to release it as a list
-                        * of pages, without caring about the
-                        * consistency of the bucket.
-                        */
                        goto free_page_list;
 
                freepage = heap->membase + pagenum * XNHEAP_PAGESZ;
@@ -636,11 +602,10 @@ int xnheap_test_and_free(struct xnheap *heap, void 
*block, int (*ckfn) (void *bl
                XENO_BUGON(COBALT, heap->buckets[ilog].fcount < 0);
 
                /*
-                * Easy case: all free blocks are laid on a single
-                * page we are now releasing. Just clear the bucket
-                * and bail out.
+                * Still easy case: all free blocks are laid on a
+                * single page we are now releasing. Just clear the
+                * bucket and bail out.
                 */
-
                if (likely(heap->buckets[ilog].fcount == 0)) {
                        heap->buckets[ilog].freelist = NULL;
                        goto free_pages;
@@ -674,37 +639,6 @@ int xnheap_test_and_free(struct xnheap *heap, void *block, 
int (*ckfn) (void *bl
        heap->used -= bsize;
 
        xnlock_put_irqrestore(&heap->lock, s);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(xnheap_test_and_free);
-
-/**
- * @fn int xnheap_free(struct xnheap *heap, void *block)
- * @brief Release a memory block to a memory heap.
- *
- * Releases a memory region to the memory heap it was previously
- * allocated from.
- *
- * @param heap The descriptor address of the heap to release memory
- * to.
- *
- * @param block The address of the region to be returned to the heap.
- *
- * @return 0 is returned upon success, or one of the following error
- * codes:
- *
- * - -EFAULT is returned whenever the memory address is outside the
- * storage space of @a heap.
- *
- * - -EINVAL is returned whenever the memory address does not
- * represent a valid block.
- *
- * @coretags{unrestricted}
- */
-int xnheap_free(struct xnheap *heap, void *block)
-{
-       return xnheap_test_and_free(heap, block, NULL);
 }
 EXPORT_SYMBOL_GPL(xnheap_free);
 
diff --git a/kernel/cobalt/posix/memory.h b/kernel/cobalt/posix/memory.h
index 562530d..702bb67 100644
--- a/kernel/cobalt/posix/memory.h
+++ b/kernel/cobalt/posix/memory.h
@@ -32,9 +32,9 @@ void *cobalt_umm_alloc(struct cobalt_umm *umm, __u32 size)
 }
 
 static inline
-int cobalt_umm_free(struct cobalt_umm *umm, void *p)
+void cobalt_umm_free(struct cobalt_umm *umm, void *p)
 {
-       return xnheap_free(&umm->heap, p);
+       xnheap_free(&umm->heap, p);
 }
 
 static inline


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to