Xenomai隔离cpu

Xenomai隔离cpu


Xenomai源码解析第一章-xenomai_init(一)
前文提到多核状态下,会设置xenomai的cpu亲和性。
【原创】有利于提高xenomai 实时性的一些配置建议一文中提到了提高xenomai实时性的一些建议。其中有一条cpu隔离。笔者在raspberry4下的应用会设置xenomai.supported_cpus=0x3,即将cpu的第一个和第二个核孤立。拒绝linux内核对这两个核心的调度,然后仅由xenomai来调度。本文从xenomai的源码角度补充之前的文章,并分析xenomai是如何实现这一机制的

初始化实时调度cpu

cpumask_clear(&xnsched_realtime_cpus);
/**
 * cpumask_clear - clear all cpus (< nr_cpu_ids) in a cpumask
 * @dstp: the cpumask pointer
 */
static inline void cpumask_clear(struct cpumask *dstp)
{
	bitmap_zero(cpumask_bits(dstp), nr_cpumask_bits);
}
#define cpumask_bits(maskp) ((maskp)->bits)
#define nr_cpumask_bits	NR_CPUS

关于cpu掩码设置可以看文章CPU masks,这里会建立一个对用户机器cpus数目的位图,该函数会将每一个有效位都清除.
这里的xnsched_realtime_cpus如下

cpumask_t supported_cpus;
#define xnsched_realtime_cpus    cobalt_pipeline.supported_cpus

关于cpumask_t 的定义:

typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
//此处不再展开直接给出结果,具体可以查看上面的文章.
typedef struct cpumask 
{
   unsigned long bits[1]; 
} cpumask_t;
static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
{
   if (small_const_nbits(nbits))
   	*dst = 0UL;
   else {
   	unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
   	memset(dst, 0, len);
   }
}
···
上述会将xenomai支持的cpu位图都清零进行初始化.

读取用户设置的参数并设置位置

for_each_online_cpu(cpu) {
	if (supported_cpus_arg & (1UL << cpu))
		cpumask_set_cpu(cpu, &xnsched_realtime_cpus);
}
#define for_each_online_cpu(cpu)   for_each_cpu((cpu), cpu_online_mask)
#define for_each_cpu(cpu, mask)				\
	for ((cpu) = -1;				\
		(cpu) = cpumask_next((cpu), (mask)),	\
		(cpu) < nr_cpu_ids;)
#define cpu_online_mask   ((const struct cpumask *)&__cpu_online_mask)

这里的for_each_online_cpu(cpu)其实就是从0开始遍历有效的cpu,因为我们设置的参数xenomai.supported_cpus=0x3,即第一个核和第二个核,这里相当于转换到内核的0核和1核。并设置位图。

static inline void cpumask_set_cpu(unsigned int cpu, struct cpumask *dstp)
{
   set_bit(cpumask_check(cpu), cpumask_bits(dstp));
}
 static __always_inline void
 set_bit(long nr, volatile unsigned long *addr)
 {
         if (IS_IMMEDIATE(nr)) {
                asm volatile(LOCK_PREFIX "orb %1,%0"
                        : CONST_MASK_ADDR(nr, addr)
                        : "iq" ((u8)CONST_MASK(nr))
                        : "memory");
        } else {
                asm volatile(LOCK_PREFIX "bts %1,%0"
                        : BITOP_ADDR(addr) : "Ir" (nr) : "memory");
        }
 }

具体的执行流程可以查看之前那篇文章.

设置cobalt cpu亲和性

cobalt_cpu_affinity = xnsched_realtime_cpus;

结束语

在这后xenomai在调度的时候会检测核是否为设置的。但是大致检索一下还没有明白如何让linux内核不调度。目前猜测可能是xenomai屏蔽了核的时钟中断,对于被孤立的核,xenomai处理完之后不在转发,对于xenomai不调度的核心。xenomai不做处理直接转发。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值