Module: xenomai-gch Branch: for-forge Commit: 1c3504760f67f8b6e6a7950bd1a080b5455bc6d8 URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=1c3504760f67f8b6e6a7950bd1a080b5455bc6d8
Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org> Date: Tue Jan 7 00:19:59 2014 +0100 cobalt: replace ppd mechanism Store the ppd in the ipipe_threadinfo structure in order to avoid the hash lookup most of the time. --- include/cobalt/kernel/ppd.h | 24 +-- include/cobalt/kernel/shadow.h | 28 ++- kernel/cobalt/debug.c | 3 - kernel/cobalt/include/ipipe/thread_info.h | 6 +- kernel/cobalt/posix/internal.h | 18 +- kernel/cobalt/posix/nsem.c | 3 +- kernel/cobalt/posix/process.h | 1 - kernel/cobalt/posix/syscall.c | 10 +- kernel/cobalt/rtdm/core.c | 8 +- kernel/cobalt/rtdm/internal.h | 2 - kernel/cobalt/rtdm/syscall.c | 9 +- kernel/cobalt/shadow.c | 335 ++++++++++++----------------- 12 files changed, 172 insertions(+), 275 deletions(-) diff --git a/include/cobalt/kernel/ppd.h b/include/cobalt/kernel/ppd.h index 05e32b3..20d6a6f 100644 --- a/include/cobalt/kernel/ppd.h +++ b/include/cobalt/kernel/ppd.h @@ -25,26 +25,10 @@ #include <cobalt/kernel/shadow.h> #include <cobalt/kernel/heap.h> -struct mm_struct; - -struct xnshadow_ppd_key { - unsigned long muxid; - struct mm_struct *mm; -}; - -struct xnshadow_ppd { - struct xnshadow_ppd_key key; - struct list_head link; -}; - -#define xnshadow_ppd_muxid(ppd) ((ppd)->key.muxid) -#define xnshadow_ppd_mm(ppd) ((ppd)->key.mm) - /* Called with nklock locked irqs off. */ -struct xnshadow_ppd *xnshadow_ppd_get(unsigned int muxid); +void *xnshadow_private_get(unsigned int muxid); struct xnsys_ppd { - struct xnshadow_ppd ppd; struct xnheap sem_heap; unsigned long mayday_addr; atomic_t refcnt; @@ -55,12 +39,12 @@ extern struct xnsys_ppd __xnsys_global_ppd; static inline struct xnsys_ppd *xnsys_ppd_get(int global) { - struct xnshadow_ppd *ppd; + struct xnsys_ppd *ppd; - if (global || (ppd = xnshadow_ppd_get(0)) == NULL) + if (global || (ppd = xnshadow_private_get(0)) == NULL) return &__xnsys_global_ppd; - return container_of(ppd, struct xnsys_ppd, ppd); + return ppd; } #endif /* _COBALT_KERNEL_PPD_H */ diff --git a/include/cobalt/kernel/shadow.h b/include/cobalt/kernel/shadow.h index 6423332..db5661b 100644 --- a/include/cobalt/kernel/shadow.h +++ b/include/cobalt/kernel/shadow.h @@ -30,7 +30,14 @@ struct timespec; struct timeval; struct completion; struct module; -struct xnshadow_ppd; + +#define NR_PERSONALITIES 4 + +struct xnshadow_process { + struct mm_struct *mm; + void *arg[NR_PERSONALITIES]; + struct hlist_node hlink; +}; struct xnpersonality { const char *name; @@ -39,8 +46,8 @@ struct xnpersonality { struct xnsyscall *syscalls; atomic_t refcnt; struct { - struct xnshadow_ppd *(*attach_process)(void); - void (*detach_process)(struct xnshadow_ppd *ppd); + void *(*attach_process)(void); + void (*detach_process)(void *ppd); struct xnpersonality *(*map_thread)(struct xnthread *thread); struct xnpersonality *(*relax_thread)(struct xnthread *thread); struct xnpersonality *(*harden_thread)(struct xnthread *thread); @@ -60,20 +67,21 @@ static inline struct xnthread *xnshadow_thread(struct task_struct *p) return ipipe_task_threadinfo(p)->thread; } -static inline struct mm_struct *xnshadow_current_mm(void) +static inline struct xnshadow_process *xnshadow_current_process(void) { - return ipipe_current_threadinfo()->mm; + return ipipe_current_threadinfo()->process; } -static inline struct mm_struct *xnshadow_swap_mm(struct mm_struct *mm) +static inline struct xnshadow_process * +xnshadow_swap_process(struct xnshadow_process *process) { struct ipipe_threadinfo *p = ipipe_current_threadinfo(); - struct mm_struct *oldmm; + struct xnshadow_process *old; - oldmm = p->mm; - p->mm = mm; + old = p->process; + p->process = process; - return oldmm; + return old; } int xnshadow_mount(void); diff --git a/kernel/cobalt/debug.c b/kernel/cobalt/debug.c index 226c5ee..10fbb53 100644 --- a/kernel/cobalt/debug.c +++ b/kernel/cobalt/debug.c @@ -618,11 +618,8 @@ void xndebug_shadow_init(struct xnthread *thread) { struct xnsys_ppd *sys_ppd; size_t len; - spl_t s; - xnlock_get_irqsave(&nklock, s); sys_ppd = xnsys_ppd_get(0); - xnlock_put_irqrestore(&nklock, s); /* * The caller is current, so we know for sure that sys_ppd * will still be valid after we dropped the lock. diff --git a/kernel/cobalt/include/ipipe/thread_info.h b/kernel/cobalt/include/ipipe/thread_info.h index 4fec9dc..ebecfc8 100644 --- a/kernel/cobalt/include/ipipe/thread_info.h +++ b/kernel/cobalt/include/ipipe/thread_info.h @@ -20,17 +20,17 @@ #define _COBALT_IPIPE_THREAD_INFO_H struct xnthread; -struct mm_struct; +struct xnshadow_process; struct ipipe_threadinfo { struct xnthread *thread; - struct mm_struct *mm; + struct xnshadow_process *process; }; static inline void __ipipe_init_threadinfo(struct ipipe_threadinfo *p) { p->thread = NULL; - p->mm = NULL; + p->process = NULL; } #endif /* !_COBALT_IPIPE_THREAD_INFO_H */ diff --git a/kernel/cobalt/posix/internal.h b/kernel/cobalt/posix/internal.h index bf73ea3..915871f 100644 --- a/kernel/cobalt/posix/internal.h +++ b/kernel/cobalt/posix/internal.h @@ -51,27 +51,17 @@ extern int cobalt_muxid; static inline struct cobalt_process *cobalt_process_context(void) { - struct xnshadow_ppd *ppd; - spl_t s; - - xnlock_get_irqsave(&nklock, s); - ppd = xnshadow_ppd_get(cobalt_muxid); - xnlock_put_irqrestore(&nklock, s); - - if (ppd == NULL) - return NULL; - - return container_of(ppd, struct cobalt_process, ppd); + return xnshadow_private_get(cobalt_muxid); } static inline struct cobalt_kqueues *cobalt_kqueues(int pshared) { - struct xnshadow_ppd *ppd; + struct cobalt_process *ppd; - if (pshared || (ppd = xnshadow_ppd_get(cobalt_muxid)) == NULL) + if (pshared || (ppd = xnshadow_private_get(cobalt_muxid)) == NULL) return &cobalt_global_kqueues; - return &container_of(ppd, struct cobalt_process, ppd)->kqueues; + return &ppd->kqueues; } int cobalt_init(void); diff --git a/kernel/cobalt/posix/nsem.c b/kernel/cobalt/posix/nsem.c index c19faaf..b7714bb 100644 --- a/kernel/cobalt/posix/nsem.c +++ b/kernel/cobalt/posix/nsem.c @@ -20,6 +20,7 @@ #include <linux/err.h> #include <cobalt/kernel/lock.h> #include <cobalt/kernel/heap.h> +#include <cobalt/kernel/shadow.h> #include "internal.h" #include "sem.h" @@ -284,7 +285,7 @@ void cobalt_sem_usems_cleanup(struct cobalt_process *cc) list_for_each_entry_safe(u, next, &cc->usems, link) { u->refs = 1; - nsem_close(u->sem->handle, cc->ppd.key.mm); + nsem_close(u->sem->handle, xnshadow_current_process()->mm); } } diff --git a/kernel/cobalt/posix/process.h b/kernel/cobalt/posix/process.h index 42f3afd..7754d64 100644 --- a/kernel/cobalt/posix/process.h +++ b/kernel/cobalt/posix/process.h @@ -35,7 +35,6 @@ struct cobalt_process { struct cobalt_kqueues kqueues; struct list_head uqds; struct list_head usems; - struct xnshadow_ppd ppd; struct list_head sigwaiters; }; diff --git a/kernel/cobalt/posix/syscall.c b/kernel/cobalt/posix/syscall.c index f79fa60..ffa9584 100644 --- a/kernel/cobalt/posix/syscall.c +++ b/kernel/cobalt/posix/syscall.c @@ -41,7 +41,7 @@ int cobalt_muxid; -static struct xnshadow_ppd *cobalt_process_attach(void) +static void *cobalt_process_attach(void) { struct cobalt_process *cc; @@ -60,14 +60,12 @@ static struct xnshadow_ppd *cobalt_process_attach(void) INIT_LIST_HEAD(&cc->usems); INIT_LIST_HEAD(&cc->sigwaiters); - return &cc->ppd; + return cc; } -static void cobalt_process_detach(struct xnshadow_ppd *ppd) +static void cobalt_process_detach(void *ppd) { - struct cobalt_process *cc; - - cc = container_of(ppd, struct cobalt_process, ppd); + struct cobalt_process *cc = ppd; cobalt_sem_usems_cleanup(cc); cobalt_mq_uqds_cleanup(cc); diff --git a/kernel/cobalt/rtdm/core.c b/kernel/cobalt/rtdm/core.c index 6750946..b4f2a81 100644 --- a/kernel/cobalt/rtdm/core.c +++ b/kernel/cobalt/rtdm/core.c @@ -101,7 +101,6 @@ static int create_instance(struct rtdm_device *device, rtdm_user_info_t *user_info, int nrt_mem) { struct rtdm_dev_context *context; - struct xnshadow_ppd *ppd; spl_t s; int fd; @@ -158,12 +157,7 @@ static int create_instance(struct rtdm_device *device, context->ops = &device->ops; atomic_set(&context->close_lock_count, 1); - xnlock_get_irqsave(&nklock, s); - ppd = xnshadow_ppd_get(__rtdm_muxid); - xnlock_put_irqrestore(&nklock, s); - - context->reserved.owner = - ppd ? container_of(ppd, struct rtdm_process, ppd) : NULL; + context->reserved.owner = xnshadow_private_get(__rtdm_muxid); INIT_LIST_HEAD(&context->reserved.cleanup); return 0; diff --git a/kernel/cobalt/rtdm/internal.h b/kernel/cobalt/rtdm/internal.h index e5868a0..b5184c1 100644 --- a/kernel/cobalt/rtdm/internal.h +++ b/kernel/cobalt/rtdm/internal.h @@ -39,8 +39,6 @@ struct rtdm_process { char name[32]; pid_t pid; #endif /* CONFIG_XENO_OPT_VFILE */ - - struct xnshadow_ppd ppd; }; DECLARE_EXTERN_XNLOCK(rt_fildes_lock); diff --git a/kernel/cobalt/rtdm/syscall.c b/kernel/cobalt/rtdm/syscall.c index b6a063f..8f1b34c 100644 --- a/kernel/cobalt/rtdm/syscall.c +++ b/kernel/cobalt/rtdm/syscall.c @@ -103,7 +103,7 @@ static int sys_rtdm_sendmsg(int fd, const struct msghdr __user *u_msg, return __rt_dev_sendmsg(p, fd, &krnl_msg, flags); } -static struct xnshadow_ppd *rtdm_process_attach(void) +static void *rtdm_process_attach(void) { struct rtdm_process *process; @@ -116,14 +116,13 @@ static struct xnshadow_ppd *rtdm_process_attach(void) process->pid = current->pid; #endif /* CONFIG_XENO_OPT_VFILE */ - return &process->ppd; + return process; } -static void rtdm_process_detach(struct xnshadow_ppd *ppd) +static void rtdm_process_detach(void *ppd) { - struct rtdm_process *process; + struct rtdm_process *process = ppd; - process = container_of(ppd, struct rtdm_process, ppd); cleanup_process_files(process); kfree(process); } diff --git a/kernel/cobalt/shadow.c b/kernel/cobalt/shadow.c index 4fc51ca..3faeba7 100644 --- a/kernel/cobalt/shadow.c +++ b/kernel/cobalt/shadow.c @@ -70,9 +70,7 @@ static int xn_gid_arg = -1; module_param_named(xenomai_gid, xn_gid_arg, int, 0644); MODULE_PARM_DESC(xenomai_gid, "GID of the group with access to Xenomai services"); -#define PERSONALITIES_NR 4 - -struct xnpersonality *personalities[PERSONALITIES_NR]; +struct xnpersonality *personalities[NR_PERSONALITIES]; static int user_muxid = -1; @@ -82,157 +80,108 @@ static void *mayday_page; static struct xnsynch yield_sync; -static struct list_head *ppd_hash; -#define PPD_HASH_SIZE 13 - -union xnshadow_ppd_hkey { - struct mm_struct *mm; - uint32_t val; -}; +static struct hlist_head *process_hash; +#define PROCESS_HASH_SIZE 13 -/* - * ppd holder with the same mm collide and are stored contiguously in - * the same bucket, so that they can all be destroyed with only one - * hash lookup by ppd_remove_mm. - */ -static unsigned int ppd_lookup_inner(struct list_head **pq, - struct xnshadow_ppd **pholder, - struct xnshadow_ppd_key *pkey) +static unsigned __attribute__((pure)) process_hash_crunch(struct mm_struct *mm) { - union xnshadow_ppd_hkey key = { .mm = pkey->mm }; - struct xnshadow_ppd *ppd = NULL; - unsigned int bucket; - - bucket = jhash2(&key.val, sizeof(key) / sizeof(uint32_t), 0); - *pq = &ppd_hash[bucket % PPD_HASH_SIZE]; - - if (list_empty(*pq)) - goto out; + unsigned long hash = ((unsigned long)mm - PAGE_OFFSET) / sizeof(*mm); + return hash % PROCESS_HASH_SIZE; +} - list_for_each_entry(ppd, *pq, link) { - if (ppd->key.mm == pkey->mm && ppd->key.muxid == pkey->muxid) { - *pholder = ppd; - return 1; /* Exact match. */ - } - /* - * Order by increasing mm address. Within the same mm, - * order by decreasing muxid. - */ - if (ppd->key.mm > pkey->mm || - (ppd->key.mm == pkey->mm && ppd->key.muxid < pkey->muxid)) - /* Not found, return successor for insertion. */ - goto out; - } +static struct xnshadow_process *__process_hash_search(struct mm_struct *mm) +{ + unsigned bucket = process_hash_crunch(mm); + struct xnshadow_process *p; + + atomic_only(); - ppd = NULL; -out: - *pholder = ppd; + hlist_for_each_entry(p, &process_hash[bucket], hlink) + if (p->mm == mm) + return p; + + return NULL; +} - return 0; +static struct xnshadow_process *process_hash_search(struct mm_struct *mm) +{ + struct xnshadow_process *process; + spl_t s; + + xnlock_get_irqsave(&nklock, s); + process = __process_hash_search(mm); + xnlock_put_irqrestore(&nklock, s); + + return process; } -static int ppd_insert(struct xnshadow_ppd *holder) +static int process_hash_enter(struct xnshadow_process *p) { - struct xnshadow_ppd *next; - struct list_head *q; - unsigned int found; + struct mm_struct *mm = current->mm; + unsigned bucket = process_hash_crunch(mm); + int err; spl_t s; xnlock_get_irqsave(&nklock, s); - - found = ppd_lookup_inner(&q, &next, &holder->key); - if (found) { - xnlock_put_irqrestore(&nklock, s); - return -EBUSY; + if (__process_hash_search(mm)) { + err = -EBUSY; + goto out; } - if (next) - list_add_tail(&holder->link, &next->link); - else - list_add_tail(&holder->link, q); - + p->mm = mm; + hlist_add_head(&p->hlink, &process_hash[bucket]); + err = 0; + out: xnlock_put_irqrestore(&nklock, s); + return err; +} - return 0; +static void process_hash_remove(struct xnshadow_process *p) +{ + hlist_del(&p->hlink); } /* nklock locked, irqs off. */ -static struct xnshadow_ppd *ppd_lookup(unsigned int muxid, - struct mm_struct *mm) +static void *private_lookup(unsigned int muxid) { - struct xnshadow_ppd_key key; - struct xnshadow_ppd *holder; - struct list_head *q; - unsigned int found; - - key.muxid = muxid; - key.mm = mm; + struct xnshadow_process *p = xnshadow_current_process(); - found = ppd_lookup_inner(&q, &holder, &key); - if (!found) + if (p == NULL) + p = process_hash_search(current->mm); + if (p == NULL) return NULL; - return holder; + return p->arg[muxid]; } -static void ppd_remove(struct xnshadow_ppd *holder) +static inline void process_remove(struct xnshadow_process *p) { - struct list_head *q; - unsigned int found; + unsigned i; spl_t s; xnlock_get_irqsave(&nklock, s); + for (i = ARRAY_SIZE(p->arg); i != 0; i--) { + struct xnpersonality *personality; + unsigned muxid = i - 1; + void *arg = p->arg[muxid]; - found = ppd_lookup_inner(&q, &holder, &holder->key); - if (found) - list_del(&holder->link); + if (arg == NULL) + continue; - xnlock_put_irqrestore(&nklock, s); -} - -static inline void ppd_remove_mm(struct mm_struct *mm, - void (*destructor) (struct xnshadow_ppd *)) -{ - struct xnshadow_ppd *ppd, *next; - struct xnshadow_ppd_key key; - struct list_head *q; - spl_t s; - - key.muxid = ~0UL; /* seek first muxid for 'mm'. */ - key.mm = mm; - xnlock_get_irqsave(&nklock, s); - ppd_lookup_inner(&q, &ppd, &key); - - while (ppd && ppd->key.mm == mm) { - if (list_is_last(&ppd->link, q)) - next = NULL; - else - next = list_next_entry(ppd, link); - list_del(&ppd->link); xnlock_put_irqrestore(&nklock, s); - /* - * Releasing the nklock is safe here, if we assume - * that no insertion for the same mm will take place - * while we are running ppd_remove_mm(). - */ - destructor(ppd); - ppd = next; + + personality = personalities[muxid]; + personality->ops.detach_process(arg); + if (personality->module) + module_put(personality->module); + xnlock_get_irqsave(&nklock, s); + p->arg[muxid] = NULL; } - + process_hash_remove(p); xnlock_put_irqrestore(&nklock, s); -} - -static void detach_ppd(struct xnshadow_ppd *ppd) -{ - struct xnpersonality *personality; - unsigned int muxid; - muxid = xnshadow_ppd_muxid(ppd); - personality = personalities[muxid]; - personality->ops.detach_process(ppd); - if (personality->module) - module_put(personality->module); + kfree(p); } static void request_syscall_restart(struct xnthread *thread, @@ -835,14 +784,14 @@ static inline void init_threadinfo(struct xnthread *thread) p = ipipe_current_threadinfo(); p->thread = thread; - p->mm = current->mm; + p->process = process_hash_search(current->mm); } static inline void destroy_threadinfo(void) { struct ipipe_threadinfo *p = ipipe_current_threadinfo(); p->thread = NULL; - p->mm = NULL; + p->process = NULL; } static void pin_to_initial_cpu(struct xnthread *thread) @@ -919,7 +868,6 @@ int xnshadow_map_user(struct xnthread *thread, struct xnthread_start_attr attr; struct xnsys_ppd *sys_ppd; struct xnheap *sem_heap; - spl_t s; int ret; if (!xnthread_test_state(thread, XNUSER)) @@ -953,9 +901,7 @@ int xnshadow_map_user(struct xnthread *thread, } #endif /* CONFIG_MMU */ - xnlock_get_irqsave(&nklock, s); sys_ppd = xnsys_ppd_get(0); - xnlock_put_irqrestore(&nklock, s); sem_heap = &sys_ppd->sem_heap; u_window = xnheap_alloc(sem_heap, sizeof(*u_window)); @@ -1322,9 +1268,7 @@ static int handle_mayday_event(struct pt_regs *regs) XENO_BUGON(NUCLEUS, !xnthread_test_state(thread, XNUSER)); /* We enter the mayday handler with hw IRQs off. */ - xnlock_get(&nklock); sys_ppd = xnsys_ppd_get(0); - xnlock_put(&nklock); xnarch_handle_mayday(tcb, regs, sys_ppd->mayday_addr); @@ -1347,8 +1291,9 @@ static inline int raise_cap(int cap) static int xnshadow_sys_bind(unsigned int magic, struct xnsysinfo __user *u_breq) { - struct xnshadow_ppd *ppd = NULL, *sys_ppd = NULL; struct xnpersonality *personality; + void *arg = NULL, *sys_ppd = NULL; + struct xnshadow_process *process; unsigned long featreq, featmis; int muxid, abirev, ret; struct xnbindreq breq; @@ -1406,7 +1351,7 @@ static int xnshadow_sys_bind(unsigned int magic, xnlock_get_irqsave(&nklock, s); - for (muxid = 1; muxid < PERSONALITIES_NR; muxid++) { + for (muxid = 1; muxid < NR_PERSONALITIES; muxid++) { personality = personalities[muxid]; if (personality && personality->magic == magic) goto do_bind; @@ -1417,74 +1362,71 @@ static int xnshadow_sys_bind(unsigned int magic, return -ESRCH; do_bind: - - sys_ppd = ppd_lookup(0, current->mm); + process = __process_hash_search(current->mm); xnlock_put_irqrestore(&nklock, s); - if (sys_ppd) + if (process) goto muxid_eventcb; sys_ppd = personalities[user_muxid]->ops.attach_process(); if (IS_ERR(sys_ppd)) return PTR_ERR(sys_ppd); - if (sys_ppd == NULL) - goto muxid_eventcb; + process = kmalloc(sizeof(*process), GFP_KERNEL); + memset(process->arg, '\0', sizeof(process->arg)); + process->arg[user_muxid] = sys_ppd; - sys_ppd->key.muxid = 0; - sys_ppd->key.mm = current->mm; - if (ppd_insert(sys_ppd) == -EBUSY) { + ret = process_hash_enter(process); + if (ret == -EBUSY) { /* In case of concurrent binding (which can not happen with Xenomai libraries), detach right away the second ppd. */ personalities[user_muxid]->ops.detach_process(sys_ppd); sys_ppd = NULL; + kfree(process); + xnlock_get_irqsave(&nklock, s); + goto do_bind; } if (personality->module && !try_module_get(personality->module)) { ret = -ENOSYS; - goto fail_destroy_sys_ppd; + goto fail_destroy_process; } muxid_eventcb: - - xnlock_get_irqsave(&nklock, s); - ppd = ppd_lookup(muxid, current->mm); - xnlock_put_irqrestore(&nklock, s); - + arg = private_lookup(muxid); /* protect from the same process binding several times. */ - if (ppd) + if (arg) return muxid; - ppd = personality->ops.attach_process(); - if (IS_ERR(ppd)) { - ret = PTR_ERR(ppd); - goto fail_destroy_sys_ppd; + arg = personality->ops.attach_process(); + if (IS_ERR(arg)) { + ret = PTR_ERR(arg); + goto fail_destroy_process; } - if (ppd == NULL) + if (arg == NULL) return muxid; - ppd->key.muxid = muxid; - ppd->key.mm = current->mm; - - if (ppd_insert(ppd) == -EBUSY) { + xnlock_get_irqsave(&nklock, s); + if (process->arg[muxid]) { /* * In case of concurrent binding (which can not happen * with Xenomai libraries), detach right away the - * second ppd. + * second arg. */ - personality->ops.detach_process(ppd); - ppd = NULL; + xnlock_put_irqrestore(&nklock, s); + personality->ops.detach_process(arg); + arg = NULL; + } else { + process->arg[muxid] = arg; + xnlock_put_irqrestore(&nklock, s); } return muxid; - fail_destroy_sys_ppd: - if (sys_ppd) { - ppd_remove(sys_ppd); - personalities[user_muxid]->ops.detach_process(sys_ppd); - } + fail_destroy_process: + process_remove(process); return ret; } @@ -1493,7 +1435,7 @@ static int xnshadow_sys_info(int muxid, struct xnsysinfo __user *u_info) { struct xnsysinfo info; - if (muxid < 0 || muxid > PERSONALITIES_NR || + if (muxid < 0 || muxid > NR_PERSONALITIES || personalities[muxid] == NULL) return -EINVAL; @@ -1553,8 +1495,6 @@ static int xnshadow_sys_heap_info(struct xnheap_desc __user *u_hd, struct xnheap *heap; spl_t s; - xnlock_get_irqsave(&nklock, s); - switch(heap_nr) { case XNHEAP_PROC_PRIVATE_HEAP: case XNHEAP_PROC_SHARED_HEAP: @@ -1564,10 +1504,10 @@ static int xnshadow_sys_heap_info(struct xnheap_desc __user *u_hd, heap = &kheap; break; default: - xnlock_put_irqrestore(&nklock, s); return -EINVAL; } + xnlock_get_irqsave(&nklock, s); hd.handle = (unsigned long)heap; hd.size = xnheap_extentsize(heap); hd.area = xnheap_base_memory(heap); @@ -1696,7 +1636,7 @@ out: return pathname; } -static struct xnshadow_ppd *user_process_attach(void) +static void *user_process_attach(void) { struct xnsys_ppd *p; char *exe_path; @@ -1737,14 +1677,13 @@ static struct xnshadow_ppd *user_process_attach(void) atomic_set(&p->refcnt, 1); atomic_inc(&personalities[user_muxid]->refcnt); - return &p->ppd; + return p; } -static void user_process_detach(struct xnshadow_ppd *ppd) +static void user_process_detach(void *ppd) { - struct xnsys_ppd *p; + struct xnsys_ppd *p = ppd; - p = container_of(ppd, struct xnsys_ppd, ppd); if (p->exe_path) kfree(p->exe_path); xnheap_destroy_mapped(&p->sem_heap, post_ppd_release, NULL); @@ -1801,8 +1740,8 @@ EXPORT_SYMBOL_GPL(xnshadow_send_sig); * to the personality, on behalf of one of its threads. The * attach_process() handler may return: * - * . a pointer to a xnshadow_ppd structure, representing the context - * of the calling process for this personality; + * . an opaque pointer, representing the context of the calling + * process for this personality; * * . a NULL pointer, meaning that no per-process structure should be * attached to this process for this personality; @@ -1828,7 +1767,7 @@ int xnshadow_register_personality(struct xnpersonality *personality) xnlock_get_irqsave(&nklock, s); - for (muxid = 0; muxid < PERSONALITIES_NR; muxid++) { + for (muxid = 0; muxid < NR_PERSONALITIES; muxid++) { if (personalities[muxid] == NULL) { atomic_set(&personality->refcnt, 0); personalities[muxid] = personality; @@ -1838,7 +1777,7 @@ int xnshadow_register_personality(struct xnpersonality *personality) xnlock_put_irqrestore(&nklock, s); - if (muxid >= PERSONALITIES_NR) + if (muxid >= NR_PERSONALITIES) muxid = -EAGAIN; up(®istration_mutex); @@ -1861,7 +1800,7 @@ int xnshadow_unregister_personality(int muxid) secondary_mode_only(); - if (muxid < 0 || muxid >= PERSONALITIES_NR) + if (muxid < 0 || muxid >= NR_PERSONALITIES) return -EINVAL; down(®istration_mutex); @@ -1899,18 +1838,16 @@ EXPORT_SYMBOL_GPL(xnshadow_unregister_personality); * * @remark Tags: atomic-entry. */ -struct xnshadow_ppd *xnshadow_ppd_get(unsigned int muxid) +void *xnshadow_private_get(unsigned int muxid) { struct xnthread *curr = xnsched_current_thread(); - atomic_only(); - if (xnthread_test_state(curr, XNROOT|XNUSER)) - return ppd_lookup(muxid, xnshadow_current_mm() ?: current->mm); + return private_lookup(muxid); return NULL; } -EXPORT_SYMBOL_GPL(xnshadow_ppd_get); +EXPORT_SYMBOL_GPL(xnshadow_private_get); /** * Stack a new personality over an existing thread. @@ -1990,7 +1927,7 @@ static int handle_head_syscall(struct ipipe_domain *ipd, struct pt_regs *regs) thread, thread ? xnthread_name(thread) : NULL, muxid, muxop); - if (muxid < 0 || muxid >= PERSONALITIES_NR || muxop < 0) + if (muxid < 0 || muxid >= NR_PERSONALITIES || muxop < 0) goto bad_syscall; personality = personalities[muxid]; @@ -2278,8 +2215,6 @@ static int handle_taskexit_event(struct task_struct *p) /* p == current */ struct xnpersonality *personality; struct xnsys_ppd *sys_ppd; struct xnthread *thread; - struct mm_struct *mm; - spl_t s; /* * We are called for both kernel and user shadows over the @@ -2302,14 +2237,11 @@ static int handle_taskexit_event(struct task_struct *p) /* p == current */ xnsched_run(); if (xnthread_test_state(thread, XNUSER)) { - xnlock_get_irqsave(&nklock, s); sys_ppd = xnsys_ppd_get(0); - xnlock_put_irqrestore(&nklock, s); xnheap_free(&sys_ppd->sem_heap, thread->u_window); thread->u_window = NULL; - mm = xnshadow_current_mm(); if (atomic_dec_and_test(&sys_ppd->refcnt)) - ppd_remove_mm(mm, detach_ppd); + process_remove(xnshadow_current_process()); } /* @@ -2483,18 +2415,15 @@ static int handle_sigwake_event(struct task_struct *p) static int handle_cleanup_event(struct mm_struct *mm) { + struct xnshadow_process *old, *process; struct xnsys_ppd *sys_ppd; struct xnthread *thread; - struct mm_struct *old; - spl_t s; /* We are NOT called for exiting kernel shadows. */ - old = xnshadow_swap_mm(mm); - - xnlock_get_irqsave(&nklock, s); + process = process_hash_search(mm); + old = xnshadow_swap_process(process); sys_ppd = xnsys_ppd_get(0); - xnlock_put_irqrestore(&nklock, s); if (sys_ppd != &__xnsys_global_ppd) { /* * Detect a userland shadow running exec(), i.e. still @@ -2511,10 +2440,10 @@ static int handle_cleanup_event(struct mm_struct *mm) ipipe_disable_notifier(current); } if (atomic_dec_and_test(&sys_ppd->refcnt)) - ppd_remove_mm(mm, detach_ppd); + process_remove(process); } - xnshadow_swap_mm(old); + xnshadow_swap_process(old); return EVENT_PROPAGATE; } @@ -2726,16 +2655,16 @@ int xnshadow_mount(void) return ret; } - size = sizeof(struct list_head) * PPD_HASH_SIZE; - ppd_hash = kmalloc(size, GFP_KERNEL); - if (ppd_hash == NULL) { + size = sizeof(*process_hash) * PROCESS_HASH_SIZE; + process_hash = kmalloc(size, GFP_KERNEL); + if (process_hash == NULL) { xnshadow_cleanup(); - printk(XENO_ERR "cannot allocate PPD hash table\n"); + printk(XENO_ERR "cannot allocate processes hash table\n"); return -ENOMEM; } - for (i = 0; i < PPD_HASH_SIZE; i++) - INIT_LIST_HEAD(ppd_hash + i); + for (i = 0; i < PROCESS_HASH_SIZE; i++) + INIT_HLIST_HEAD(&process_hash[i]); user_muxid = xnshadow_register_personality(&user_personality); XENO_BUGON(NUCLEUS, user_muxid != 0); @@ -2750,9 +2679,9 @@ void xnshadow_cleanup(void) user_muxid = -1; } - if (ppd_hash) { - kfree(ppd_hash); - ppd_hash = NULL; + if (process_hash) { + kfree(process_hash); + process_hash = NULL; } mayday_cleanup_page(); _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git