Module: xenomai-jki
Branch: for-upstream
Commit: bdda0013bb4a666a1d2c55ef52c5dd55e5fb6f3b
URL:    
http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=bdda0013bb4a666a1d2c55ef52c5dd55e5fb6f3b

Author: Jan Kiszka <jan.kis...@siemens.com>
Date:   Mon Nov 16 14:39:42 2009 +0100

nucleus: Include all heaps in statistics

This extends /proc/xenomai/heap with statistics about all currently used
heaps. The required descriptive label is propagated via a new xnheap API
service, xnheap_set_label. Moreover, care is taken to flush nklock while
iterating of this potentially long list.

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

---

 include/nucleus/heap.h    |    6 +++
 ksrc/drivers/ipc/iddp.c   |    1 +
 ksrc/drivers/ipc/xddp.c   |    3 +
 ksrc/nucleus/heap.c       |   99 ++++++++++++++++++++++++++++++++++++++++-----
 ksrc/nucleus/module.c     |    2 +
 ksrc/nucleus/pod.c        |    2 +
 ksrc/nucleus/shadow.c     |    2 +
 ksrc/skins/native/heap.c  |    1 +
 ksrc/skins/native/pipe.c  |    2 +
 ksrc/skins/native/queue.c |    1 +
 ksrc/skins/posix/shm.c    |    3 +
 ksrc/skins/psos+/rn.c     |    2 +
 ksrc/skins/rtai/shm.c     |    1 +
 ksrc/skins/vrtx/heap.c    |    1 +
 ksrc/skins/vrtx/syscall.c |    2 +
 15 files changed, 118 insertions(+), 10 deletions(-)

diff --git a/include/nucleus/heap.h b/include/nucleus/heap.h
index 44db738..77fefa6 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 label[XNOBJECT_NAME_LEN+16];
+
 } xnheap_t;
 
 extern xnheap_t kheap;
@@ -226,6 +230,8 @@ int xnheap_init(xnheap_t *heap,
                u_long heapsize,
                u_long pagesize);
 
+void xnheap_set_label(xnheap_t *heap, const char *name, ...);
+
 void xnheap_destroy(xnheap_t *heap,
                    void (*flushfn)(xnheap_t *heap,
                                    void *extaddr,
diff --git a/ksrc/drivers/ipc/iddp.c b/ksrc/drivers/ipc/iddp.c
index a589d34..8a1b079 100644
--- a/ksrc/drivers/ipc/iddp.c
+++ b/ksrc/drivers/ipc/iddp.c
@@ -564,6 +564,7 @@ static int __iddp_bind_socket(struct rtipc_private *priv,
                        xnarch_free_host_mem(poolmem, poolsz);
                        goto fail;
                }
+               xnheap_set_label(&sk->privpool, "ippd: %d", port);
 
                sk->poolevt = &sk->privevt;
                sk->poolwait = &sk->privwait;
diff --git a/ksrc/drivers/ipc/xddp.c b/ksrc/drivers/ipc/xddp.c
index f62147a..c2a65e9 100644
--- a/ksrc/drivers/ipc/xddp.c
+++ b/ksrc/drivers/ipc/xddp.c
@@ -750,6 +750,9 @@ static int __xddp_bind_socket(struct rtipc_private *priv,
        if (sk->peer.sipc_port < 0)
                sk->peer = *sa;
 
+       if (poolsz > 0)
+               xnheap_set_label(sk->bufpool, "xddp: %d", sa->sipc_port);
+
        if (*sk->label) {
                ret = xnregistry_enter(sk->label, sk, &sk->handle,
                                       &__xddp_pnode);
diff --git a/ksrc/nucleus/heap.c b/ksrc/nucleus/heap.c
index 27a4ad7..8e82c9a 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;
@@ -167,6 +170,7 @@ int xnheap_init(xnheap_t *heap,
        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 +236,57 @@ int xnheap_init(xnheap_t *heap,
 
        appendq(&heap->extents, &extent->link);
 
+       snprintf(heap->label, sizeof(heap->label), "unlabeled @0x%p", heap);
+
+       xnlock_get_irqsave(&nklock, s);
+       appendq(&heapq, &heap->stat_link);
+       heapq_rev++;
+       xnlock_put_irqrestore(&nklock, s);
+
        xnarch_init_display_context(heap);
 
        return 0;
 }
 EXPORT_SYMBOL_GPL(xnheap_init);
 
+/*!
+ * \fn xnheap_set_label(xnheap_t *heap,const char *label,...)
+ * \brief Set the heap's label string.
+ *
+ * Set the heap label that will be used in statistic outputs.
+ *
+ * @param heap The address of a heap descriptor.
+ *
+ * @param label Label string displayed in statistic outputs. This parameter
+ * can be a format string, in which case succeeding parameters will be used
+ * to resolve the final label.
+ *
+ * Environments:
+ *
+ * This service can be called from:
+ *
+ * - Kernel module initialization/cleanup code
+ * - Kernel-based task
+ * - User-space task
+ *
+ * Rescheduling: never.
+ */
+
+void xnheap_set_label(xnheap_t *heap, const char *label, ...)
+{
+       va_list args;
+       spl_t s;
+
+       va_start(args, label);
+
+       xnlock_get_irqsave(&nklock, s);
+       vsnprintf(heap->label, sizeof(heap->label), label, args);
+       xnlock_put_irqrestore(&nklock, s);
+
+       va_end(args);
+}
+EXPORT_SYMBOL_GPL(xnheap_set_label);
+
 /*! 
  * \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 +322,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;
 
@@ -1232,6 +1286,7 @@ void xnheap_destroy_mapped(xnheap_t *heap,
                           void __user *mapaddr)
 {
        unsigned long len;
+       spl_t s;
 
        /*
         * Trying to unmap user memory without providing a release
@@ -1239,6 +1294,11 @@ void xnheap_destroy_mapped(xnheap_t *heap,
         */
        XENO_ASSERT(NUCLEUS, mapaddr == NULL || release, /* nop */);
 
+       xnlock_get_irqsave(&nklock, s);
+       removeq(&heapq, &heap->stat_link);
+       heapq_rev++;
+       xnlock_put_irqrestore(&nklock, s);
+
        len = xnheap_extentsize(heap);
 
        /*
@@ -1354,22 +1414,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->label);
+
+               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..5404182 100644
--- a/ksrc/nucleus/module.c
+++ b/ksrc/nucleus/module.c
@@ -104,6 +104,8 @@ int __init __xeno_sys_init(void)
                                 XNARCH_SHARED_HEAP_FLAGS);
        if (ret)
                goto cleanup_arch;
+
+       xnheap_set_label(&__xnsys_global_ppd.sem_heap, "global sem heap");
 #endif
        
 #ifdef __KERNEL__
diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c
index fb356c5..5690e95 100644
--- a/ksrc/nucleus/pod.c
+++ b/ksrc/nucleus/pod.c
@@ -388,6 +388,7 @@ int xnpod_init(void)
                        XNHEAP_PAGE_SIZE) != 0) {
                return -ENOMEM;
        }
+       xnheap_set_label(&kheap, "main heap");
 
 #if CONFIG_XENO_OPT_SYS_STACKPOOLSZ > 0
        /*
@@ -409,6 +410,7 @@ int xnpod_init(void)
                xnheap_destroy(&kheap, &xnpod_flush_heap, NULL);
                return -ENOMEM;
        }
+       xnheap_set_label(&kstacks, "stack pool");
 #endif /* CONFIG_XENO_OPT_SYS_STACKPOOLSZ > 0 */
 
        for (cpu = 0; cpu < nr_cpus; ++cpu) {
diff --git a/ksrc/nucleus/shadow.c b/ksrc/nucleus/shadow.c
index 6046143..23afea6 100644
--- a/ksrc/nucleus/shadow.c
+++ b/ksrc/nucleus/shadow.c
@@ -1897,6 +1897,8 @@ static void *xnshadow_sys_event(int event, void *data)
                        xnarch_free_host_mem(p, sizeof(*p));
                        return ERR_PTR(err);
                }
+               xnheap_set_label(&p->sem_heap,
+                                "private sem heap [%d]", current->pid);
 
                return &p->ppd;
 
diff --git a/ksrc/skins/native/heap.c b/ksrc/skins/native/heap.c
index eacb3f0..2a5de8c 100644
--- a/ksrc/skins/native/heap.c
+++ b/ksrc/skins/native/heap.c
@@ -292,6 +292,7 @@ int rt_heap_create(RT_HEAP *heap, const char *name, size_t 
heapsize, int mode)
                        return err;
                }
        }
+       xnheap_set_label(&heap->heap_base, "rt_heap: %s", name);
 
        xnsynch_init(&heap->synch_base, mode & (H_PRIO | H_FIFO), NULL);
        heap->handle = 0;       /* i.e. (still) unregistered heap. */
diff --git a/ksrc/skins/native/pipe.c b/ksrc/skins/native/pipe.c
index 672fa7a..d756758 100644
--- a/ksrc/skins/native/pipe.c
+++ b/ksrc/skins/native/pipe.c
@@ -300,6 +300,8 @@ int rt_pipe_create(RT_PIPE *pipe, const char *name, int 
minor, size_t poolsize)
                        xnarch_free_host_mem(poolmem, poolsize);
                        return err;
                }
+               xnheap_set_label(&pipe->privpool,
+                                "rt_pipe: %d / %s", minor, name);
 
                pipe->bufpool = &pipe->privpool;
        }
diff --git a/ksrc/skins/native/queue.c b/ksrc/skins/native/queue.c
index 211925f..6a71165 100644
--- a/ksrc/skins/native/queue.c
+++ b/ksrc/skins/native/queue.c
@@ -255,6 +255,7 @@ int rt_queue_create(RT_QUEUE *q,
                        return err;
                }
        }
+       xnheap_set_label(&q->bufpool, "rt_queue: %s", name);
 
        xnsynch_init(&q->synch_base, mode & (Q_PRIO | Q_FIFO), NULL);
        initq(&q->pendq);
diff --git a/ksrc/skins/posix/shm.c b/ksrc/skins/posix/shm.c
index c92096a..3524341 100644
--- a/ksrc/skins/posix/shm.c
+++ b/ksrc/skins/posix/shm.c
@@ -543,6 +543,9 @@ int ftruncate(int fd, off_t len)
                        if (err)
                                goto err_up;
 
+                       xnheap_set_label(&shm->heapbase,
+                                        "posix shm: %s", shm->nodebase.name);
+
                        shm->size = xnheap_max_contiguous(&shm->heapbase);
                        shm->addr = xnheap_alloc(&shm->heapbase, shm->size);
                        /* Required. */
diff --git a/ksrc/skins/psos+/rn.c b/ksrc/skins/psos+/rn.c
index 98f4500..1eef1a4 100644
--- a/ksrc/skins/psos+/rn.c
+++ b/ksrc/skins/psos+/rn.c
@@ -209,6 +209,8 @@ u_long rn_create(const char *name,
                if (xnheap_init(&rn->heapbase, rnaddr, rnsize, 
XNHEAP_PAGE_SIZE) != 0)
                        return ERR_TINYRN;
 
+       xnheap_set_label(&rn->heapbase, "psosrn: %s", name);
+
        inith(&rn->link);
        rn->rnsize = rnsize;
        rn->usize = usize;
diff --git a/ksrc/skins/rtai/shm.c b/ksrc/skins/rtai/shm.c
index 21c3b07..96b7ae1 100644
--- a/ksrc/skins/rtai/shm.c
+++ b/ksrc/skins/rtai/shm.c
@@ -176,6 +176,7 @@ static xnshm_a_t *create_new_heap(unsigned long name, int 
heapsize, int suprt)
                xnheap_free(&kheap, p);
                return NULL;
        }
+       xnheap_set_label(p->heap, "rtai heap: 0x%lx", name);
 
        p->chunk = xnheap_mapped_address(p->heap, 0);
 
diff --git a/ksrc/skins/vrtx/heap.c b/ksrc/skins/vrtx/heap.c
index de60792..5f70675 100644
--- a/ksrc/skins/vrtx/heap.c
+++ b/ksrc/skins/vrtx/heap.c
@@ -197,6 +197,7 @@ int sc_hcreate(char *heapaddr, u_long heapsize, unsigned 
log2psize, int *errp)
                        return 0;
                }
        }
+       xnheap_set_label(&heap->sysheap, "vrtx sysheap");
 
        heap->magic = VRTX_HEAP_MAGIC;
        inith(&heap->link);
diff --git a/ksrc/skins/vrtx/syscall.c b/ksrc/skins/vrtx/syscall.c
index 1623066..5933d39 100644
--- a/ksrc/skins/vrtx/syscall.c
+++ b/ksrc/skins/vrtx/syscall.c
@@ -1057,6 +1057,8 @@ static int __sc_pcreate(struct pt_regs *regs)
        if (err)
                goto free_heap;
 
+       xnheap_set_label(ptheap, "vrtx ptheap");
+
        /* Allocate the partition space as a single shared heap block. */
        ptaddr = xnheap_alloc(ptheap, ptsize);
        pid = sc_pcreate(pid, ptaddr, ptsize, bsize, &err);


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

Reply via email to