diff --git a/include/asm-generic/xenomai/wrappers.h b/include/asm-generic/xenomai/wrappers.h index 7654047b4dad6778786d1c554e4239c4e4aa0dbb..0bded1d9bc076fa1f724eebbf727da1c3819088c 100644 --- a/include/asm-generic/xenomai/wrappers.h +++ b/include/asm-generic/xenomai/wrappers.h @@ -248,7 +248,9 @@ devm_hwmon_device_register_with_groups(struct device *dev, const char *name, } #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(5,14,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,14,0) && \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(5,11,0) || \ + LINUX_VERSION_CODE < KERNEL_VERSION(5,10,220)) #define close_fd(__ufd) __close_fd(current->files, __ufd) #endif @@ -258,7 +260,9 @@ devm_hwmon_device_register_with_groups(struct device *dev, const char *name, (LINUX_VERSION_CODE >= KERNEL_VERSION(5,5,0) || \ LINUX_VERSION_CODE < KERNEL_VERSION(5,4,251)) && \ (LINUX_VERSION_CODE >= KERNEL_VERSION(4,20,0) || \ - LINUX_VERSION_CODE < KERNEL_VERSION(4,19,291)) + LINUX_VERSION_CODE < KERNEL_VERSION(4,19,255) || \ + (LINUX_VERSION_CODE == KERNEL_VERSION(4,19,255) && \ + CONFIG_KVER_SUBLEVEL < 291)) #define dev_addr_set(dev, addr) memcpy((dev)->dev_addr, addr, MAX_ADDR_LEN) #define eth_hw_addr_set(dev, addr) memcpy((dev)->dev_addr, addr, ETH_ALEN) #endif diff --git a/include/xenomai/cobalt/kernel/thread.h b/include/xenomai/cobalt/kernel/thread.h index b79cb8429650e2503f2a5bc72040d19a613cb55c..325859b6a472b4f70e8482fe4ff2da074c604bee 100644 --- a/include/xenomai/cobalt/kernel/thread.h +++ b/include/xenomai/cobalt/kernel/thread.h @@ -65,6 +65,11 @@ struct lostage_signal { struct lostage_signal *self; /* Revisit: I-pipe requirement */ }; +struct lostage_wakeup { + struct pipeline_inband_work inband_work; /* Must be first. */ + struct task_struct *task; +}; + struct xnthread_init_attr { struct xnthread_personality *personality; cpumask_t affinity; @@ -215,6 +220,7 @@ struct xnthread { u32 proghash; /* Hash value for exe_path */ #endif struct lostage_signal sigarray[XNTHREAD_MAX_SIGNALS]; + struct lostage_wakeup relax_work; }; static inline int xnthread_get_state(const struct xnthread *thread) diff --git a/include/xenomai/pipeline/inband_work.h b/include/xenomai/pipeline/inband_work.h index af3d70fc69837df65a6013f836f25ba0322ab07f..826785e437c13e89c9795ac864d57d25aeea5f96 100644 --- a/include/xenomai/pipeline/inband_work.h +++ b/include/xenomai/pipeline/inband_work.h @@ -25,4 +25,7 @@ struct pipeline_inband_work { #define pipeline_post_inband_work(__work) \ irq_work_queue(&(__work)->inband_work.work) +#define pipeline_sync_inband_work(__work) \ + irq_work_sync(&(__work)->inband_work.work) + #endif /* !_COBALT_KERNEL_DOVETAIL_INBAND_WORK_H */ diff --git a/include/xenomai/rtdm/analogy/rtdm_helpers.h b/include/xenomai/rtdm/analogy/rtdm_helpers.h index 1de219f967b68bffe9f16dcd707f13122d6d79c4..6799183c19f14679d346ce2e1e637ae35af239af 100644 --- a/include/xenomai/rtdm/analogy/rtdm_helpers.h +++ b/include/xenomai/rtdm/analogy/rtdm_helpers.h @@ -65,7 +65,7 @@ #else /* !CONFIG_XENO_DRIVERS_ANALOGY_DEBUG */ -#define __a4l_dbg(level, debug, fmt, args...) +#define __a4l_dbg(level, debug, fmt, args...) do {} while (0) #endif /* CONFIG_XENO_DRIVERS_ANALOGY_DEBUG */ diff --git a/init/Kconfig b/init/Kconfig index e6499123b465eb32759f652583c7c0b2929a0b87..2e0b84f8ad4aa3df3c59cec6475a614fe40a815b 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -2449,8 +2449,8 @@ config XENO_VERSION_MINOR config XENO_REVISION_LEVEL int - default 4 + default 6 config XENO_VERSION_STRING string - default "3.2.4" + default "3.2.6" diff --git a/kernel/xenomai/posix/process.c b/kernel/xenomai/posix/process.c index 935007f821150737ea01ad25f18a90b0182528f1..d789c4cdd954647f140c0b591e0d2ec7bd5ad791 100644 --- a/kernel/xenomai/posix/process.c +++ b/kernel/xenomai/posix/process.c @@ -838,6 +838,7 @@ static void __handle_taskexit_event(struct task_struct *p) { struct cobalt_ppd *sys_ppd; struct xnthread *thread; + unsigned int n; spl_t s; /* @@ -861,6 +862,10 @@ static void __handle_taskexit_event(struct task_struct *p) xnthread_run_handler_stack(thread, exit_thread); + for (n = 0; n < XNTHREAD_MAX_SIGNALS; n++) + pipeline_sync_inband_work(&thread->sigarray[n]); + pipeline_sync_inband_work(&thread->relax_work); + if (xnthread_test_state(thread, XNUSER)) { cobalt_umm_free(&cobalt_kernel_ppd.umm, thread->u_window); thread->u_window = NULL; diff --git a/kernel/xenomai/posix/timer.c b/kernel/xenomai/posix/timer.c index a58ea99a363facb62f0e6a4890c53f0c452a8673..a115ded5358b33d92a5886705dbbd8ba1e5c56e1 100644 --- a/kernel/xenomai/posix/timer.c +++ b/kernel/xenomai/posix/timer.c @@ -43,7 +43,7 @@ void cobalt_timer_handler(struct xntimer *xntimer) EXPORT_SYMBOL_GPL(cobalt_timer_handler); static inline struct cobalt_thread * -timer_init(struct cobalt_timer *timer, +cobalt_timer_init(struct cobalt_timer *timer, const struct sigevent *__restrict__ evp) /* nklocked, IRQs off. */ { struct cobalt_thread *owner = cobalt_current_thread(), *target = NULL; @@ -88,7 +88,7 @@ timer_init(struct cobalt_timer *timer, return target; } -static inline int timer_alloc_id(struct cobalt_process *cc) +static inline int cobalt_timer_alloc_id(struct cobalt_process *cc) { int id; @@ -101,7 +101,7 @@ static inline int timer_alloc_id(struct cobalt_process *cc) return id; } -static inline void timer_free_id(struct cobalt_process *cc, int id) +static inline void cobalt_timer_free_id(struct cobalt_process *cc, int id) { __set_bit(id, cc->timers_map); } @@ -118,9 +118,9 @@ cobalt_timer_by_id(struct cobalt_process *cc, timer_t timer_id) return cc->timers[timer_id]; } -static inline int timer_create(clockid_t clockid, - const struct sigevent *__restrict__ evp, - timer_t * __restrict__ timerid) +static int cobalt_timer_create_internal(clockid_t clockid, + const struct sigevent *__restrict__ evp, + timer_t * __restrict__ timerid) { struct cobalt_process *cc; struct cobalt_thread *target; @@ -146,7 +146,7 @@ static inline int timer_create(clockid_t clockid, xnlock_get_irqsave(&nklock, s); - ret = timer_alloc_id(cc); + ret = cobalt_timer_alloc_id(cc); if (ret < 0) goto out; @@ -172,7 +172,7 @@ static inline int timer_create(clockid_t clockid, timer->sigp.si.si_tid = timer_id; timer->id = timer_id; - target = timer_init(timer, evp); + target = cobalt_timer_init(timer, evp); if (target == NULL) { ret = -EPERM; goto fail; @@ -192,7 +192,7 @@ static inline int timer_create(clockid_t clockid, return 0; fail: - timer_free_id(cc, timer_id); + cobalt_timer_free_id(cc, timer_id); out: xnlock_put_irqrestore(&nklock, s); @@ -201,19 +201,19 @@ static inline int timer_create(clockid_t clockid, return ret; } -static void timer_cleanup(struct cobalt_process *p, struct cobalt_timer *timer) +static void cobalt_timer_cleanup(struct cobalt_process *p, + struct cobalt_timer *timer) { xntimer_destroy(&timer->timerbase); if (!list_empty(&timer->sigp.next)) list_del(&timer->sigp.next); - timer_free_id(p, cobalt_timer_id(timer)); + cobalt_timer_free_id(p, cobalt_timer_id(timer)); p->timers[cobalt_timer_id(timer)] = NULL; } -static inline int -timer_delete(timer_t timerid) +static int cobalt_timer_delete_internal(timer_t timerid) { struct cobalt_process *cc; struct cobalt_timer *timer; @@ -248,7 +248,7 @@ timer_delete(timer_t timerid) else ret = 0; - timer_cleanup(cc, timer); + cobalt_timer_cleanup(cc, timer); xnlock_put_irqrestore(&nklock, s); xnfree(timer); @@ -273,9 +273,8 @@ void __cobalt_timer_getval(struct xntimer *__restrict__ timer, } } -static inline void -timer_gettimeout(struct cobalt_timer *__restrict__ timer, - struct itimerspec64 *__restrict__ value) +static void cobalt_timer_gettimeout(struct cobalt_timer *__restrict__ timer, + struct itimerspec64 *__restrict__ value) { int ret = 0; @@ -311,8 +310,9 @@ int __cobalt_timer_setval(struct xntimer *__restrict__ timer, int clock_flag, return xntimer_start(timer, start, period, clock_flag); } -static inline int timer_set(struct cobalt_timer *timer, int flags, - const struct itimerspec64 *__restrict__ value) +static inline int +cobalt_timer_set(struct cobalt_timer *timer, int flags, + const struct itimerspec64 *__restrict__ value) { /* nklocked, IRQs off. */ struct cobalt_thread *thread; int ret = 0; @@ -344,7 +344,7 @@ static inline int timer_set(struct cobalt_timer *timer, int flags, } static inline void -timer_deliver_late(struct cobalt_process *cc, timer_t timerid) +cobalt_timer_deliver_late(struct cobalt_process *cc, timer_t timerid) { struct cobalt_timer *timer; spl_t s; @@ -382,9 +382,9 @@ int __cobalt_timer_settime(timer_t timerid, int flags, } if (ovalue) - timer_gettimeout(timer, ovalue); + cobalt_timer_gettimeout(timer, ovalue); - ret = timer_set(timer, flags, value); + ret = cobalt_timer_set(timer, flags, value); if (ret == -ETIMEDOUT) { /* * Time has already passed, deliver a notification @@ -393,7 +393,7 @@ int __cobalt_timer_settime(timer_t timerid, int flags, * break the atomic section temporarily. */ xnlock_put_irqrestore(&nklock, s); - timer_deliver_late(cc, timerid); + cobalt_timer_deliver_late(cc, timerid); return 0; } out: @@ -418,7 +418,7 @@ int __cobalt_timer_gettime(timer_t timerid, struct itimerspec64 *value) if (timer == NULL) goto fail; - timer_gettimeout(timer, value); + cobalt_timer_gettimeout(timer, value); xnlock_put_irqrestore(&nklock, s); @@ -431,7 +431,7 @@ int __cobalt_timer_gettime(timer_t timerid, struct itimerspec64 *value) COBALT_SYSCALL(timer_delete, current, (timer_t timerid)) { - return timer_delete(timerid); + return cobalt_timer_delete_internal(timerid); } int __cobalt_timer_create(clockid_t clock, @@ -441,12 +441,12 @@ int __cobalt_timer_create(clockid_t clock, timer_t timerid = 0; int ret; - ret = timer_create(clock, sev, &timerid); + ret = cobalt_timer_create_internal(clock, sev, &timerid); if (ret) return ret; if (cobalt_copy_to_user(u_tm, &timerid, sizeof(timerid))) { - timer_delete(timerid); + cobalt_timer_delete_internal(timerid); return -EFAULT; } @@ -578,7 +578,7 @@ void cobalt_timer_reclaim(struct cobalt_process *p) continue; cobalt_call_extension(timer_cleanup, &timer->extref, ret); - timer_cleanup(p, timer); + cobalt_timer_cleanup(p, timer); xnlock_put_irqrestore(&nklock, s); xnfree(timer); xnlock_get_irqsave(&nklock, s); diff --git a/kernel/xenomai/rtdm/drvlib.c b/kernel/xenomai/rtdm/drvlib.c index 99d54f58f5e11ec4013596e44d1ab75d90ae5a4a..f4a2c5277fb0456b3bc6a8418238cd1d889b9399 100644 --- a/kernel/xenomai/rtdm/drvlib.c +++ b/kernel/xenomai/rtdm/drvlib.c @@ -1762,6 +1762,7 @@ static int mmap_iomem_helper(struct vm_area_struct *vma, phys_addr_t pa) { pgprot_t prot = PAGE_SHARED; unsigned long len; + int ret; len = vma->vm_end - vma->vm_start; #ifndef CONFIG_MMU @@ -1775,8 +1776,17 @@ static int mmap_iomem_helper(struct vm_area_struct *vma, phys_addr_t pa) #endif vma->vm_page_prot = pgprot_noncached(prot); - return remap_pfn_range(vma, vma->vm_start, pa >> PAGE_SHIFT, - len, vma->vm_page_prot); + ret = remap_pfn_range(vma, vma->vm_start, pa >> PAGE_SHIFT, + len, vma->vm_page_prot); + if (ret) + return ret; + +#ifdef CONFIG_MMU + if (cobalt_machine.prefault) + cobalt_machine.prefault(vma); +#endif + + return 0; } static int mmap_buffer_helper(struct rtdm_fd *fd, struct vm_area_struct *vma) diff --git a/kernel/xenomai/thread.c b/kernel/xenomai/thread.c index ff12f288ad4ca1b801a61a4d09ffe5a452403b48..343f1f0e09f54facae7a1d7307b2fe26c6fbbe09 100644 --- a/kernel/xenomai/thread.c +++ b/kernel/xenomai/thread.c @@ -1967,11 +1967,6 @@ int xnthread_harden(void) } EXPORT_SYMBOL_GPL(xnthread_harden); -struct lostage_wakeup { - struct pipeline_inband_work inband_work; /* Must be first. */ - struct task_struct *task; -}; - static void lostage_task_wakeup(struct pipeline_inband_work *inband_work) { struct lostage_wakeup *rq; @@ -2045,11 +2040,6 @@ void __xnthread_propagate_schedparam(struct xnthread *curr) void xnthread_relax(int notify, int reason) { struct task_struct *p = current; - struct lostage_wakeup wakework = { - .inband_work = PIPELINE_INBAND_WORK_INITIALIZER(wakework, - lostage_task_wakeup), - .task = p, - }; struct xnthread *thread = xnthread_current(); int cpu __maybe_unused, suspension; kernel_siginfo_t si; @@ -2063,6 +2053,11 @@ void xnthread_relax(int notify, int reason) */ trace_cobalt_shadow_gorelax(reason); + thread->relax_work.inband_work = (struct pipeline_inband_work) + PIPELINE_INBAND_WORK_INITIALIZER(thread->relax_work, + lostage_task_wakeup); + thread->relax_work.task = p; + /* * If you intend to change the following interrupt-free * sequence, /first/ make sure to check the special handling @@ -2075,7 +2070,7 @@ void xnthread_relax(int notify, int reason) */ splmax(); trace_cobalt_lostage_request("wakeup", p); - pipeline_post_inband_work(&wakework); + pipeline_post_inband_work(&thread->relax_work); /* * Grab the nklock to synchronize the Linux task state * manipulation with handle_sigwake_event. This lock will be