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

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Sun Dec 29 00:25:12 2013 +0100

cobalt/fd: use kmalloc/kfree to allocate fd based objects

Since the object creation requires calling __real_open, thus entails
a switch to secondary mode.

Move the fd destruction callback to an ipipe root work, to allow using
kfree in these callbacks.

---

 kernel/cobalt/fd.c            |   25 ++++++++++++++++++++--
 kernel/cobalt/posix/mqueue.c  |   47 +++++++++++++----------------------------
 kernel/cobalt/posix/syscall.c |    2 +-
 kernel/cobalt/posix/timerfd.c |    6 +++---
 4 files changed, 42 insertions(+), 38 deletions(-)

diff --git a/kernel/cobalt/fd.c b/kernel/cobalt/fd.c
index 13e9239..c45f6c5 100644
--- a/kernel/cobalt/fd.c
+++ b/kernel/cobalt/fd.c
@@ -135,6 +135,19 @@ struct xnfd *xnfd_get(int ufd, struct mm_struct *mm, 
unsigned magic)
        return res;
 }
 
+struct lostage_destroy {
+       struct ipipe_work_header work; /* Must be first */
+       struct xnfd *xnfd;
+};
+
+static void lostage_destroy(struct ipipe_work_header *work)
+{
+       struct lostage_destroy *rq;
+       
+       rq = container_of(work, struct lostage_destroy, work);
+       rq->xnfd->ops->destroy(rq->xnfd);
+}
+
 static int xnfd_put_inner(struct xnfd *xnfd, spl_t s)
 {
        int destroy;
@@ -153,8 +166,16 @@ static int xnfd_put_inner(struct xnfd *xnfd, spl_t s)
        }
        xnlock_put_irqrestore(&xnfd_lock, s);
        
-       if (destroy)
-               xnfd->ops->destroy(xnfd);
+       if (destroy) {
+               struct lostage_destroy destroywork = {
+                       .work = {
+                               .size = sizeof(destroywork),
+                               .handler = lostage_destroy,
+                       },
+                       .xnfd = xnfd,
+               };
+               ipipe_post_work_root(&destroywork, work);
+       }
 
        return 0;
 }
diff --git a/kernel/cobalt/posix/mqueue.c b/kernel/cobalt/posix/mqueue.c
index db65093..bfad002 100644
--- a/kernel/cobalt/posix/mqueue.c
+++ b/kernel/cobalt/posix/mqueue.c
@@ -173,30 +173,8 @@ static inline int mq_init(struct cobalt_mq *mq, const 
struct mq_attr *attr)
        return 0;
 }
 
-struct lostage_memfree {
-       struct ipipe_work_header work; /* Must be first. */
-       void *mem;
-       size_t memsize;
-};
-
-static void lostage_mq_memfree(struct ipipe_work_header *work)
-{
-       struct lostage_memfree *rq;
-
-       rq = container_of(work, struct lostage_memfree, work);
-       free_pages_exact(rq->mem, rq->memsize);
-}
-
 static inline void mq_destroy(struct cobalt_mq *mq)
 {
-       struct lostage_memfree freework = {
-               .work = {
-                       .size = sizeof(freework),
-                       .handler = lostage_mq_memfree,
-               },
-               .mem = mq->mem,
-               .memsize = mq->memsize,
-       };
        int resched;
        spl_t s;
 
@@ -211,9 +189,9 @@ static inline void mq_destroy(struct cobalt_mq *mq)
        xnlock_put_irqrestore(&nklock, s);
        xnselect_destroy(&mq->read_select);
        xnselect_destroy(&mq->write_select);
-       ipipe_post_work_root(&freework, work);
        xnregistry_remove(mq->handle);
-       xnfree(mq);
+       free_pages_exact(mq->mem, mq->memsize);
+       kfree(mq);
 
        if (resched)
                xnsched_run();
@@ -232,19 +210,25 @@ static int mq_unref_inner(struct cobalt_mq *mq, spl_t s)
        return destroy;
 }      
 
+static int mq_unref(struct cobalt_mq *mq)
+{
+       spl_t s;
+       
+       xnlock_get_irqsave(&nklock, s);
+       return mq_unref_inner(mq, s);
+}
+
 static void mqd_destroy(struct xnfd *xnfd)
 {
        struct cobalt_mqd *mqd = container_of(xnfd, struct cobalt_mqd, xnfd);
        struct cobalt_mq *mq = mqd->mq;
-       spl_t s;
 
 #if XENO_DEBUG(COBALT)
        printk(XENO_INFO "closing Cobalt message queue descriptor %d\n",
                xnfd_getfd(&mqd->xnfd));
 #endif
-       xnfree(mqd);
-       xnlock_get_irqsave(&nklock, s);
-       mq_unref_inner(mq, s);
+       kfree(mqd);
+       mq_unref(mq);
 }
 
 int mqd_select_bind(struct xnfd *xnfd, struct xnselector *selector,
@@ -312,7 +296,7 @@ static inline int mqd_create(struct cobalt_mq *mq, unsigned 
long flags, int ufd)
        if (p == &__xnsys_global_ppd)
                return -EPERM;
        
-       mqd = xnmalloc(sizeof(*mqd));
+       mqd = kmalloc(sizeof(*mqd), GFP_KERNEL);
        if (mqd == NULL)
                return -ENOSPC;
 
@@ -427,8 +411,7 @@ static int mq_open(int uqd, const char *name, int oflags, 
...)
                err = mqd_create(mq, oflags & (O_NONBLOCK | COBALT_PERMS_MASK),
                                uqd);
                if (err < 0) {
-                       xnlock_get_irqsave(&nklock, s);
-                       mq_unref_inner(mq, s);
+                       mq_unref(mq);
                        return err;
                }
                break;
@@ -438,7 +421,7 @@ static int mq_open(int uqd, const char *name, int oflags, 
...)
                if ((oflags & O_CREAT) == 0)
                        return (mqd_t)-ENOENT;
                
-               mq = xnmalloc(sizeof(*mq));
+               mq = kmalloc(sizeof(*mq), GFP_KERNEL);
                if (mq == NULL)
                        return -ENOSPC;
 
diff --git a/kernel/cobalt/posix/syscall.c b/kernel/cobalt/posix/syscall.c
index 4332517..6603d94 100644
--- a/kernel/cobalt/posix/syscall.c
+++ b/kernel/cobalt/posix/syscall.c
@@ -139,7 +139,7 @@ static struct xnsyscall cobalt_syscalls[] = {
        SKINCALL_DEF(sc_cobalt_timer_settime, cobalt_timer_settime, primary),
        SKINCALL_DEF(sc_cobalt_timer_gettime, cobalt_timer_gettime, any),
        SKINCALL_DEF(sc_cobalt_timer_getoverrun, cobalt_timer_getoverrun, any),
-       SKINCALL_DEF(sc_cobalt_timerfd_create, cobalt_timerfd_create, any),
+       SKINCALL_DEF(sc_cobalt_timerfd_create, cobalt_timerfd_create, lostage),
        SKINCALL_DEF(sc_cobalt_timerfd_gettime, cobalt_timerfd_gettime, any),
        SKINCALL_DEF(sc_cobalt_timerfd_settime, cobalt_timerfd_settime, any),
        SKINCALL_DEF(sc_cobalt_mutexattr_init, cobalt_mutexattr_init, any),
diff --git a/kernel/cobalt/posix/timerfd.c b/kernel/cobalt/posix/timerfd.c
index 4f05d97..41c293e 100644
--- a/kernel/cobalt/posix/timerfd.c
+++ b/kernel/cobalt/posix/timerfd.c
@@ -136,7 +136,7 @@ static void timerfd_destroy(struct xnfd *xnfd)
        resched = xnsynch_destroy(&tfd->readers) == XNSYNCH_RESCHED;
        xnlock_put_irqrestore(&nklock, s);
        xnselect_destroy(&tfd->read_select);
-       xnfree(tfd);
+       kfree(tfd);
        
        if (resched)
                xnsched_run();
@@ -175,7 +175,7 @@ int cobalt_timerfd_create(int ufd, int clockid, int flags)
        if (flags & ~TFD_CREATE_FLAGS)
                return -EINVAL;
        
-       tfd = xnmalloc(sizeof(*tfd));
+       tfd = kmalloc(sizeof(*tfd), GFP_KERNEL);
        if (tfd == NULL)
                return -ENOMEM;
        
@@ -238,7 +238,7 @@ int cobalt_timerfd_settime(int fd, int flags,
        xnlock_get_irqsave(&nklock, s);
 
        if (flags & TFD_WAKEUP) {
-               tfd->target = xnshadow_thread(current);
+               tfd->target = xnshadow_current();
                if (tfd->target == NULL) {
                        err = -EPERM;
                        goto out_unlock;


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

Reply via email to