Module: xenomai-jki
Branch: queues/heap
Commit: 7348ee674f7a91eb17a2db14b7c6cf927c9de8ba
URL:    
http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=7348ee674f7a91eb17a2db14b7c6cf927c9de8ba

Author: Jan Kiszka <jan.kis...@siemens.com>
Date:   Wed Nov 11 13:34:51 2009 +0100

nucleus: Include all heaps in statistics

This extends /proc/xenomai/heap with statistics about all currently used
heaps. It takes care to flush nklock while iterating of this potentially
long list.

Signed-off-by: Jan Kiszka <jan.kis...@siemens.com>

---

 include/nucleus/heap.h    |   12 ++++-
 ksrc/drivers/ipc/iddp.c   |    3 +-
 ksrc/drivers/ipc/xddp.c   |    6 ++-
 ksrc/nucleus/heap.c       |  125 +++++++++++++++++++++++++++++++++++++++-----
 ksrc/nucleus/module.c     |    2 +-
 ksrc/nucleus/pod.c        |    5 +-
 ksrc/nucleus/shadow.c     |    5 ++-
 ksrc/skins/native/heap.c  |    6 ++-
 ksrc/skins/native/pipe.c  |    4 +-
 ksrc/skins/native/queue.c |    6 ++-
 ksrc/skins/posix/shm.c    |    4 +-
 ksrc/skins/psos+/rn.c     |    6 ++-
 ksrc/skins/rtai/shm.c     |    7 ++-
 ksrc/skins/vrtx/heap.c    |    6 ++-
 ksrc/skins/vrtx/syscall.c |    3 +-
 15 files changed, 163 insertions(+), 37 deletions(-)

diff --git a/include/nucleus/heap.h b/include/nucleus/heap.h
index 44db738..f653cd7 100644
--- a/include/nucleus/heap.h
+++ b/include/nucleus/heap.h
@@ -115,6 +115,10 @@ typedef struct xnheap {
 
        XNARCH_DECL_DISPLAY_CONTEXT();
 
+       xnholder_t stat_link;   /* Link in heapq */
+
+       char name[48];
+
 } xnheap_t;
 
 extern xnheap_t kheap;
@@ -202,7 +206,8 @@ void xnheap_cleanup_proc(void);
 
 int xnheap_init_mapped(xnheap_t *heap,
                       u_long heapsize,
-                      int memflags);
+                      int memflags,
+                      const char *name, ...);
 
 void xnheap_destroy_mapped(xnheap_t *heap,
                           void (*release)(struct xnheap *heap),
@@ -224,7 +229,10 @@ void xnheap_destroy_mapped(xnheap_t *heap,
 int xnheap_init(xnheap_t *heap,
                void *heapaddr,
                u_long heapsize,
-               u_long pagesize);
+               u_long pagesize,
+               const char *name, ...);
+
+void xnheap_set_name(xnheap_t *heap, const char *name, ...);
 
 void xnheap_destroy(xnheap_t *heap,
                    void (*flushfn)(xnheap_t *heap,
diff --git a/ksrc/drivers/ipc/iddp.c b/ksrc/drivers/ipc/iddp.c
index a589d34..1f33ada 100644
--- a/ksrc/drivers/ipc/iddp.c
+++ b/ksrc/drivers/ipc/iddp.c
@@ -559,7 +559,8 @@ static int __iddp_bind_socket(struct rtipc_private *priv,
                }
 
                ret = xnheap_init(&sk->privpool,
-                                 poolmem, poolsz, XNHEAP_PAGE_SIZE);
+                                 poolmem, poolsz, XNHEAP_PAGE_SIZE,
+                                 "ippd: %d", port);
                if (ret) {
                        xnarch_free_host_mem(poolmem, poolsz);
                        goto fail;
diff --git a/ksrc/drivers/ipc/xddp.c b/ksrc/drivers/ipc/xddp.c
index f62147a..a5dafef 100644
--- a/ksrc/drivers/ipc/xddp.c
+++ b/ksrc/drivers/ipc/xddp.c
@@ -703,7 +703,7 @@ static int __xddp_bind_socket(struct rtipc_private *priv,
                }
 
                ret = xnheap_init(&sk->privpool,
-                                 poolmem, poolsz, XNHEAP_PAGE_SIZE);
+                                 poolmem, poolsz, XNHEAP_PAGE_SIZE, "");
                if (ret) {
                        xnarch_free_host_mem(poolmem, poolsz);
                        goto fail;
@@ -746,6 +746,10 @@ static int __xddp_bind_socket(struct rtipc_private *priv,
        sk->minor = ret;
        sa->sipc_port = ret;
        sk->name = *sa;
+
+       if (poolsz > 0)
+               xnheap_set_name(sk->bufpool, "xddp: %d", sa->sipc_port);
+
        /* Set default destination if unset at binding time. */
        if (sk->peer.sipc_port < 0)
                sk->peer = *sa;
diff --git a/ksrc/nucleus/heap.c b/ksrc/nucleus/heap.c
index 27a4ad7..896c9d1 100644
--- a/ksrc/nucleus/heap.c
+++ b/ksrc/nucleus/heap.c
@@ -76,6 +76,9 @@ EXPORT_SYMBOL_GPL(kheap);
 xnheap_t kstacks;      /* Private stack pool */
 #endif
 
+static DEFINE_XNQUEUE(heapq);  /* Heap list for /proc reporting */
+static unsigned long heapq_rev;
+
 static void init_extent(xnheap_t *heap, xnextent_t *extent)
 {
        caddr_t freepage;
@@ -108,7 +111,7 @@ static void init_extent(xnheap_t *heap, xnextent_t *extent)
  */
 
 /*!
- * \fn xnheap_init(xnheap_t *heap,void *heapaddr,u_long heapsize,u_long 
pagesize)
+ * \fn xnheap_init(xnheap_t *heap,void *heapaddr,u_long heapsize,u_long 
pagesize,const char *name,...)
  * \brief Initialize a memory heap.
  *
  * Initializes a memory heap suitable for time-bounded allocation
@@ -145,6 +148,10 @@ static void init_extent(xnheap_t *heap, xnextent_t *extent)
  * best one for your needs. In the current implementation, pagesize
  * must be a power of two in the range [ 8 .. 32768 ] inclusive.
  *
+ * @param name Name displayed in statistic outputs. This parameter can
+ * be a format string, in which case succeeding parameters will be used
+ * to resolve the final name.
+ *
  * @return 0 is returned upon success, or one of the following error
  * codes:
  *
@@ -161,12 +168,13 @@ static void init_extent(xnheap_t *heap, xnextent_t 
*extent)
  * Rescheduling: never.
  */
 
-int xnheap_init(xnheap_t *heap,
-               void *heapaddr, u_long heapsize, u_long pagesize)
+static int xnheap_init_va(xnheap_t *heap, void *heapaddr, u_long heapsize,
+                         u_long pagesize, const char *name, va_list args)
 {
        unsigned cpu, nr_cpus = xnarch_num_online_cpus();
        u_long hdrsize, shiftsize, pageshift;
        xnextent_t *extent;
+       spl_t s;
 
        /*
         * Perform some parametrical checks first.
@@ -232,12 +240,71 @@ int xnheap_init(xnheap_t *heap,
 
        appendq(&heap->extents, &extent->link);
 
+       vsnprintf(heap->name, sizeof(heap->name), name, args);
+
+       xnlock_get_irqsave(&nklock, s);
+       appendq(&heapq, &heap->stat_link);
+       heapq_rev++;
+       xnlock_put_irqrestore(&nklock, s);
+
        xnarch_init_display_context(heap);
 
        return 0;
 }
+
+int xnheap_init(xnheap_t *heap, void *heapaddr, u_long heapsize,
+               u_long pagesize, const char *name, ...)
+{
+       va_list args;
+       int ret;
+
+       va_start(args, name);
+       ret = xnheap_init_va(heap, heapaddr, heapsize, pagesize, name, args);
+       va_end(args);
+
+       return ret;
+}
 EXPORT_SYMBOL_GPL(xnheap_init);
 
+/*!
+ * \fn xnheap_set_name(xnheap_t *heap,const char *name,...)
+ * \brief Overwrite the heap's name.
+ *
+ * Set the heap name that will be used in statistic outputs. This service
+ * is useful if the final name is not yet defined on xnheap_init().
+ *
+ * @param heap The address of a heap descriptor.
+ *
+ * @param name Name displayed in statistic outputs. This parameter can
+ * be a format string, in which case succeeding parameters will be used
+ * to resolve the final name.
+ *
+ * Environments:
+ *
+ * This service can be called from:
+ *
+ * - Kernel module initialization/cleanup code
+ * - Kernel-based task
+ * - User-space task
+ *
+ * Rescheduling: never.
+ */
+
+void xnheap_set_name(xnheap_t *heap, const char *name, ...)
+{
+       va_list args;
+       spl_t s;
+
+       va_start(args, name);
+
+       xnlock_get_irqsave(&nklock, s);
+       vsnprintf(heap->name, sizeof(heap->name), name, args);
+       xnlock_put_irqrestore(&nklock, s);
+
+       va_end(args);
+}
+EXPORT_SYMBOL_GPL(xnheap_set_name);
+
 /*! 
  * \fn void xnheap_destroy(xnheap_t *heap, void (*flushfn)(xnheap_t *heap, 
void *extaddr, u_long extsize, void *cookie), void *cookie)
  * \brief Destroys a memory heap.
@@ -273,6 +340,11 @@ void xnheap_destroy(xnheap_t *heap,
        xnholder_t *holder;
        spl_t s;
 
+       xnlock_get_irqsave(&nklock, s);
+       removeq(&heapq, &heap->stat_link);
+       heapq_rev++;
+       xnlock_put_irqrestore(&nklock, s);
+
        if (!flushfn)
                return;
 
@@ -1194,9 +1266,11 @@ fail:
 #define xnheap_get_unmapped_area  NULL
 #endif /* CONFIG_MMU */
 
-int xnheap_init_mapped(xnheap_t *heap, u_long heapsize, int memflags)
+int xnheap_init_mapped(xnheap_t *heap, u_long heapsize, int memflags,
+                      const char *name, ...)
 {
        void *heapbase;
+       va_list args;
        int err;
 
        /* Caller must have accounted for internal overhead. */
@@ -1210,7 +1284,9 @@ int xnheap_init_mapped(xnheap_t *heap, u_long heapsize, 
int memflags)
        if (heapbase == NULL)
                return -ENOMEM;
 
-       err = xnheap_init(heap, heapbase, heapsize, PAGE_SIZE);
+       va_start(args, name);
+       err = xnheap_init_va(heap, heapbase, heapsize, PAGE_SIZE, name, args);
+       va_end(args);
        if (err) {
                __unreserve_and_free_heap(heapbase, heapsize, memflags);
                return err;
@@ -1354,22 +1430,41 @@ static int heap_read_proc(char *page,
                          char **start,
                          off_t off, int count, int *eof, void *data)
 {
+       unsigned long rev;
+       xnholder_t *entry;
+       xnheap_t *heap;
        int len;
+       spl_t s;
 
        if (!xnpod_active_p())
                return -ESRCH;
 
-       len = sprintf(page, "size=%lu:used=%lu:pagesz=%lu  (main heap)\n",
-                     xnheap_usable_mem(&kheap),
-                     xnheap_used_mem(&kheap),
-                     xnheap_page_size(&kheap));
+       xnlock_get_irqsave(&nklock, s);
 
-#if CONFIG_XENO_OPT_SYS_STACKPOOLSZ > 0
-       len += sprintf(page + len, "size=%lu:used=%lu:pagesz=%lu  (stack 
pool)\n",
-                      xnheap_usable_mem(&kstacks),
-                      xnheap_used_mem(&kstacks),
-                      xnheap_page_size(&kstacks));
-#endif
+restart:
+       len = 0;
+
+       entry = getheadq(&heapq);
+       while (entry) {
+               heap = container_of(entry, xnheap_t, stat_link);
+               len += sprintf(page + len,
+                              "size=%lu:used=%lu:pagesz=%lu  (%s)\n",
+                              xnheap_usable_mem(heap),
+                              xnheap_used_mem(heap),
+                              xnheap_page_size(heap),
+                              heap->name);
+
+               rev = heapq_rev;
+
+               xnlock_sync_irq(&nklock, s);
+
+               if (heapq_rev != rev)
+                       goto restart;
+
+               entry = nextq(&heapq, entry);
+       }
+
+       xnlock_put_irqrestore(&nklock, s);
 
        len -= off;
        if (len <= off + count)
diff --git a/ksrc/nucleus/module.c b/ksrc/nucleus/module.c
index b6d9787..3f41a01 100644
--- a/ksrc/nucleus/module.c
+++ b/ksrc/nucleus/module.c
@@ -101,7 +101,7 @@ int __init __xeno_sys_init(void)
 #ifndef __XENO_SIM__
        ret = xnheap_init_mapped(&__xnsys_global_ppd.sem_heap,
                                 CONFIG_XENO_OPT_GLOBAL_SEM_HEAPSZ * 1024,
-                                XNARCH_SHARED_HEAP_FLAGS);
+                                XNARCH_SHARED_HEAP_FLAGS, "global sem heap");
        if (ret)
                goto cleanup_arch;
 #endif
diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c
index 0911a7f..8440321 100644
--- a/ksrc/nucleus/pod.c
+++ b/ksrc/nucleus/pod.c
@@ -385,9 +385,8 @@ int xnpod_init(void)
        heapaddr = xnarch_alloc_host_mem(xnmod_sysheap_size);
        if (heapaddr == NULL ||
            xnheap_init(&kheap, heapaddr, xnmod_sysheap_size,
-                       XNHEAP_PAGE_SIZE) != 0) {
+                       XNHEAP_PAGE_SIZE, "main heap") != 0)
                return -ENOMEM;
-       }
 
 #if CONFIG_XENO_OPT_SYS_STACKPOOLSZ > 0
        /*
@@ -405,7 +404,7 @@ int xnpod_init(void)
        heapaddr = xnarch_alloc_stack_mem(CONFIG_XENO_OPT_SYS_STACKPOOLSZ * 
1024);
        if (heapaddr == NULL ||
            xnheap_init(&kstacks, heapaddr, CONFIG_XENO_OPT_SYS_STACKPOOLSZ * 
1024,
-                       XNHEAP_PAGE_SIZE) != 0) {
+                       XNHEAP_PAGE_SIZE, "stack pool") != 0) {
                xnheap_destroy(&kheap, &xnpod_flush_heap, NULL);
                return -ENOMEM;
        }
diff --git a/ksrc/nucleus/shadow.c b/ksrc/nucleus/shadow.c
index 1eae0a1..d5203ff 100644
--- a/ksrc/nucleus/shadow.c
+++ b/ksrc/nucleus/shadow.c
@@ -1886,7 +1886,9 @@ static void *xnshadow_sys_event(int event, void *data)
 
                err = xnheap_init_mapped(&p->sem_heap,
                                         CONFIG_XENO_OPT_SEM_HEAPSZ * 1024,
-                                        XNARCH_SHARED_HEAP_FLAGS);
+                                        XNARCH_SHARED_HEAP_FLAGS,
+                                        "private sem heap [%d]",
+                                        current->pid);
                if (err) {
                        xnarch_free_host_mem(p, sizeof(*p));
                        return ERR_PTR(err);
@@ -1896,6 +1898,7 @@ static void *xnshadow_sys_event(int event, void *data)
 
        case XNSHADOW_CLIENT_DETACH:
                p = ppd2sys((xnshadow_ppd_t *) data);
+
                xnheap_destroy_mapped(&p->sem_heap, post_ppd_release, NULL);
 
                return NULL;
diff --git a/ksrc/skins/native/heap.c b/ksrc/skins/native/heap.c
index eacb3f0..d9276fb 100644
--- a/ksrc/skins/native/heap.c
+++ b/ksrc/skins/native/heap.c
@@ -266,7 +266,8 @@ int rt_heap_create(RT_HEAP *heap, const char *name, size_t 
heapsize, int mode)
                                         heapsize,
                                         ((mode & H_DMA) ? GFP_DMA : 0)
                                         | ((mode & H_NONCACHED) ?
-                                           XNHEAP_GFP_NONCACHED : 0));
+                                           XNHEAP_GFP_NONCACHED : 0),
+                                        "rt_heap: %s", name);
                if (err)
                        return err;
 
@@ -286,7 +287,8 @@ int rt_heap_create(RT_HEAP *heap, const char *name, size_t 
heapsize, int mode)
                if (!heapmem)
                        return -ENOMEM;
 
-               err = xnheap_init(&heap->heap_base, heapmem, heapsize, 
XNHEAP_PAGE_SIZE);
+               err = xnheap_init(&heap->heap_base, heapmem, heapsize,
+                                 XNHEAP_PAGE_SIZE, "rt_heap: %s", name);
                if (err) {
                        xnarch_free_host_mem(heapmem, heapsize);
                        return err;
diff --git a/ksrc/skins/native/pipe.c b/ksrc/skins/native/pipe.c
index 672fa7a..18d9aa0 100644
--- a/ksrc/skins/native/pipe.c
+++ b/ksrc/skins/native/pipe.c
@@ -295,7 +295,9 @@ int rt_pipe_create(RT_PIPE *pipe, const char *name, int 
minor, size_t poolsize)
                        return -ENOMEM;
 
                /* Use natural page size */
-               err = xnheap_init(&pipe->privpool, poolmem, poolsize, 
XNHEAP_PAGE_SIZE);
+               err = xnheap_init(&pipe->privpool, poolmem, poolsize,
+                                 XNHEAP_PAGE_SIZE,
+                                 "rt_pipe: %d / %s", minor, name);
                if (err) {
                        xnarch_free_host_mem(poolmem, poolsize);
                        return err;
diff --git a/ksrc/skins/native/queue.c b/ksrc/skins/native/queue.c
index 211925f..28d289d 100644
--- a/ksrc/skins/native/queue.c
+++ b/ksrc/skins/native/queue.c
@@ -229,7 +229,8 @@ int rt_queue_create(RT_QUEUE *q,
                err = xnheap_init_mapped(&q->bufpool,
                                         poolsize,
                                         ((mode & Q_DMA) ? GFP_DMA 
-                                         : XNARCH_SHARED_HEAP_FLAGS));
+                                         : XNARCH_SHARED_HEAP_FLAGS),
+                                        "rt_queue: %s", name);
                if (err)
                        return err;
 
@@ -249,7 +250,8 @@ int rt_queue_create(RT_QUEUE *q,
                if (!poolmem)
                        return -ENOMEM;
 
-               err = xnheap_init(&q->bufpool, poolmem, poolsize, 
XNHEAP_PAGE_SIZE);
+               err = xnheap_init(&q->bufpool, poolmem, poolsize,
+                                 XNHEAP_PAGE_SIZE, "rt_queue: %s", name);
                if (err) {
                        xnarch_free_host_mem(poolmem, poolsize);
                        return err;
diff --git a/ksrc/skins/posix/shm.c b/ksrc/skins/posix/shm.c
index c92096a..0f0bd1a 100644
--- a/ksrc/skins/posix/shm.c
+++ b/ksrc/skins/posix/shm.c
@@ -539,7 +539,9 @@ int ftruncate(int fd, off_t len)
                        int flags = XNARCH_SHARED_HEAP_FLAGS |
                                ((desc_flags & O_DIRECT) ? GFP_DMA : 0);
 
-                       err = -xnheap_init_mapped(&shm->heapbase, len, flags);
+                       err = -xnheap_init_mapped(&shm->heapbase, len, flags,
+                                                 "posix shm: %s",
+                                                 shm->nodebase.name);
                        if (err)
                                goto err_up;
 
diff --git a/ksrc/skins/psos+/rn.c b/ksrc/skins/psos+/rn.c
index 98f4500..3eb3ab9 100644
--- a/ksrc/skins/psos+/rn.c
+++ b/ksrc/skins/psos+/rn.c
@@ -191,7 +191,8 @@ u_long rn_create(const char *name,
 
                rnsize = xnheap_rounded_size(rnsize, PAGE_SIZE),
                err = xnheap_init_mapped(&rn->heapbase, rnsize, 
-                                        XNARCH_SHARED_HEAP_FLAGS);
+                                        XNARCH_SHARED_HEAP_FLAGS,
+                                        "psosrn: %s", name);
 
                if (err)
                        return err;
@@ -206,7 +207,8 @@ u_long rn_create(const char *name,
                 * Caller must have accounted for overhead and
                 * alignment since it supplies the memory space.
                 */
-               if (xnheap_init(&rn->heapbase, rnaddr, rnsize, 
XNHEAP_PAGE_SIZE) != 0)
+               if (xnheap_init(&rn->heapbase, rnaddr, rnsize,
+                               XNHEAP_PAGE_SIZE, "psosrn: %s", name) != 0)
                        return ERR_TINYRN;
 
        inith(&rn->link);
diff --git a/ksrc/skins/rtai/shm.c b/ksrc/skins/rtai/shm.c
index 21c3b07..0b33a57 100644
--- a/ksrc/skins/rtai/shm.c
+++ b/ksrc/skins/rtai/shm.c
@@ -151,7 +151,8 @@ static xnshm_a_t *create_new_heap(unsigned long name, int 
heapsize, int suprt)
        err = xnheap_init_mapped(p->heap,
                                 heapsize,
                                 (suprt == USE_GFP_KERNEL ? GFP_KERNEL : 0)
-                                | XNARCH_SHARED_HEAP_FLAGS);
+                                | XNARCH_SHARED_HEAP_FLAGS,
+                                "rtai heap: 0x%lx", name);
 #else /* !CONFIG_XENO_OPT_PERVASIVE */
        {
                void *heapmem;
@@ -164,7 +165,9 @@ static xnshm_a_t *create_new_heap(unsigned long name, int 
heapsize, int suprt)
                        err = -ENOMEM;
                } else {
 
-                       err = xnheap_init(p->heap, heapmem, heapsize, 
XNHEAP_PAGE_SIZE);
+                       err = xnheap_init(p->heap, heapmem, heapsize,
+                                         XNHEAP_PAGE_SIZE,
+                                         "rtai heap: 0x%lx", name);
                        if (err) {
                                xnarch_free_host_mem(heapmem, heapsize);
                        }
diff --git a/ksrc/skins/vrtx/heap.c b/ksrc/skins/vrtx/heap.c
index de60792..8f8a1d5 100644
--- a/ksrc/skins/vrtx/heap.c
+++ b/ksrc/skins/vrtx/heap.c
@@ -165,7 +165,8 @@ int sc_hcreate(char *heapaddr, u_long heapsize, unsigned 
log2psize, int *errp)
 #ifdef CONFIG_XENO_OPT_PERVASIVE
                heapsize = xnheap_rounded_size(heapsize, PAGE_SIZE);
                err = xnheap_init_mapped(&heap->sysheap, heapsize, 
-                                        XNARCH_SHARED_HEAP_FLAGS);
+                                        XNARCH_SHARED_HEAP_FLAGS,
+                                        "vrtx sysheap");
 
                if (err) {
                        *errp = ER_MEM;
@@ -184,7 +185,8 @@ int sc_hcreate(char *heapaddr, u_long heapsize, unsigned 
log2psize, int *errp)
                 * Caller must have accounted for overhead and
                 * alignment since it supplies the memory space.
                 */
-               err = xnheap_init(&heap->sysheap, heapaddr, heapsize, pagesize);
+               err = xnheap_init(&heap->sysheap, heapaddr, heapsize, pagesize,
+                                 "vrtx sysheap");
 
                if (err) {
                        if (err == -EINVAL)
diff --git a/ksrc/skins/vrtx/syscall.c b/ksrc/skins/vrtx/syscall.c
index 1623066..e3d2e31 100644
--- a/ksrc/skins/vrtx/syscall.c
+++ b/ksrc/skins/vrtx/syscall.c
@@ -1052,7 +1052,8 @@ static int __sc_pcreate(struct pt_regs *regs)
        /* Block size. */
        bsize = __xn_reg_arg3(regs);
 
-       err = xnheap_init_mapped(ptheap, ptsize, XNARCH_SHARED_HEAP_FLAGS);
+       err = xnheap_init_mapped(ptheap, ptsize, XNARCH_SHARED_HEAP_FLAGS,
+                                "vrtx ptheap");
 
        if (err)
                goto free_heap;


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to