5.4.2 场景1之运行在Head域Xenomai线程调用Xenomai系统调用read

点击查看《Xenomai/IPIPE源代码情景解析》 

5.4.2 场景1之运行在Head域Xenomai线程调用Xenomai系统调用read

参考《5.2.2 用户层:用latency演示Xenomai系统调用》,latency 是 Xenomai/Cobalt 实时内核提供的一个工具,用于测量系统的实时性能,特别是上下文切换和中断响应的延迟。它启动后,会新建一个display线程用于打印信息;会新建一个sampling线程用于延迟采样。

本文分析samping作为Xenomai实时线程,调用Xenomai系统调用read的过程:

第一步,ipipe_handle_syscall

第二步,handle_head_syscall

第三步,返回到ipipe_handle_syscall的第1187行

第四步,返回非0值到el0_svc_common第110行

第一步,ipipe_handle_syscall

第1186行,条件1(nr >= nr_syscalls)成立,因为从用户层传下来的write系统调用号0x10000051远大于Linux自身的系统调用数量nr_syscalls(294),具体参考《5.2 ARM64 Xenomai系统调用》。条件2(local_flags & _TIP_HEAD)成立,因为local_flags即ti->ipipe_flags,值为6。参考《5.3.2 ipipe_flags之TIP_HEAD》,_TIP_HEAD代表线程当前运行在head domain。条件1和条件2是与的关系,所以第1186行的if成立,会跳转到第1187行的快速路径ipipe_fastcall_hook。

第1187行,调用ipipe_fastcall_hook。在这个快速路径中,直接调用handle_head_syscall。

int ipipe_fastcall_hook(struct pt_regs *regs)
{
	int ret;

	ret = handle_head_syscall(false, regs);
	XENO_BUG_ON(COBALT, ret == KEVENT_PROPAGATE);

	return ret;
}
第二步,handle_head_syscall

handle_head_syscall函数比较长,分成两个部分来解释

(1)handle_head_syscall第483~第513行

第498行,通过__xn_syscall得到bind在xenomai中的系统调用号81。具体原理参考《5.2.3 内核层:Xenomai系统调用的流程》。

第512行,从Xenomai系统调用表中,找出bind系统调用的CoBaLt_read函数指针。

第513行,从Xenomai系统模式表中,找出bind系统调用的调用模式。参考《5.2.4 内核层:Xenomai系统调用的定义》,在kernel/xenomai/posix/syscall_entries.h找到read系统调用模式为__COBALT_MODE(read, handover) ,即80(0x50)。

kernel/xenomai/posix/syscall.c:

/* Exec in current domain. */
#define __xn_exec_current    0x10
/* Attempt syscall restart in the opposite domain upon -ENOSYS. */
#define __xn_exec_adaptive   0x40

/* Hand over mode selection to syscall.  */
#define __xn_exec_handover  (__xn_exec_current|__xn_exec_adaptive)

(2)handle_head_syscall第578~第557行

第578行,因为bind系统调用模式为__COBALT_MODE(bind, lostage),条件成立。

第562行,caller_is_relaxed是false,不会跳转到第588行返回。

第598行,获取当前进程调用系统调用的参数,存入args。

第600行,调用CoBaLt_read,再继续调用rtdm_fd_read函数。

COBALT_SYSCALL(read, handover,
	       (int fd, void __user *buf, size_t size))
{
	return rtdm_fd_read(fd, buf, size);
}

在此之后,会根据CoBaLt_read的返回值执行一些逻辑,最终返回ipipe_fastcall_hook,在返回到ipipe_handle_syscall的第1187行。

第三步,返回到ipipe_handle_syscall的第1187行

第1187行,从ipipe_fastcall_hook返回,完全不检查返回值。

第1188行,重新读取当前任务的ipipe_flags。

第1189~1192行,如果当前仍然运行在HEAD域,检查是否有_TIP_MAYDAY标记,如果有,参照《5.3.4 ipipe_flags之TIP_MAYDAY》,进行处理,如果没有则返回1.

第1193行~1195行,如果当前切换到了root域,回放root domain的中断,返回-1.

无论上述判断如何,最终从ipipe_handle_syscall返回的值,肯定是非0值。

第四步,返回非0值到el0_svc_common第110行

第111行,因为ret等于-1或1,条件成立,最终在第117行返回,完成系统调用!

第131行,此行完全没有机会也没有必要执行了!

点击查看《Xenomai/IPIPE源代码情景解析》 

原创不易,需要大家多多鼓励!您的关注、点赞、收藏就是我的创作动力!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值