155 Star 693 Fork 537

OpenHarmony / kernel_liteos_m

 / 详情

【共建需求】【Kernel】支持多核SMP

进行中
任务 成员
创建于  
2022-02-11 10:29

【需求价值】:
支持多核SMP
【需求描述】:
支持多核SMP
【方案描述】:

【配套文档】:

【验收标准】:
1、实现多核基础功能:
1)多核启动框架;
2)多核调度;
3)绑核操作;
2、支持多核功能裁剪,即单核运行或多核运行;
3、保证多核运行尽量独立,减少竞态,提高并行能力;
4、多核性能测试工具,输出多核性能提升数据;
5、支持spinlock死锁检测机制;
6、输出需求分析、架构分析、详细设计、测试用例、开发指南、维测手段等文档;
【技能要求】:
1、熟悉内核调度模块;
2、熟悉架构多核启动流程;

评论 (6)

huangsox 创建了需求
LeonChan 任务状态待办的 修改为已拒绝
LeonChan 任务状态已拒绝 修改为设计中
展开全部操作日志

如果有方案了,可以直接在这边回复,也可以在交流群里发出来,让子系统负责人一起看看方案

kenneth 负责人设置为yhuan416

需求分析

liteos_m适配smp,主要需要修改的地方为arch、los_task、los_sched
arch需要新增接口用于多核适配
los_task模块需要将任务调度时用到的全局变量私有化
新增los_precpu,管理每个核心私有的属性

多核启动部分:
主核在对内核相关的对象完成初始化工作后,拉起从核。等待从核启动完成,再开始任务调度
初期,从核的启动可以(C部分)可以使用独有的函数。后期,在每个核心初始化时(私有的空闲任务,软件定时器等),应该使用统一的接口

关于任务调度的任务优先级问题,还需要再分析现有的代码

基于原子操作实现自旋锁

// arch
VOID  ArchSpinLock(UINT32 *rawlock)        // 上锁
INT32 ArchSpinTrylock(UINT32 *rawlock)     // 尝试上锁
VOID  ArchSpinUnlock(UINT32 *rawlock)      // 解锁

// LOS
typedef struct {
    UINT32 rawlock;
    ...
} LosSpinCB;

LOS_SpinLock(LosSpinCB *spin)
LOS_SpinTrylock         
LOS_SpinUnlock          
LOS_SpinLockSave        
LOS_SpinUnlockRestore

...

实现步骤

  1. 调整现有的代码,抽象成preCpu,将与任务调度相关的全局变量变成每个核心私有的变量

    1. arch需要提供一个通用的接口,获取当前核心id
    2. g_losTask g_idleTaskID g_swtmrTaskID 等变量需要私有化
    3. 需要调整任务调度相关的函数
  2. 多核启动框架

    1. arch提供接口用于唤醒从核
    2. 每个平台自己的启动汇编代码
    3. 主核启动后唤醒从核并等待从核启动后再开始调度
  3. 多核调度 绑核操作

    1. 任务优先级
    2. 支持绑核操作

目前大概的计划是这样,计划按照这个步骤实现

LiteOS_M SMP方案设计文档

杨泽霖
2022-4-26

需求:

1. 多核调度
2. 亲核特性
3. 多核引导

1. spinlock自旋锁

arch层

提供以下类型以及接口

typedef struct {
    ...
} ArchSpinRawLock;

INT32 ArchCurrCpuid(VOID);// 获取当前核心号 ( 0 , 1 , 2 ... )
VOID ArchSpinInit(ArchSpinRawLock *lock);
VOID ArchSpinLock(ArchSpinRawLock *lock);
VOID ArchSpinUnlock(ArchSpinRawLock *lock);
INT32 ArchSpinTrylock(ArchSpinRawLock *lock);

如果当前不需要开启自旋锁, 这些接口可以由通用的los_core.h内实现几个空函数代替
如果需要开启自旋锁功能, 需要在平台自己的arch目录下添加头文件 los_arch_core.h 并实现上述接口

kernel层

struct Spinlock {
	ArchSpinRawLock      rawLock;
	...
};

VOID LOS_SpinInit(struct Spinlock *lock);
VOID LOS_SpinLock(struct Spinlock *lock);
INT32 LOS_SpinTrylock(struct Spinlock *lock);
VOID LOS_SpinUnlock(struct Spinlock *lock);
VOID LOS_SpinLockSave(struct Spinlock *lock, UINT32 *intSave);
VOID LOS_SpinUnlockRestore(struct Spinlock *lock, UINT32 intSave);

spinlock死锁检测机制后续可以做到这个模块内

2. los_bitmap.c/los_bitmap.h

VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos);
VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos);
UINT16 LOS_HighBitGet(UINT32 bitmap);
UINT16 LOS_LowBitGet(UINT32 bitmap);

3. SchedRunqueue调度队列

typedef struct {
	SortLinkAttribute taskSortLinkList;							/*  超时等待任务队列, 如果任务是超时等待的状态, 
																		会加入这个队列, 触发超时之后, 唤醒任务进行调度 */
	LOS_DL_LIST 	  priQueueList[OS_PRIORITY_QUEUE_NUM];		/* 优先级队列 */
	UINT32 			  queueBitmap;								/* 优先级bitmap */
	UINT64            responseTime; 							/* Response time for current CPU tick interrupts */
	UINT32            responseID;   							/* The response ID of the current CPU tick interrupt */
	UINT32            idleTaskID;   							/* 空闲任务id */
	UINT32            taskLockCnt;  							/* 锁调度状态 */
	UINT32            schedFlag;    							/* 当前调度队列的调度状态 */
} SchedRunqueue;
	
// 全局变量
extern SchedRunqueue g_schedRunqueue[LOSCFG_KERNEL_CORE_NUM];

STATIC INLINE SchedRunqueue *OsGetRunQueue(INT32 cpuid)
{
	return &(g_schedRunqueue[cpuid]);
}

先基于现有的调度逻辑, 将于调度有关的全局变量抽象出来, 放在 SchedRunqueue 变量内部

4. 多核引导

LOS_KernelInit() 主核初始化相关流程
{
	...
	
	OsSmpInit(); // 拉起从核
}

// 从核初始化逻辑
VOID OsSmpSecondaryInit(VOID *arg)
{
#if (LOSCFG_BASE_CORE_SWTMR == 1)
	OsSwtmrInit();// 初始化软件定时器
#endif

	OsIdleTaskCreate();// 初始化从核的空闲任务

	OsSchedStart();// 开始调度
}

5. 亲核特性

任务创建之后, 根据它的亲核特性, 将其加入到对应的SchedRunqueue中
如果没有设置亲核属性, 判断当前哪个核心上的任务较少(后面可以换成判断哪个核心负载较低?)

// 根据taskCB判断当前的任务与哪个核相关
INT32 OsPickCpu(LosTaskCB *taskCB)
{
	...
	return cpuid;
}

每个任务在创建好之后只在固定的核心上进行调度。

注意模块解耦及可裁剪

Hongjin Li 修改了描述
Hongjin Li 任务类型需求 修改为任务
Hongjin Li 任务状态设计中 修改为待办的
Hongjin Li 任务状态待办的 修改为进行中

登录 后才可以发表评论

状态
负责人
项目
里程碑
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
开始日期   -   截止日期
-
置顶选项
优先级
预计工期 (小时)
参与者(4)
6580357 yhuan416 1604858120
C
1
https://gitee.com/openharmony/kernel_liteos_m.git
git@gitee.com:openharmony/kernel_liteos_m.git
openharmony
kernel_liteos_m
kernel_liteos_m

搜索帮助