From: Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>
To: Dmitriy Cherkasov <dmitriy@mperpetuo.com>
Cc: "xenomai@xenomai.org" <xenomai@xenomai.org>
Subject: Re: [Xenomai] xenomai/ipipe arm64 port
Date: Fri, 2 Oct 2015 12:01:42 +0200 [thread overview]
Message-ID: <20151002100142.GN31137@hermes.click-hack.org> (raw)
In-Reply-To: <560DC717.9050902@mperpetuo.com>
On Thu, Oct 01, 2015 at 04:51:51PM -0700, Dmitriy Cherkasov wrote:
> The following changes since commit 17095784c6d3d44dc7f1512ffab9bb957e298466:
>
> cobalt/arm64: leave mm tracking to the pipeline (2015-09-17 15:08:34
> +0200)
>
> are available in the git repository at:
>
> http://gitlab.mperpetuo.com/it/xenomai-3.git arm64-fp
Ok, I retrieved your code, some comments inlined:
> /*
> static void enable_fpsimd(void) {
> __asm__ __volatile__("mrs x1, cpacr_el1\n\
> orr x1, x1, #(0x3 << 20)\n\
> msr cpacr_el1, x1\n\
> isb" : : : "x1", "memory", "cc");
> }
> static void disable_fpsimd(void) {
> __asm__ __volatile__("mrs x1, cpacr_el1\n\
> and x1, x1, #~(0x3 << 20)\n\
> msr cpacr_el1, x1\n\
> isb" : : : "x1", "memory", "cc");
> }
Coding style: braces at the beginning of line, and you probably want to
make these functions inline.
> int xnarch_fault_fpu_p(struct ipipe_trap_data *d)
> {
> /* check if this is an FPU access trap to be handled by Xenomai */
> if(d->exception == IPIPE_TRAP_FPU_ACC){
> return 1;
> }
> /* FPU already enabled, propagate fault to kernel */
> return 0;
> }
return d->exception == IPIPE_TAP_FPU_ACC ?
> static inline struct fpsimd_state *get_fpu_owner(struct xnarchtcb *tcb) {
> return &(tcb->core.tsp->fpsimd_state);
> }
coding style, brace again
> void xnarch_leave_root(struct xnthread *root)
> {
> struct xnarchtcb *rootcb = xnthread_archtcb(root);
> rootcb->fpup = get_fpu_owner(rootcb);
> disable_fpsimd();
> }
This is not the place to disable fpu. The context switch is the place.
> void xnarch_save_fpu(struct xnthread *thread)
> {
> struct xnarchtcb *tcb = &(thread->tcb);
> if (xnarch_fpu_ptr(tcb))
> fpsimd_save_state(tcb->fpup);
> }
> void xnarch_switch_fpu(struct xnthread *from, struct xnthread *to)
> {
> struct fpsimd_state *const from_fpup = from ? from->tcb.fpup : NULL;
> struct fpsimd_state *const to_fpup = to->tcb.fpup;
> /*
> * This only gets called if XNFPU flag is set, or if migrating to Linux.
> * In both cases, this means turn on FPU and switch.
> */
> enable_fpsimd();
> if (xnthread_test_state(to, XNROOT) == 0) {
> if (from_fpup == to_fpup)
> return;
> if (from_fpup)
> fpsimd_save_state(from_fpup);
> fpsimd_load_state(to_fpup);
> }
> else {
> /* Going to Linux. */
> if (from_fpup)
> fpsimd_save_state(from_fpup);
> fpsimd_load_state(to_fpup);
> }
When returning to root, you can also skip reloading the fpu if
from_fpu == to_fpu. If they are equal, the real-time threads have
not touched the fpu context, thus it is still valid and what needs
to be done is to simply reenable the fpu.
> int xnarch_handle_fpu_fault(struct xnthread *from,
> struct xnthread *to, struct ipipe_trap_data *d)
> {
> spl_t s;
> if (xnthread_test_state(to, XNFPU))
> /* FPU is already enabled, probably an exception */
> return 0;
You want to BUG() here, since the fpu exception is unequivocally
related to access to disabled fpu, if this happens, it means there
is a bug somewhere.
> xnlock_get_irqsave(&nklock, s);
> xnthread_set_state(to, XNFPU);
> xnlock_put_irqrestore(&nklock, s);
> xnarch_switch_fpu(from, to);
> return 1;
> }
> void xnarch_init_shadow_tcb(struct xnthread *thread)
> {
> spl_t s;
> struct xnarchtcb *tcb = xnthread_archtcb(thread);
> tcb->fpup = &(tcb->core.host_task->thread.fpsimd_state);
> xnlock_get_irqsave(&nklock, s);
> xnthread_clear_state(thread, XNFPU);
> xnlock_put_irqrestore(&nklock, s);
> }
> #endif /* CONFIG_XENO_ARCH_FPU */
I am not sure you need taking the nklock here, the thread is in its
initialization process, it is not known by the scheduler yet, so
nothing should be able to change its state concurrently.
> void xnarch_switch_to(struct xnthread *out, struct xnthread *in)
> {
> struct xnarchtcb *out_tcb = &out->tcb, *in_tcb = &in->tcb;
> struct mm_struct *prev_mm, *next_mm;
> struct task_struct *next;
> next = in_tcb->core.host_task;
> prev_mm = out_tcb->core.active_mm;
> next_mm = in_tcb->core.mm;
> if (next_mm == NULL) {
> in_tcb->core.active_mm = prev_mm;
> enter_lazy_tlb(prev_mm, next);
> } else {
> ipipe_switch_mm_head(prev_mm, next_mm, next);
> /*
> * We might be switching back to the root thread,
> * which we preempted earlier, shortly after "current"
> * dropped its mm context in the do_exit() path
> * (next->mm == NULL). In that particular case, the
> * kernel expects a lazy TLB state for leaving the mm.
> */
> if (next->mm == NULL)
> enter_lazy_tlb(prev_mm, next);
> }
> xnarch_tls_thread_switch(in_tcb->core.tip->task);
> xnarch_contextidr_thread_switch(in_tcb->core.tip->task);
> /* check if we need to switch FPU on return to Linux */
> if (xnthread_test_state(in, XNROOT) == 1)
> xnarch_switch_fpu(out, in);
No, doing this here is wrong. xnarch_switch_fpu is called by the
cobalt core at the right moment.
*
> /*
> * Complete any pending TLB or cache maintenance on this CPU in case
> * the thread migrates to a different CPU.
> */
> dsb(ish);
> cpu_switch_to(out_tcb->core.tip->task, in_tcb->core.tip->task);
> }
You want to disable the fpu before calling cpu_switch_to. If
switching to a thread with XNFPU, xnarch_switch_fpu will be called,
which enables the fpu, and if switching to a thread without XNFPU,
we want the FPU to be disabled so that the task will take a fault
upon its first use of fpu.
--
Gilles.
https://click-hack.org
next prev parent reply other threads:[~2015-10-02 10:01 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-25 0:13 [Xenomai] xenomai/ipipe arm64 port Don Mahurin
2015-08-25 14:08 ` Philippe Gerum
2015-08-25 15:20 ` Jorge Ramirez Ortiz
2015-08-25 16:13 ` Jan Kiszka
2015-08-25 17:07 ` Jorge Ramirez Ortiz
2015-08-25 17:34 ` Jorge Ramirez Ortiz
2015-08-25 17:36 ` Jan Kiszka
2015-08-25 17:54 ` Jorge Ramirez Ortiz
2015-08-25 18:03 ` Jan Kiszka
2015-08-25 17:34 ` Jan Kiszka
2015-08-25 18:02 ` Jorge Ramirez Ortiz
2015-08-25 18:05 ` Don Mahurin
2015-08-25 18:34 ` Jorge Ramirez Ortiz
2015-08-25 18:36 ` Jan Kiszka
2015-08-25 18:43 ` Philippe Gerum
2015-08-25 18:52 ` Gilles Chanteperdrix
2015-08-26 14:40 ` Jorge Ramirez Ortiz
2015-08-26 16:30 ` Don Mahurin
2015-08-27 17:07 ` Jorge Ramirez Ortiz
2015-08-27 21:56 ` Don Mahurin
2015-09-01 17:45 ` Jorge Ramirez Ortiz
[not found] ` <CAPuu0=jX6ig5L7SJrmPVOhCmOm=gwxEmTafTpOqzE85hOji8CA@mail.gmail.com>
2015-09-01 19:11 ` Jorge Ramirez Ortiz
2015-09-01 19:24 ` Philippe Gerum
2015-09-01 20:14 ` Jorge Ramirez Ortiz
2015-09-01 21:02 ` Hongfei Cheng
2015-09-02 0:43 ` Don Mahurin
2015-09-07 16:03 ` Philippe Gerum
2015-09-24 19:39 ` Dmitriy Cherkasov
2015-09-25 15:02 ` Gilles Chanteperdrix
2015-09-25 17:14 ` Dmitriy Cherkasov
2015-09-25 18:01 ` Gilles Chanteperdrix
2015-09-26 11:24 ` Gilles Chanteperdrix
2015-09-28 23:57 ` Dmitriy Cherkasov
2015-09-29 0:12 ` Gilles Chanteperdrix
2015-09-29 12:54 ` Jorge Ramirez Ortiz
2015-09-29 17:31 ` Dmitriy Cherkasov
2015-09-29 17:47 ` Gilles Chanteperdrix
2015-09-29 20:17 ` Jorge Ramirez Ortiz
2015-09-29 17:05 ` Don Mahurin
2015-09-29 14:14 ` Lennart Sorensen
2015-09-29 20:49 ` Gilles Chanteperdrix
2015-10-01 23:51 ` Dmitriy Cherkasov
2015-10-02 10:01 ` Gilles Chanteperdrix [this message]
2015-10-02 11:55 ` Gilles Chanteperdrix
2015-10-02 20:18 ` Dmitriy Cherkasov
2015-10-03 9:53 ` Philippe Gerum
2015-10-03 10:01 ` Philippe Gerum
2015-10-03 10:05 ` Philippe Gerum
2015-09-01 19:30 ` Philippe Gerum
2015-09-01 20:47 ` Jorge Ramirez Ortiz
2015-09-01 19:44 ` Gilles Chanteperdrix
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20151002100142.GN31137@hermes.click-hack.org \
--to=gilles.chanteperdrix@xenomai.org \
--cc=dmitriy@mperpetuo.com \
--cc=xenomai@xenomai.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.