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