feat: 支持cgroups
BREAKING CHANGE: 支持cgroups对外变更: 1.在proc目录下支持plimits目录,支持ipc, pid, memory, devices, sched控制器 Close #I6GVPL Signed-off-by: zhushengle <zhushengle@huawei.com> Change-Id: Ib996e07bf148abce9e40290d6188b763b52e89bb
This commit is contained in:
parent
57455849ca
commit
b45cdbda3e
5
BUILD.gn
5
BUILD.gn
|
@ -252,6 +252,11 @@ config("container_config") {
|
|||
"-DLOSCFG_TIME_CONTAINER",
|
||||
"-DLOSCFG_USER_CONTAINER",
|
||||
"-DLOSCFG_PROC_PROCESS_DIR",
|
||||
"-DLOSCFG_KERNEL_PLIMITS",
|
||||
"-DLOSCFG_KERNEL_MEM_PLIMIT",
|
||||
"-DLOSCFG_KERNEL_IPC_PLIMIT",
|
||||
"-DLOSCFG_KERNEL_DEV_PLIMIT",
|
||||
"-DLOSCFG_KERNEL_SCHED_PLIMIT",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,7 +113,9 @@ STATIC INLINE struct mqarray *GetMqueueCBByName(const CHAR *name)
|
|||
STATIC INT32 DoMqueueDelete(struct mqarray *mqueueCB)
|
||||
{
|
||||
UINT32 ret;
|
||||
|
||||
#ifdef LOSCFG_KERNEL_IPC_PLIMIT
|
||||
OsIPCLimitMqFree();
|
||||
#endif
|
||||
if (mqueueCB->mq_name != NULL) {
|
||||
LOS_MemFree(OS_SYS_MEM_ADDR, mqueueCB->mq_name);
|
||||
mqueueCB->mq_name = NULL;
|
||||
|
@ -163,11 +165,29 @@ STATIC int SaveMqueueName(const CHAR *mqName, struct mqarray *mqueueCB)
|
|||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC VOID MqueueCBInit(struct mqarray *mqueueCB, const struct mq_attr *attr, INT32 openFlag, UINT32 mode)
|
||||
{
|
||||
mqueueCB->unlinkflag = FALSE;
|
||||
mqueueCB->unlink_ref = 0;
|
||||
mqueueCB->mq_personal->mq_status = MQ_USE_MAGIC;
|
||||
mqueueCB->mq_personal->mq_next = NULL;
|
||||
mqueueCB->mq_personal->mq_posixdes = mqueueCB;
|
||||
mqueueCB->mq_personal->mq_flags = (INT32)((UINT32)openFlag | ((UINT32)attr->mq_flags & (UINT32)FNONBLOCK));
|
||||
mqueueCB->mq_personal->mq_mode = mode;
|
||||
mqueueCB->mq_personal->mq_refcount = 0;
|
||||
mqueueCB->mq_notify.pid = 0;
|
||||
}
|
||||
|
||||
STATIC struct mqpersonal *DoMqueueCreate(const struct mq_attr *attr, const CHAR *mqName, INT32 openFlag, UINT32 mode)
|
||||
{
|
||||
struct mqarray *mqueueCB = NULL;
|
||||
UINT32 mqueueID;
|
||||
|
||||
#ifdef LOSCFG_KERNEL_IPC_PLIMIT
|
||||
if (OsIPCLimitMqAlloc() != LOS_OK) {
|
||||
return (struct mqpersonal *)-1;
|
||||
}
|
||||
#endif
|
||||
UINT32 err = LOS_QueueCreate(NULL, attr->mq_maxmsg, &mqueueID, 0, attr->mq_msgsize);
|
||||
if (map_errno(err) != ENOERR) {
|
||||
goto ERROUT;
|
||||
|
@ -201,15 +221,7 @@ STATIC struct mqpersonal *DoMqueueCreate(const struct mq_attr *attr, const CHAR
|
|||
goto ERROUT;
|
||||
}
|
||||
|
||||
mqueueCB->unlinkflag = FALSE;
|
||||
mqueueCB->unlink_ref = 0;
|
||||
mqueueCB->mq_personal->mq_status = MQ_USE_MAGIC;
|
||||
mqueueCB->mq_personal->mq_next = NULL;
|
||||
mqueueCB->mq_personal->mq_posixdes = mqueueCB;
|
||||
mqueueCB->mq_personal->mq_flags = (INT32)((UINT32)openFlag | ((UINT32)attr->mq_flags & (UINT32)FNONBLOCK));
|
||||
mqueueCB->mq_personal->mq_mode = mode;
|
||||
mqueueCB->mq_personal->mq_refcount = 0;
|
||||
mqueueCB->mq_notify.pid = 0;
|
||||
MqueueCBInit(mqueueCB, attr, openFlag, mode);
|
||||
|
||||
return mqueueCB->mq_personal;
|
||||
ERROUT:
|
||||
|
@ -218,6 +230,9 @@ ERROUT:
|
|||
LOS_MemFree(OS_SYS_MEM_ADDR, mqueueCB->mq_name);
|
||||
mqueueCB->mq_name = NULL;
|
||||
}
|
||||
#ifdef LOSCFG_KERNEL_IPC_PLIMIT
|
||||
OsIPCLimitMqFree();
|
||||
#endif
|
||||
return (struct mqpersonal *)-1;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ kernel_module(module_name) {
|
|||
"os_adapt/fs_cache_proc.c",
|
||||
"os_adapt/mem_info.c",
|
||||
"os_adapt/mounts_proc.c",
|
||||
"os_adapt/plimits_proc.c",
|
||||
"os_adapt/power_proc.c",
|
||||
"os_adapt/proc_init.c",
|
||||
"os_adapt/proc_vfs.c",
|
||||
|
|
|
@ -55,6 +55,16 @@ void ProcSysMemInfoInit(void);
|
|||
void ProcFileSysInit(void);
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
void ProcLimitsInit(void);
|
||||
#endif
|
||||
|
||||
void ProcEntryClearVnode(struct ProcDirEntry *entry);
|
||||
|
||||
void ProcDetachNode(struct ProcDirEntry *pn);
|
||||
|
||||
void RemoveProcEntryTravalsal(struct ProcDirEntry *pn);
|
||||
|
||||
void ProcPmInit(void);
|
||||
|
||||
void ProcVmmInit(void);
|
||||
|
|
|
@ -93,6 +93,15 @@ struct ProcFileOperations {
|
|||
ssize_t (*readLink)(struct ProcDirEntry *pde, char *buf, size_t bufLen);
|
||||
};
|
||||
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
struct ProcDirOperations {
|
||||
int (*rmdir)(struct ProcDirEntry *parent, struct ProcDirEntry *pde, const char *name);
|
||||
int (*mkdir)(struct ProcDirEntry *parent, const char *dirName, mode_t mode, struct ProcDirEntry **pde);
|
||||
};
|
||||
#endif
|
||||
|
||||
#define PROC_DATA_STATIC 0
|
||||
#define PROC_DATA_FREE 1
|
||||
struct ProcDirEntry {
|
||||
uint uid;
|
||||
uint gid;
|
||||
|
@ -101,6 +110,10 @@ struct ProcDirEntry {
|
|||
const struct ProcFileOperations *procFileOps;
|
||||
struct ProcFile *pf;
|
||||
struct ProcDirEntry *next, *parent, *subdir;
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
const struct ProcDirOperations *procDirOps;
|
||||
#endif
|
||||
int dataType;
|
||||
void *data;
|
||||
atomic_t count; /* open file count */
|
||||
spinlock_t pdeUnloadLock;
|
||||
|
@ -111,6 +124,11 @@ struct ProcDirEntry {
|
|||
enum VnodeType type;
|
||||
};
|
||||
|
||||
struct ProcDataParm {
|
||||
void *data;
|
||||
int dataType;
|
||||
};
|
||||
|
||||
struct ProcFile {
|
||||
fmode_t fMode;
|
||||
spinlock_t fLock;
|
||||
|
@ -274,7 +292,7 @@ extern struct ProcDirEntry *ProcCreate(const char *name, mode_t mode,
|
|||
*
|
||||
*/
|
||||
extern struct ProcDirEntry *ProcCreateData(const char *name, mode_t mode, struct ProcDirEntry *parent,
|
||||
const struct ProcFileOperations *procFileOps, void *data);
|
||||
const struct ProcFileOperations *procFileOps, struct ProcDataParm *param);
|
||||
/**
|
||||
* @ingroup procfs
|
||||
* @brief init proc fs
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -72,6 +72,9 @@ void ProcFsInit(void)
|
|||
ProcSysMemInfoInit();
|
||||
ProcFileSysInit();
|
||||
#endif
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
ProcLimitsInit();
|
||||
#endif
|
||||
}
|
||||
|
||||
LOS_MODULE_INIT(ProcFsInit, LOS_INIT_LEVEL_KMOD_EXTENDED);
|
||||
|
|
|
@ -239,6 +239,53 @@ int VfsProcfsStat(struct Vnode *node, struct stat *buf)
|
|||
return LOS_OK;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
int VfsProcfsMkdir(struct Vnode *parent, const char *dirName, mode_t mode, struct Vnode **vnode)
|
||||
{
|
||||
struct ProcDirEntry *parentEntry = VnodeToEntry(parent);
|
||||
struct ProcDirEntry *pde = NULL;
|
||||
if ((parentEntry->procDirOps == NULL) || (parentEntry->procDirOps->mkdir == NULL)) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int ret = parentEntry->procDirOps->mkdir(parentEntry, dirName, mode, &pde);
|
||||
if ((ret < 0) || (pde == NULL)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
*vnode = EntryToVnode(pde);
|
||||
(*vnode)->vop = parent->vop;
|
||||
(*vnode)->parent = parent;
|
||||
(*vnode)->originMount = parent->originMount;
|
||||
if ((*vnode)->type == VNODE_TYPE_DIR) {
|
||||
(*vnode)->mode = S_IFDIR | PROCFS_DEFAULT_MODE;
|
||||
} else {
|
||||
(*vnode)->mode = S_IFREG | PROCFS_DEFAULT_MODE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int VfsProcfsRmdir(struct Vnode *parent, struct Vnode *vnode, const char *dirName)
|
||||
{
|
||||
if (parent == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
struct ProcDirEntry *parentEntry = VnodeToEntry(parent);
|
||||
if ((parentEntry->procDirOps == NULL) || (parentEntry->procDirOps->rmdir == NULL)) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
struct ProcDirEntry *dirEntry = VnodeToEntry(vnode);
|
||||
int ret = parentEntry->procDirOps->rmdir(parentEntry, dirEntry, dirName);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
vnode->data = NULL;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int VfsProcfsReaddir(struct Vnode *node, struct fs_dirent_s *dir)
|
||||
{
|
||||
int result;
|
||||
|
@ -350,7 +397,7 @@ int VfsProcfsClose(struct file *filep)
|
|||
VnodeHold();
|
||||
struct Vnode *node = filep->f_vnode;
|
||||
struct ProcDirEntry *pde = VnodeToEntry(node);
|
||||
if (pde == NULL) {
|
||||
if ((pde == NULL) || (pde->pf == NULL)) {
|
||||
VnodeDrop();
|
||||
return -EPERM;
|
||||
}
|
||||
|
@ -410,6 +457,10 @@ static struct VnodeOps g_procfsVops = {
|
|||
.Closedir = VfsProcfsClosedir,
|
||||
.Truncate = VfsProcfsTruncate,
|
||||
.Readlink = VfsProcfsReadlink,
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
.Mkdir = VfsProcfsMkdir,
|
||||
.Rmdir = VfsProcfsRmdir,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct file_operations_vfs g_procfsFops = {
|
||||
|
|
|
@ -588,6 +588,7 @@ void ProcFreeProcessDir(struct ProcDirEntry *processDir)
|
|||
static struct ProcDirEntry *ProcCreatePorcess(UINT32 pid, struct ProcProcess *porcess, uintptr_t processCB)
|
||||
{
|
||||
int ret;
|
||||
struct ProcDataParm dataParm;
|
||||
char pidName[PROC_PID_DIR_LEN] = {0};
|
||||
struct ProcessData *data = (struct ProcessData *)malloc(sizeof(struct ProcessData));
|
||||
if (data == NULL) {
|
||||
|
@ -613,7 +614,9 @@ static struct ProcDirEntry *ProcCreatePorcess(UINT32 pid, struct ProcProcess *po
|
|||
|
||||
data->process = processCB;
|
||||
data->type = porcess->type;
|
||||
struct ProcDirEntry *container = ProcCreateData(pidName, porcess->mode, NULL, porcess->fileOps, (void *)data);
|
||||
dataParm.data = data;
|
||||
dataParm.dataType = PROC_DATA_FREE;
|
||||
struct ProcDirEntry *container = ProcCreateData(pidName, porcess->mode, NULL, porcess->fileOps, &dataParm);
|
||||
if (container == NULL) {
|
||||
free(data);
|
||||
PRINT_ERR("create /proc/%s error!\n", pidName);
|
||||
|
|
|
@ -296,7 +296,7 @@ static int ProcAddNode(struct ProcDirEntry *parent, struct ProcDirEntry *pn)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ProcDetachNode(struct ProcDirEntry *pn)
|
||||
void ProcDetachNode(struct ProcDirEntry *pn)
|
||||
{
|
||||
struct ProcDirEntry *parent = pn->parent;
|
||||
struct ProcDirEntry **iter = NULL;
|
||||
|
@ -379,7 +379,7 @@ struct ProcDirEntry *CreateProcEntry(const char *name, mode_t mode, struct ProcD
|
|||
return pde;
|
||||
}
|
||||
|
||||
static void ProcEntryClearVnode(struct ProcDirEntry *entry)
|
||||
void ProcEntryClearVnode(struct ProcDirEntry *entry)
|
||||
{
|
||||
struct Vnode *item = NULL;
|
||||
struct Vnode *nextItem = NULL;
|
||||
|
@ -404,16 +404,14 @@ static void FreeProcEntry(struct ProcDirEntry *entry)
|
|||
return;
|
||||
}
|
||||
|
||||
ProcEntryClearVnode(entry);
|
||||
|
||||
if (entry->pf != NULL) {
|
||||
free(entry->pf);
|
||||
entry->pf = NULL;
|
||||
}
|
||||
if (entry->data != NULL) {
|
||||
if ((entry->dataType == PROC_DATA_FREE) && (entry->data != NULL)) {
|
||||
free(entry->data);
|
||||
entry->data = NULL;
|
||||
}
|
||||
entry->data = NULL;
|
||||
free(entry);
|
||||
}
|
||||
|
||||
|
@ -424,7 +422,7 @@ void ProcFreeEntry(struct ProcDirEntry *pn)
|
|||
}
|
||||
}
|
||||
|
||||
static void RemoveProcEntryTravalsal(struct ProcDirEntry *pn)
|
||||
void RemoveProcEntryTravalsal(struct ProcDirEntry *pn)
|
||||
{
|
||||
if (pn == NULL) {
|
||||
return;
|
||||
|
@ -432,6 +430,8 @@ static void RemoveProcEntryTravalsal(struct ProcDirEntry *pn)
|
|||
RemoveProcEntryTravalsal(pn->next);
|
||||
RemoveProcEntryTravalsal(pn->subdir);
|
||||
|
||||
ProcEntryClearVnode(pn);
|
||||
|
||||
ProcFreeEntry(pn);
|
||||
}
|
||||
|
||||
|
@ -461,6 +461,9 @@ void RemoveProcEntry(const char *name, struct ProcDirEntry *parent)
|
|||
spin_unlock(&procfsLock);
|
||||
|
||||
RemoveProcEntryTravalsal(pn->subdir);
|
||||
|
||||
ProcEntryClearVnode(pn);
|
||||
|
||||
ProcFreeEntry(pn);
|
||||
}
|
||||
|
||||
|
@ -475,14 +478,17 @@ struct ProcDirEntry *ProcMkdir(const char *name, struct ProcDirEntry *parent)
|
|||
}
|
||||
|
||||
struct ProcDirEntry *ProcCreateData(const char *name, mode_t mode, struct ProcDirEntry *parent,
|
||||
const struct ProcFileOperations *procFileOps, void *data)
|
||||
const struct ProcFileOperations *procFileOps, struct ProcDataParm *param)
|
||||
{
|
||||
struct ProcDirEntry *pde = CreateProcEntry(name, mode, parent);
|
||||
if (pde != NULL) {
|
||||
if (procFileOps != NULL) {
|
||||
pde->procFileOps = procFileOps;
|
||||
}
|
||||
pde->data = data;
|
||||
if (param != NULL) {
|
||||
pde->data = param->data;
|
||||
pde->dataType = param->dataType;
|
||||
}
|
||||
}
|
||||
return pde;
|
||||
}
|
||||
|
@ -639,12 +645,15 @@ int WriteProcFile(struct ProcDirEntry *pde, const void *buf, size_t len)
|
|||
return -EISDIR;
|
||||
}
|
||||
|
||||
#ifndef LOSCFG_KERNEL_PLIMITS
|
||||
spin_lock(&procfsLock);
|
||||
#endif
|
||||
if ((pde->procFileOps != NULL) && (pde->procFileOps->write != NULL)) {
|
||||
result = pde->procFileOps->write(pde->pf, (const char *)buf, len, &(pde->pf->fPos));
|
||||
}
|
||||
#ifndef LOSCFG_KERNEL_PLIMITS
|
||||
spin_unlock(&procfsLock);
|
||||
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -214,7 +214,7 @@ VOID OsPidContainerDestroyAllProcess(LosProcessCB *curr)
|
|||
for (UINT32 index = 2; index < LOSCFG_BASE_CORE_PROCESS_LIMIT; index++) { /* 2: ordinary process */
|
||||
SCHEDULER_LOCK(intSave);
|
||||
LosProcessCB *processCB = OS_PCB_FROM_PID(index);
|
||||
if (OsProcessIsUnused(processCB)) {
|
||||
if (OsProcessIsUnused(processCB) || (processCB->parentProcess == NULL)) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -451,7 +451,9 @@ LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB)
|
|||
}
|
||||
processCB->files = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
OsPLimitsDeleteProcess(processCB);
|
||||
#endif
|
||||
if (processCB->resourceLimit != NULL) {
|
||||
(VOID)LOS_MemFree((VOID *)m_aucSysMem0, processCB->resourceLimit);
|
||||
processCB->resourceLimit = NULL;
|
||||
|
@ -606,7 +608,9 @@ UINT32 OsProcessInit(VOID)
|
|||
#ifdef LOSCFG_KERNEL_CONTAINER
|
||||
OsInitRootContainer();
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
OsProcLimiterSetInit();
|
||||
#endif
|
||||
SystemProcessEarlyInit(OsGetIdleProcess());
|
||||
SystemProcessEarlyInit(OsGetUserInitProcess());
|
||||
SystemProcessEarlyInit(OsGetKernelInitProcess());
|
||||
|
@ -883,6 +887,13 @@ STATIC UINT32 OsSystemProcessInit(LosProcessCB *processCB, UINT32 flags, const C
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
ret = OsPLimitsAddProcess(NULL, processCB);
|
||||
if (ret != LOS_OK) {
|
||||
ret = LOS_ENOMEM;
|
||||
goto EXIT;
|
||||
}
|
||||
#endif
|
||||
return LOS_OK;
|
||||
|
||||
EXIT:
|
||||
|
@ -2066,6 +2077,13 @@ STATIC INT32 OsCopyProcess(UINT32 flags, const CHAR *name, UINTPTR sp, UINT32 si
|
|||
if (ret != LOS_OK) {
|
||||
goto ERROR_INIT;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
ret = OsPLimitsAddProcess(run->plimits, child);
|
||||
if (ret != LOS_OK) {
|
||||
goto ERROR_INIT;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ret = OsForkInitPCB(flags, child, name, sp, size);
|
||||
|
|
|
@ -50,6 +50,9 @@
|
|||
#ifdef LOSCFG_KERNEL_CONTAINER
|
||||
#include "los_container_pri.h"
|
||||
#endif
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
#include "los_plimits.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
|
@ -139,6 +142,11 @@ typedef struct ProcessCB {
|
|||
#ifdef LOSCFG_PROC_PROCESS_DIR
|
||||
struct ProcDirEntry *procDir;
|
||||
#endif
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
ProcLimiterSet *plimits;
|
||||
LOS_DL_LIST plimitsList; /* plimit process list */
|
||||
PLimitsData limitStat;
|
||||
#endif
|
||||
} LosProcessCB;
|
||||
|
||||
extern LosProcessCB *g_processCBArray;
|
||||
|
|
|
@ -429,7 +429,7 @@ typedef struct TagTaskCB {
|
|||
PidContainer *pidContainer;
|
||||
#endif
|
||||
#ifdef LOSCFG_IPC_CONTAINER
|
||||
BOOL cloneIpc;
|
||||
BOOL cloneIpc;
|
||||
#endif
|
||||
} LosTaskCB;
|
||||
|
||||
|
@ -619,6 +619,10 @@ STATIC INLINE VOID SchedTaskUnfreeze(LosTaskCB *taskCB)
|
|||
g_taskScheduled &= ~(1U << (cpuid)); \
|
||||
} while (0);
|
||||
|
||||
#ifdef LOSCFG_KERNEL_SCHED_PLIMIT
|
||||
BOOL OsSchedLimitCheckTime(LosTaskCB *task);
|
||||
#endif
|
||||
|
||||
STATIC INLINE LosTaskCB *HPFRunqueueTopTaskGet(HPFRunqueue *rq)
|
||||
{
|
||||
LosTaskCB *newTask = NULL;
|
||||
|
@ -634,6 +638,12 @@ STATIC INLINE LosTaskCB *HPFRunqueueTopTaskGet(HPFRunqueue *rq)
|
|||
while (bitmap) {
|
||||
UINT32 priority = CLZ(bitmap);
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(newTask, &queueList->priQueList[priority], LosTaskCB, pendList) {
|
||||
#ifdef LOSCFG_KERNEL_SCHED_PLIMIT
|
||||
if (!OsSchedLimitCheckTime(newTask)) {
|
||||
bitmap &= ~(1U << (OS_PRIORITY_QUEUE_NUM - priority - 1));
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#ifdef LOSCFG_KERNEL_SMP
|
||||
if (newTask->cpuAffiMask & (1U << cpuid)) {
|
||||
#endif
|
||||
|
|
|
@ -54,6 +54,7 @@ extern "C" {
|
|||
|
||||
/* scheduler lock */
|
||||
extern SPIN_LOCK_S g_taskSpin;
|
||||
#define SCHEDULER_HELD() LOS_SpinHeld(&g_taskSpin)
|
||||
#define SCHEDULER_LOCK(state) LOS_SpinLockSave(&g_taskSpin, &(state))
|
||||
#define SCHEDULER_UNLOCK(state) LOS_SpinUnlockRestore(&g_taskSpin, state)
|
||||
|
||||
|
|
|
@ -98,6 +98,9 @@ STATIC VOID HPFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 curr
|
|||
taskCB->schedStat.timeSliceRealTime += incTime;
|
||||
#endif
|
||||
}
|
||||
#ifdef LOSCFG_KERNEL_SCHED_PLIMIT
|
||||
OsSchedLimitUpdateRuntime(taskCB, currTime, incTime);
|
||||
#endif
|
||||
taskCB->irqUsedTime = 0;
|
||||
taskCB->startTime = currTime;
|
||||
if (taskCB->timeSlice <= OS_TIME_SLICE_MIN) {
|
||||
|
|
|
@ -359,6 +359,12 @@ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame)
|
|||
return LOS_ERRNO_VM_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
if (OsMemLimitCheckAndMemAdd(PAGE_SIZE) != LOS_OK) {
|
||||
return LOS_ERRNO_VM_NO_MEMORY;
|
||||
}
|
||||
#endif
|
||||
|
||||
(VOID)LOS_MuxAcquire(&space->regionMux);
|
||||
region = LOS_RegionFind(space, vaddr);
|
||||
if (region == NULL) {
|
||||
|
@ -450,6 +456,9 @@ VMM_MAP_FAILED:
|
|||
}
|
||||
CHECK_FAILED:
|
||||
OsFaultTryFixup(frame, excVaddr, &status);
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
OsMemLimitMemFree(PAGE_SIZE);
|
||||
#endif
|
||||
DONE:
|
||||
(VOID)LOS_MuxRelease(&space->regionMux);
|
||||
return status;
|
||||
|
|
|
@ -34,7 +34,9 @@
|
|||
#include "los_vm_phys.h"
|
||||
#include "los_vm_boot.h"
|
||||
#include "los_vm_filemap.h"
|
||||
|
||||
#ifdef LOSCFG_KERNEL_MEM_PLIMIT
|
||||
#include "los_plimits.h"
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_KERNEL_VM
|
||||
|
||||
|
@ -81,7 +83,8 @@ VOID OsVmPageStartup(VOID)
|
|||
* struct LosVmPage occupied, which satisfies the equation:
|
||||
* nPage * sizeof(LosVmPage) + nPage * PAGE_SIZE = OsVmPhysPageNumGet() * PAGE_SIZE.
|
||||
*/
|
||||
nPage = OsVmPhysPageNumGet() * PAGE_SIZE / (sizeof(LosVmPage) + PAGE_SIZE);
|
||||
UINT32 pageNum = OsVmPhysPageNumGet();
|
||||
nPage = pageNum * PAGE_SIZE / (sizeof(LosVmPage) + PAGE_SIZE);
|
||||
g_vmPageArraySize = nPage * sizeof(LosVmPage);
|
||||
g_vmPageArray = (LosVmPage *)OsVmBootMemAlloc(g_vmPageArraySize);
|
||||
|
||||
|
@ -89,6 +92,9 @@ VOID OsVmPageStartup(VOID)
|
|||
|
||||
OsVmPhysSegAdd();
|
||||
OsVmPhysInit();
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
OsMemLimitSetLimit(pageNum * PAGE_SIZE);
|
||||
#endif
|
||||
|
||||
for (segID = 0; segID < g_vmPhysSegNum; segID++) {
|
||||
seg = &g_vmPhysSeg[segID];
|
||||
|
|
|
@ -456,6 +456,9 @@ VOID LOS_PhysPagesFreeContiguous(VOID *ptr, size_t nPages)
|
|||
OsVmPhysPagesFreeContiguous(page, nPages);
|
||||
|
||||
LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
OsMemLimitMemFree(nPages * PAGE_SIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
PADDR_T OsKVaddrToPaddr(VADDR_T kvaddr)
|
||||
|
@ -503,6 +506,9 @@ VOID LOS_PhysPageFree(LosVmPage *page)
|
|||
|
||||
LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
|
||||
}
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
OsMemLimitMemFree(PAGE_SIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
LosVmPage *LOS_PhysPageAlloc(VOID)
|
||||
|
|
|
@ -193,40 +193,58 @@ STATIC VOID ShmPagesRefDec(struct shmIDSource *seg)
|
|||
}
|
||||
}
|
||||
|
||||
STATIC INT32 ShmAllocSeg(key_t key, size_t size, INT32 shmflg)
|
||||
STATIC INT32 ShmAllocSegCheck(key_t key, size_t *size, INT32 *segNum)
|
||||
{
|
||||
INT32 i;
|
||||
INT32 segNum = -1;
|
||||
struct shmIDSource *seg = NULL;
|
||||
size_t count;
|
||||
|
||||
if ((size == 0) || (size < IPC_SHM_INFO.shmmin) ||
|
||||
(size > IPC_SHM_INFO.shmmax)) {
|
||||
if ((*size == 0) || (*size < IPC_SHM_INFO.shmmin) ||
|
||||
(*size > IPC_SHM_INFO.shmmax)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
size = LOS_Align(size, PAGE_SIZE);
|
||||
if ((IPC_SHM_USED_PAGE_COUNT + (size >> PAGE_SHIFT)) > IPC_SHM_INFO.shmall) {
|
||||
*size = LOS_Align(*size, PAGE_SIZE);
|
||||
if ((IPC_SHM_USED_PAGE_COUNT + (*size >> PAGE_SHIFT)) > IPC_SHM_INFO.shmall) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (i = 0; i < IPC_SHM_INFO.shmmni; i++) {
|
||||
if (IPC_SHM_SEGS[i].status & SHM_SEG_FREE) {
|
||||
IPC_SHM_SEGS[i].status &= ~SHM_SEG_FREE;
|
||||
segNum = i;
|
||||
*segNum = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (segNum < 0) {
|
||||
if (*segNum < 0) {
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_KERNEL_IPC_PLIMIT
|
||||
if (OsIPCLimitShmAlloc(*size) != LOS_OK) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC INT32 ShmAllocSeg(key_t key, size_t size, INT32 shmflg)
|
||||
{
|
||||
INT32 segNum = -1;
|
||||
struct shmIDSource *seg = NULL;
|
||||
size_t count;
|
||||
|
||||
INT32 ret = ShmAllocSegCheck(key, &size, &segNum);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
seg = &IPC_SHM_SEGS[segNum];
|
||||
count = LOS_PhysPagesAlloc(size >> PAGE_SHIFT, &seg->node);
|
||||
if (count != (size >> PAGE_SHIFT)) {
|
||||
(VOID)LOS_PhysPagesFree(&seg->node);
|
||||
seg->status = SHM_SEG_FREE;
|
||||
#ifdef LOSCFG_KERNEL_IPC_PLIMIT
|
||||
OsIPCLimitShmFree(size);
|
||||
#endif
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
@ -264,6 +282,9 @@ STATIC INLINE VOID ShmFreeSeg(struct shmIDSource *seg, UINT32 *shmUsedPageCount)
|
|||
VM_ERR("free physical pages failed, count = %d, size = %d", count, seg->ds.shm_segsz >> PAGE_SHIFT);
|
||||
return;
|
||||
}
|
||||
#ifdef LOSCFG_KERNEL_IPC_PLIMIT
|
||||
OsIPCLimitShmFree(seg->ds.shm_segsz);
|
||||
#endif
|
||||
if (shmUsedPageCount != NULL) {
|
||||
(*shmUsedPageCount) -= seg->ds.shm_segsz >> PAGE_SHIFT;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ group("extended") {
|
|||
"lms",
|
||||
"perf",
|
||||
"pipes",
|
||||
"plimit",
|
||||
"power",
|
||||
"trace",
|
||||
"vdso",
|
||||
|
@ -62,5 +63,6 @@ config("public") {
|
|||
"perf:public",
|
||||
"lms:public",
|
||||
"power:public",
|
||||
"plimit:public",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -76,6 +76,31 @@ config KERNEL_PIPE
|
|||
help
|
||||
Answer Y to enable LiteOS support pipes.
|
||||
|
||||
config KERNEL_PLIMITS
|
||||
bool "Enable plimits Feature"
|
||||
default n
|
||||
depends on KERNEL_EXTKERNEL
|
||||
|
||||
config KERNEL_MEM_PLIMIT
|
||||
bool "Enable mem limits Feature"
|
||||
default n
|
||||
depends on KERNEL_PLIMITS
|
||||
|
||||
config KERNEL_IPC_PLIMIT
|
||||
bool "Enable ipc limits Feature"
|
||||
default n
|
||||
depends on KERNEL_PLIMITS
|
||||
|
||||
config KERNEL_DEV_PLIMIT
|
||||
bool "Enable dev limits Feature"
|
||||
default n
|
||||
depends on KERNEL_PLIMITS
|
||||
|
||||
config KERNEL_SCHED_PLIMIT
|
||||
bool "Enable sched limits Feature"
|
||||
default n
|
||||
depends on KERNEL_PLIMITS
|
||||
|
||||
config BASE_CORE_HILOG
|
||||
bool "Enable Hilog"
|
||||
default y
|
||||
|
@ -104,4 +129,4 @@ source "kernel/extended/perf/Kconfig"
|
|||
source "kernel/extended/lms/Kconfig"
|
||||
|
||||
######################### config options of hilog #########################
|
||||
source "kernel/extended/hilog/Kconfig"
|
||||
source "kernel/extended/hilog/Kconfig"
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
# Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
# of conditions and the following disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
# to endorse or promote products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import("//kernel/liteos_a/liteos.gni")
|
||||
|
||||
module_switch = true
|
||||
module_name = get_path_info(rebase_path("."), "name")
|
||||
kernel_module(module_name) {
|
||||
sources = [
|
||||
"los_devicelimit.c",
|
||||
"los_ipclimit.c",
|
||||
"los_memlimit.c",
|
||||
"los_plimits.c",
|
||||
"los_processlimit.c",
|
||||
"los_schedlimit.c",
|
||||
]
|
||||
}
|
||||
|
||||
config("public") {
|
||||
include_dirs = [ "." ]
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
# Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
# of conditions and the following disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
# to endorse or promote products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
include $(LITEOSTOPDIR)/config.mk
|
||||
|
||||
MODULE_NAME := $(notdir $(shell pwd))
|
||||
|
||||
LOCAL_SRCS := $(wildcard *.c)
|
||||
|
||||
include $(MODULE)
|
|
@ -0,0 +1,613 @@
|
|||
/*
|
||||
* Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_seq_buf.h"
|
||||
#include "los_bitmap.h"
|
||||
#include "los_process_pri.h"
|
||||
#include "los_devicelimit.h"
|
||||
|
||||
#ifdef LOSCFG_KERNEL_DEV_PLIMIT
|
||||
#define TYPE_CHAR_LEN (1)
|
||||
#define DEVICE_NAME_PREFIX_SPACE (1)
|
||||
#define DEVICE_ACCESS_MAXLEN (3)
|
||||
#define BUF_SEPARATOR (5)
|
||||
|
||||
STATIC ProcDevLimit *g_procDevLimit = NULL;
|
||||
|
||||
VOID OsDevLimitInit(UINTPTR limit)
|
||||
{
|
||||
ProcDevLimit *deviceLimit = (ProcDevLimit *)limit;
|
||||
deviceLimit->behavior = DEVLIMIT_DEFAULT_ALLOW;
|
||||
LOS_ListInit(&(deviceLimit->accessList));
|
||||
g_procDevLimit = deviceLimit;
|
||||
}
|
||||
|
||||
VOID *OsDevLimitAlloc(VOID)
|
||||
{
|
||||
ProcDevLimit *plimit = (ProcDevLimit *)LOS_KernelMalloc(sizeof(ProcDevLimit));
|
||||
if (plimit == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
(VOID)memset_s(plimit, sizeof(ProcDevLimit), 0, sizeof(ProcDevLimit));
|
||||
LOS_ListInit(&(plimit->accessList));
|
||||
plimit->behavior = DEVLIMIT_DEFAULT_NONE;
|
||||
LOS_AtomicSet(&plimit->rc, 1);
|
||||
return (VOID *)plimit;
|
||||
}
|
||||
|
||||
STATIC VOID DevAccessListDelete(ProcDevLimit *devLimit)
|
||||
{
|
||||
DevAccessItem *delItem = NULL;
|
||||
DevAccessItem *tmpItem = NULL;
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(delItem, tmpItem, &devLimit->accessList, DevAccessItem, list) {
|
||||
LOS_ListDelete(&delItem->list);
|
||||
LOS_KernelFree((VOID *)delItem);
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsDevLimitFree(UINTPTR limit)
|
||||
{
|
||||
ProcDevLimit *devLimit = (ProcDevLimit *)limit;
|
||||
if (devLimit == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOS_AtomicDec(&devLimit->rc);
|
||||
if (LOS_AtomicRead(&devLimit->rc) <= 0) {
|
||||
DevAccessListDelete(devLimit);
|
||||
LOS_KernelFree(devLimit);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC UINT32 DevLimitCopyAccess(ProcDevLimit *devLimitDest, ProcDevLimit *devLimitSrc)
|
||||
{
|
||||
DevAccessItem *tmpItem = NULL;
|
||||
INT32 itemSize = sizeof(DevAccessItem);
|
||||
devLimitDest->behavior = devLimitSrc->behavior;
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(tmpItem, &devLimitSrc->accessList, DevAccessItem, list) {
|
||||
DevAccessItem *newItem = (DevAccessItem *)LOS_KernelMalloc(itemSize);
|
||||
if (newItem == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
(VOID)memcpy_s(newItem, sizeof(DevAccessItem), tmpItem, sizeof(DevAccessItem));
|
||||
LOS_ListTailInsert(&devLimitDest->accessList, &newItem->list);
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
VOID OsDevLimitCopy(UINTPTR dest, UINTPTR src)
|
||||
{
|
||||
ProcDevLimit *devLimitDest = (ProcDevLimit *)dest;
|
||||
ProcDevLimit *devLimitSrc = (ProcDevLimit *)src;
|
||||
(VOID)DevLimitCopyAccess(devLimitDest, devLimitSrc);
|
||||
devLimitDest->parent = (ProcDevLimit *)src;
|
||||
}
|
||||
|
||||
VOID OsDevLimitMigrate(UINTPTR currLimit, UINTPTR parentLimit, UINTPTR process)
|
||||
{
|
||||
(VOID)currLimit;
|
||||
ProcDevLimit *parentDevLimit = (ProcDevLimit *)parentLimit;
|
||||
LosProcessCB *pcb = (LosProcessCB *)process;
|
||||
if (pcb == NULL) {
|
||||
LOS_AtomicInc(&parentDevLimit->rc);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC INLINE INT32 IsSpace(INT32 c)
|
||||
{
|
||||
return (c == ' ' || (unsigned)c - '\t' < BUF_SEPARATOR);
|
||||
}
|
||||
|
||||
STATIC UINT32 ParseItemAccess(const CHAR *buf, DevAccessItem *item)
|
||||
{
|
||||
switch (*buf) {
|
||||
case 'a':
|
||||
item->type = DEVLIMIT_DEV_ALL;
|
||||
return LOS_OK;
|
||||
case 'b':
|
||||
item->type = DEVLIMIT_DEV_BLOCK;
|
||||
break;
|
||||
case 'c':
|
||||
item->type = DEVLIMIT_DEV_CHAR;
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
buf += DEVICE_NAME_PREFIX_SPACE;
|
||||
if (!IsSpace(*buf)) {
|
||||
return EINVAL;
|
||||
}
|
||||
buf += DEVICE_NAME_PREFIX_SPACE;
|
||||
|
||||
for (INT32 count = 0; count < sizeof(item->name) - 1; count++) {
|
||||
if (IsSpace(*buf)) {
|
||||
break;
|
||||
}
|
||||
item->name[count] = *buf;
|
||||
buf += TYPE_CHAR_LEN;
|
||||
}
|
||||
if (!IsSpace(*buf)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
buf += DEVICE_NAME_PREFIX_SPACE;
|
||||
for (INT32 i = 0; i < DEVICE_ACCESS_MAXLEN; i++) {
|
||||
switch (*buf) {
|
||||
case 'r':
|
||||
item->access |= DEVLIMIT_ACC_READ;
|
||||
break;
|
||||
case 'w':
|
||||
item->access |= DEVLIMIT_ACC_WRITE;
|
||||
break;
|
||||
case 'm':
|
||||
item->access |= DEVLIMIT_ACC_MKNOD;
|
||||
break;
|
||||
case '\n':
|
||||
case '\0':
|
||||
i = DEVICE_ACCESS_MAXLEN;
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
buf += TYPE_CHAR_LEN;
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC BOOL DevLimitMayAllowAll(ProcDevLimit *parent)
|
||||
{
|
||||
if (parent == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
return (parent->behavior == DEVLIMIT_DEFAULT_ALLOW);
|
||||
}
|
||||
|
||||
STATIC BOOL DevLimitHasChildren(ProcLimitSet *procLimitSet, ProcDevLimit *devLimit)
|
||||
{
|
||||
ProcLimitSet *parent = procLimitSet;
|
||||
ProcLimitSet *childProcLimitSet = NULL;
|
||||
if (devLimit == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(childProcLimitSet, &(procLimitSet->childList), ProcLimitSet, childList) {
|
||||
if (childProcLimitSet == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (childProcLimitSet->parent != parent) {
|
||||
continue;
|
||||
}
|
||||
if (!((childProcLimitSet->mask) & BIT(PROCESS_LIMITER_ID_DEV))) {
|
||||
continue;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
STATIC UINT32 DealItemAllAccess(ProcLimitSet *procLimitSet, ProcDevLimit *devLimit,
|
||||
ProcDevLimit *devParentLimit, INT32 filetype)
|
||||
{
|
||||
switch (filetype) {
|
||||
case DEVLIMIT_ALLOW: {
|
||||
if (DevLimitHasChildren(procLimitSet, devLimit)) {
|
||||
return EINVAL;
|
||||
}
|
||||
if (!DevLimitMayAllowAll(devParentLimit)) {
|
||||
return EPERM;
|
||||
}
|
||||
DevAccessListDelete(devLimit);
|
||||
devLimit->behavior = DEVLIMIT_DEFAULT_ALLOW;
|
||||
if (devParentLimit == NULL) {
|
||||
break;
|
||||
}
|
||||
DevLimitCopyAccess(devLimit, devParentLimit);
|
||||
break;
|
||||
}
|
||||
case DEVLIMIT_DENY: {
|
||||
if (DevLimitHasChildren(procLimitSet, devLimit)) {
|
||||
return EINVAL;
|
||||
}
|
||||
DevAccessListDelete(devLimit);
|
||||
devLimit->behavior = DEVLIMIT_DEFAULT_DENY;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC BOOL DevLimitMatchItemPartial(LOS_DL_LIST *list, DevAccessItem *item)
|
||||
{
|
||||
if ((list == NULL) || (item == NULL)) {
|
||||
return FALSE;
|
||||
}
|
||||
if (LOS_ListEmpty(list)) {
|
||||
return FALSE;
|
||||
}
|
||||
DevAccessItem *walk = NULL;
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(walk, list, DevAccessItem, list) {
|
||||
if (item->type != walk->type) {
|
||||
continue;
|
||||
}
|
||||
if ((strcmp(walk->name, "*") != 0) && (strcmp(item->name, "*") != 0)
|
||||
&& (strcmp(walk->name, item->name) != 0)) {
|
||||
continue;
|
||||
}
|
||||
if (!(item->access & ~(walk->access))) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
STATIC BOOL DevLimitParentAllowsRmItem(ProcDevLimit *devParentLimit, DevAccessItem *item)
|
||||
{
|
||||
if (devParentLimit == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
/* Make sure you're not removing part or a whole item existing in the parent plimits */
|
||||
return !DevLimitMatchItemPartial(&devParentLimit->accessList, item);
|
||||
}
|
||||
|
||||
STATIC BOOL DevLimitMatchItem(LOS_DL_LIST *list, DevAccessItem *item)
|
||||
{
|
||||
if ((list == NULL) || (item == NULL)) {
|
||||
return FALSE;
|
||||
}
|
||||
if (LOS_ListEmpty(list)) {
|
||||
return FALSE;
|
||||
}
|
||||
DevAccessItem *walk = NULL;
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(walk, list, DevAccessItem, list) {
|
||||
if (item->type != walk->type) {
|
||||
continue;
|
||||
}
|
||||
if ((strcmp(walk->name, "*") != 0) && (strcmp(walk->name, item->name) != 0)) {
|
||||
continue;
|
||||
}
|
||||
if (!(item->access & ~(walk->access))) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used to make sure a child plimits won't have more privileges than its parent
|
||||
*/
|
||||
STATIC BOOL DevLimitVerifyNewItem(ProcDevLimit *parent, DevAccessItem *item, INT32 currBehavior)
|
||||
{
|
||||
if (parent == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (parent->behavior == DEVLIMIT_DEFAULT_ALLOW) {
|
||||
if (currBehavior == DEVLIMIT_DEFAULT_ALLOW) {
|
||||
return TRUE;
|
||||
}
|
||||
return !DevLimitMatchItemPartial(&parent->accessList, item);
|
||||
}
|
||||
return DevLimitMatchItem(&parent->accessList, item);
|
||||
}
|
||||
|
||||
STATIC BOOL DevLimitParentAllowsAddItem(ProcDevLimit *devParentLimit, DevAccessItem *item, INT32 currBehavior)
|
||||
{
|
||||
return DevLimitVerifyNewItem(devParentLimit, item, currBehavior);
|
||||
}
|
||||
|
||||
STATIC VOID DevLimitAccessListRm(ProcDevLimit *devLimit, DevAccessItem *item)
|
||||
{
|
||||
if ((item == NULL) || (devLimit == NULL)) {
|
||||
return;
|
||||
}
|
||||
DevAccessItem *walk, *tmp = NULL;
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(walk, tmp, &devLimit->accessList, DevAccessItem, list) {
|
||||
if (walk->type != item->type) {
|
||||
continue;
|
||||
}
|
||||
if (strcmp(walk->name, item->name) != 0) {
|
||||
continue;
|
||||
}
|
||||
walk->access &= ~item->access;
|
||||
if (!walk->access) {
|
||||
LOS_ListDelete(&walk->list);
|
||||
LOS_KernelFree((VOID *)walk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC UINT32 DevLimitAccessListAdd(ProcDevLimit *devLimit, DevAccessItem *item)
|
||||
{
|
||||
if ((item == NULL) || (devLimit == NULL)) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
DevAccessItem *walk = NULL;
|
||||
DevAccessItem *newItem = (DevAccessItem *)LOS_KernelMalloc(sizeof(DevAccessItem));
|
||||
if (newItem == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
(VOID)memcpy_s(newItem, sizeof(DevAccessItem), item, sizeof(DevAccessItem));
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(walk, &devLimit->accessList, DevAccessItem, list) {
|
||||
if (walk->type != item->type) {
|
||||
continue;
|
||||
}
|
||||
if (strcmp(walk->name, item->name) != 0) {
|
||||
continue;
|
||||
}
|
||||
walk->access |= item->access;
|
||||
LOS_KernelFree((VOID *)newItem);
|
||||
newItem = NULL;
|
||||
}
|
||||
|
||||
if (newItem != NULL) {
|
||||
LOS_ListTailInsert(&devLimit->accessList, &newItem->list);
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Revalidate permissions
|
||||
*/
|
||||
STATIC VOID DevLimitRevalidateActiveItems(ProcDevLimit *devLimit, ProcDevLimit *devParentLimit)
|
||||
{
|
||||
if ((devLimit == NULL) || (devParentLimit == NULL)) {
|
||||
return;
|
||||
}
|
||||
DevAccessItem *walK = NULL;
|
||||
DevAccessItem *tmp = NULL;
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(walK, tmp, &devLimit->accessList, DevAccessItem, list) {
|
||||
if (!DevLimitParentAllowsAddItem(devParentLimit, walK, devLimit->behavior)) {
|
||||
DevLimitAccessListRm(devLimit, walK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* propagates a new item to the children
|
||||
*/
|
||||
STATIC UINT32 DevLimitPropagateItem(ProcLimitSet *procLimitSet, ProcDevLimit *devLimit, DevAccessItem *item)
|
||||
{
|
||||
UINT32 ret = LOS_OK;
|
||||
ProcLimitSet *parent = procLimitSet;
|
||||
ProcLimitSet *childProcLimitSet = NULL;
|
||||
|
||||
if ((procLimitSet == NULL) || (item == NULL)) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
if (devLimit == NULL) {
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(childProcLimitSet, &procLimitSet->childList, ProcLimitSet, childList) {
|
||||
if (childProcLimitSet == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (childProcLimitSet->parent != parent) {
|
||||
continue;
|
||||
}
|
||||
if (!((childProcLimitSet->mask) & BIT(PROCESS_LIMITER_ID_DEV))) {
|
||||
continue;
|
||||
}
|
||||
ProcDevLimit *devLimitChild = (ProcDevLimit *)childProcLimitSet->limitsList[PROCESS_LIMITER_ID_DEV];
|
||||
if (devLimit->behavior == DEVLIMIT_DEFAULT_ALLOW &&
|
||||
devLimitChild->behavior == DEVLIMIT_DEFAULT_ALLOW) {
|
||||
ret = DevLimitAccessListAdd(devLimitChild, item);
|
||||
} else {
|
||||
DevLimitAccessListRm(devLimitChild, item);
|
||||
}
|
||||
DevLimitRevalidateActiveItems(devLimitChild, (ProcDevLimit *)parent->limitsList[PROCESS_LIMITER_ID_DEV]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC UINT32 DevLimitUpdateAccess(ProcLimitSet *procLimitSet, const CHAR *buf, INT32 filetype)
|
||||
{
|
||||
UINT32 ret;
|
||||
UINT32 intSave;
|
||||
DevAccessItem item = {0};
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
ProcDevLimit *devLimit = (ProcDevLimit *)(procLimitSet->limitsList[PROCESS_LIMITER_ID_DEV]);
|
||||
ProcDevLimit *devParentLimit = devLimit->parent;
|
||||
|
||||
ret = ParseItemAccess(buf, &item);
|
||||
if (ret != LOS_OK) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
if (item.type == DEVLIMIT_DEV_ALL) {
|
||||
ret = DealItemAllAccess(procLimitSet, devLimit, devParentLimit, filetype);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
switch (filetype) {
|
||||
case DEVLIMIT_ALLOW: {
|
||||
if (devLimit->behavior == DEVLIMIT_DEFAULT_ALLOW) {
|
||||
if (!DevLimitParentAllowsRmItem(devParentLimit, &item)) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return EPERM;
|
||||
}
|
||||
DevLimitAccessListRm(devLimit, &item);
|
||||
break;
|
||||
}
|
||||
if (!DevLimitParentAllowsAddItem(devParentLimit, &item, devLimit->behavior)) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return EPERM;
|
||||
}
|
||||
ret = DevLimitAccessListAdd(devLimit, &item);
|
||||
break;
|
||||
}
|
||||
case DEVLIMIT_DENY: {
|
||||
if (devLimit->behavior == DEVLIMIT_DEFAULT_DENY) {
|
||||
DevLimitAccessListRm(devLimit, &item);
|
||||
} else {
|
||||
ret = DevLimitAccessListAdd(devLimit, &item);
|
||||
}
|
||||
// update child access list
|
||||
ret = DevLimitPropagateItem(procLimitSet, devLimit, &item);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ret = EINVAL;
|
||||
break;
|
||||
}
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
UINT32 OsDevLimitWriteAllow(ProcLimitSet *plimit, const CHAR *buf, UINT32 size)
|
||||
{
|
||||
(VOID)size;
|
||||
return DevLimitUpdateAccess(plimit, buf, DEVLIMIT_ALLOW);
|
||||
}
|
||||
|
||||
UINT32 OsDevLimitWriteDeny(ProcLimitSet *plimit, const CHAR *buf, UINT32 size)
|
||||
{
|
||||
(VOID)size;
|
||||
return DevLimitUpdateAccess(plimit, buf, DEVLIMIT_DENY);
|
||||
}
|
||||
|
||||
STATIC VOID DevLimitItemSetAccess(CHAR *acc, INT16 access)
|
||||
{
|
||||
INT32 index = 0;
|
||||
(VOID)memset_s(acc, ACCLEN, 0, ACCLEN);
|
||||
if (access & DEVLIMIT_ACC_READ) {
|
||||
acc[index++] = 'r';
|
||||
}
|
||||
if (access & DEVLIMIT_ACC_WRITE) {
|
||||
acc[index++] = 'w';
|
||||
}
|
||||
if (access & DEVLIMIT_ACC_MKNOD) {
|
||||
acc[index++] = 'm';
|
||||
}
|
||||
}
|
||||
|
||||
STATIC CHAR DevLimitItemTypeToChar(INT16 type)
|
||||
{
|
||||
if (type == DEVLIMIT_DEV_ALL) {
|
||||
return 'a';
|
||||
} else if (type == DEVLIMIT_DEV_CHAR) {
|
||||
return 'c';
|
||||
} else if (type == DEVLIMIT_DEV_BLOCK) {
|
||||
return 'b';
|
||||
}
|
||||
return 'X';
|
||||
}
|
||||
|
||||
UINT32 OsDevLimitShow(ProcDevLimit *devLimit, struct SeqBuf *seqBuf)
|
||||
{
|
||||
DevAccessItem *item = NULL;
|
||||
CHAR acc[ACCLEN];
|
||||
UINT32 intSave;
|
||||
|
||||
if ((devLimit == NULL) || (seqBuf == NULL)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
if (devLimit->behavior == DEVLIMIT_DEFAULT_ALLOW) {
|
||||
DevLimitItemSetAccess(acc, DEVLIMIT_ACC_MASK);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
LosBufPrintf(seqBuf, "%c %s %s\n", DevLimitItemTypeToChar(DEVLIMIT_DEV_ALL), "*", acc);
|
||||
return LOS_OK;
|
||||
}
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(item, &devLimit->accessList, DevAccessItem, list) {
|
||||
DevLimitItemSetAccess(acc, item->access);
|
||||
LosBufPrintf(seqBuf, "%c %s %s\n", DevLimitItemTypeToChar(item->type), item->name, acc);
|
||||
}
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC INLINE INT16 ConversionDevType(INT32 vnodeType)
|
||||
{
|
||||
INT16 type = 0;
|
||||
if (vnodeType == VNODE_TYPE_BLK) {
|
||||
type = DEVLIMIT_DEV_BLOCK;
|
||||
} else if (vnodeType == VNODE_TYPE_CHR) {
|
||||
type = DEVLIMIT_DEV_CHAR;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
STATIC INLINE INT16 ConversionDevAccess(INT32 flags)
|
||||
{
|
||||
INT16 access = 0;
|
||||
if ((flags & O_ACCMODE) == O_RDONLY) {
|
||||
access |= DEVLIMIT_ACC_READ;
|
||||
}
|
||||
if (flags & O_WRONLY) {
|
||||
access |= DEVLIMIT_ACC_WRITE;
|
||||
}
|
||||
if (flags & O_RDWR) {
|
||||
access |= DEVLIMIT_ACC_WRITE | DEVLIMIT_ACC_READ;
|
||||
}
|
||||
if (flags & O_CREAT) {
|
||||
access |= DEVLIMIT_ACC_MKNOD;
|
||||
}
|
||||
return access;
|
||||
}
|
||||
|
||||
UINT32 OsDevLimitCheckPermission(INT32 vnodeType, const CHAR *pathName, INT32 flags)
|
||||
{
|
||||
BOOL matched = FALSE;
|
||||
DevAccessItem item = {0};
|
||||
LosProcessCB *run = OsCurrProcessGet();
|
||||
if ((run == NULL) || (run->plimits == NULL)) {
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
if (pathName == NULL) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
ProcDevLimit *devLimit = (ProcDevLimit *)run->plimits->limitsList[PROCESS_LIMITER_ID_DEV];
|
||||
|
||||
item.type = ConversionDevType(vnodeType);
|
||||
item.access = ConversionDevAccess(flags);
|
||||
LOS_ListInit(&(item.list));
|
||||
(VOID)strncpy_s(item.name, PATH_MAX, pathName, PATH_MAX);
|
||||
|
||||
if (devLimit->behavior == DEVLIMIT_DEFAULT_ALLOW) {
|
||||
matched = !DevLimitMatchItemPartial(&devLimit->accessList, &item);
|
||||
} else {
|
||||
matched = DevLimitMatchItem(&devLimit->accessList, &item);
|
||||
}
|
||||
if (!matched) {
|
||||
return EPERM;
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_DEVICELIMIT_H
|
||||
#define _LOS_DEVICELIMIT_H
|
||||
|
||||
#include "los_typedef.h"
|
||||
#include "los_atomic.h"
|
||||
#include "los_list.h"
|
||||
#include "vfs_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define DEVLIMIT_ACC_MKNOD 1
|
||||
#define DEVLIMIT_ACC_READ 2
|
||||
#define DEVLIMIT_ACC_WRITE 4
|
||||
#define DEVLIMIT_ACC_MASK (DEVLIMIT_ACC_MKNOD | DEVLIMIT_ACC_READ | DEVLIMIT_ACC_WRITE)
|
||||
|
||||
#define DEVLIMIT_DEV_BLOCK 1
|
||||
#define DEVLIMIT_DEV_CHAR 2
|
||||
#define DEVLIMIT_DEV_ALL 4 /* all devices */
|
||||
|
||||
#define DEVLIMIT_ALLOW 1
|
||||
#define DEVLIMIT_DENY 2
|
||||
|
||||
#define ACCLEN 4
|
||||
|
||||
struct SeqBuf;
|
||||
typedef struct TagPLimiterSet ProcLimitSet;
|
||||
|
||||
enum DevLimitBehavior {
|
||||
DEVLIMIT_DEFAULT_NONE,
|
||||
DEVLIMIT_DEFAULT_ALLOW,
|
||||
DEVLIMIT_DEFAULT_DENY,
|
||||
};
|
||||
|
||||
typedef struct DevAccessItem {
|
||||
INT16 type;
|
||||
INT16 access;
|
||||
LOS_DL_LIST list;
|
||||
CHAR name[PATH_MAX];
|
||||
} DevAccessItem;
|
||||
|
||||
typedef struct ProcDevLimit {
|
||||
struct ProcDevLimit *parent;
|
||||
Atomic rc;
|
||||
UINT8 allowFile;
|
||||
UINT8 denyFile;
|
||||
LOS_DL_LIST accessList; // device belong to devicelimite
|
||||
enum DevLimitBehavior behavior;
|
||||
} ProcDevLimit;
|
||||
|
||||
VOID OsDevLimitInit(UINTPTR limit);
|
||||
VOID *OsDevLimitAlloc(VOID);
|
||||
VOID OsDevLimitFree(UINTPTR limit);
|
||||
VOID OsDevLimitCopy(UINTPTR dest, UINTPTR src);
|
||||
VOID OsDevLimitMigrate(UINTPTR currLimit, UINTPTR parentLimit, UINTPTR process);
|
||||
UINT32 OsDevLimitWriteAllow(ProcLimitSet *plimit, const CHAR *buf, UINT32 size);
|
||||
UINT32 OsDevLimitWriteDeny(ProcLimitSet *plimit, const CHAR *buf, UINT32 size);
|
||||
UINT32 OsDevLimitShow(ProcDevLimit *devLimit, struct SeqBuf *seqBuf);
|
||||
UINT32 OsDevLimitCheckPermission(INT32 vnodeType, const CHAR *pathName, INT32 flags);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
#endif /* _LOS_DEVICELIMIT_H */
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_ipclimit.h"
|
||||
#include "los_process_pri.h"
|
||||
|
||||
#ifdef LOSCFG_KERNEL_IPC_PLIMIT
|
||||
STATIC ProcIPCLimit *g_rootIPCLimit = NULL;
|
||||
#define PLIMIT_IPC_SHM_LIMIT_MAX 104857600
|
||||
|
||||
VOID OsIPCLimitInit(UINTPTR limite)
|
||||
{
|
||||
ProcIPCLimit *plimite = (ProcIPCLimit *)limite;
|
||||
plimite->mqCountLimit = LOSCFG_BASE_IPC_QUEUE_LIMIT;
|
||||
plimite->shmSizeLimit = PLIMIT_IPC_SHM_LIMIT_MAX;
|
||||
g_rootIPCLimit = plimite;
|
||||
}
|
||||
|
||||
VOID *OsIPCLimitAlloc(VOID)
|
||||
{
|
||||
ProcIPCLimit *plimite = (ProcIPCLimit *)LOS_KernelMalloc(sizeof(ProcIPCLimit));
|
||||
if (plimite == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
(VOID)memset_s(plimite, sizeof(ProcIPCLimit), 0, sizeof(ProcIPCLimit));
|
||||
LOS_AtomicSet(&plimite->rc, 1);
|
||||
return (VOID *)plimite;
|
||||
}
|
||||
|
||||
VOID OsIPCLimitFree(UINTPTR limite)
|
||||
{
|
||||
ProcIPCLimit *plimite = (ProcIPCLimit *)limite;
|
||||
if (plimite == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOS_AtomicDec(&plimite->rc);
|
||||
if (LOS_AtomicRead(&plimite->rc) <= 0) {
|
||||
LOS_KernelFree((VOID *)plimite);
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsIPCLimitCopy(UINTPTR dest, UINTPTR src)
|
||||
{
|
||||
ProcIPCLimit *plimiteDest = (ProcIPCLimit *)dest;
|
||||
ProcIPCLimit *plimiteSrc = (ProcIPCLimit *)src;
|
||||
plimiteDest->mqCountLimit = plimiteSrc->mqCountLimit;
|
||||
plimiteDest->shmSizeLimit = plimiteSrc->shmSizeLimit;
|
||||
return;
|
||||
}
|
||||
|
||||
BOOL OsIPCLimiteMigrateCheck(UINTPTR curr, UINTPTR parent)
|
||||
{
|
||||
ProcIPCLimit *currIpcLimit = (ProcIPCLimit *)curr;
|
||||
ProcIPCLimit *parentIpcLimit = (ProcIPCLimit *)parent;
|
||||
if ((currIpcLimit->mqCount + parentIpcLimit->mqCount) >= parentIpcLimit->mqCountLimit) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((currIpcLimit->shmSize + parentIpcLimit->shmSize) >= parentIpcLimit->shmSizeLimit) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID OsIPCLimitMigrate(UINTPTR currLimit, UINTPTR parentLimit, UINTPTR process)
|
||||
{
|
||||
ProcIPCLimit *currIpcLimit = (ProcIPCLimit *)currLimit;
|
||||
ProcIPCLimit *parentIpcLimit = (ProcIPCLimit *)parentLimit;
|
||||
LosProcessCB *pcb = (LosProcessCB *)process;
|
||||
|
||||
if (pcb == NULL) {
|
||||
parentIpcLimit->mqCount += currIpcLimit->mqCount;
|
||||
parentIpcLimit->mqFailedCount += currIpcLimit->mqFailedCount;
|
||||
parentIpcLimit->shmSize += currIpcLimit->shmSize;
|
||||
parentIpcLimit->shmFailedCount += currIpcLimit->shmFailedCount;
|
||||
LOS_AtomicInc(&parentIpcLimit->rc);
|
||||
return;
|
||||
}
|
||||
|
||||
parentIpcLimit->mqCount -= pcb->limitStat.mqCount;
|
||||
parentIpcLimit->shmSize -= pcb->limitStat.shmSize;
|
||||
currIpcLimit->mqCount += pcb->limitStat.mqCount;
|
||||
currIpcLimit->shmSize += pcb->limitStat.shmSize;
|
||||
}
|
||||
|
||||
BOOL OsIPCLimitAddProcessCheck(UINTPTR limit, UINTPTR process)
|
||||
{
|
||||
ProcIPCLimit *ipcLimit = (ProcIPCLimit *)limit;
|
||||
LosProcessCB *pcb = (LosProcessCB *)process;
|
||||
if ((ipcLimit->mqCount + pcb->limitStat.mqCount) >= ipcLimit->mqCountLimit) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((ipcLimit->shmSize + pcb->limitStat.shmSize) >= ipcLimit->shmSizeLimit) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID OsIPCLimitAddProcess(UINTPTR limit, UINTPTR process)
|
||||
{
|
||||
LosProcessCB *pcb = (LosProcessCB *)process;
|
||||
ProcIPCLimit *plimits = (ProcIPCLimit *)limit;
|
||||
plimits->mqCount += pcb->limitStat.mqCount;
|
||||
plimits->shmSize += pcb->limitStat.shmSize;
|
||||
return;
|
||||
}
|
||||
|
||||
VOID OsIPCLimitDelProcess(UINTPTR limit, UINTPTR process)
|
||||
{
|
||||
LosProcessCB *pcb = (LosProcessCB *)process;
|
||||
ProcIPCLimit *plimits = (ProcIPCLimit *)limit;
|
||||
|
||||
plimits->mqCount -= pcb->limitStat.mqCount;
|
||||
plimits->shmSize -= pcb->limitStat.shmSize;
|
||||
return;
|
||||
}
|
||||
|
||||
UINT32 OsIPCLimitSetMqLimit(ProcIPCLimit *ipcLimit, UINT32 value)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
if ((ipcLimit == NULL) || (value == 0) || (value > LOSCFG_BASE_IPC_QUEUE_LIMIT)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (ipcLimit == g_rootIPCLimit) {
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
if (value < ipcLimit->mqCount) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
ipcLimit->mqCountLimit = value;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 OsIPCLimitSetShmLimit(ProcIPCLimit *ipcLimit, UINT32 value)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
if ((ipcLimit == NULL) || (value == 0) || (value > PLIMIT_IPC_SHM_LIMIT_MAX)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (ipcLimit == g_rootIPCLimit) {
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
if (value < ipcLimit->shmSize) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
ipcLimit->shmSizeLimit = value;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 OsIPCLimitMqAlloc(VOID)
|
||||
{
|
||||
UINT32 intSave;
|
||||
SCHEDULER_LOCK(intSave);
|
||||
LosProcessCB *run = OsCurrProcessGet();
|
||||
ProcIPCLimit *ipcLimit = (ProcIPCLimit *)run->plimits->limitsList[PROCESS_LIMITER_ID_IPC];
|
||||
if (ipcLimit->mqCount >= ipcLimit->mqCountLimit) {
|
||||
ipcLimit->mqFailedCount++;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
run->limitStat.mqCount++;
|
||||
ipcLimit->mqCount++;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
VOID OsIPCLimitMqFree(VOID)
|
||||
{
|
||||
UINT32 intSave;
|
||||
SCHEDULER_LOCK(intSave);
|
||||
LosProcessCB *run = OsCurrProcessGet();
|
||||
ProcIPCLimit *ipcLimit = (ProcIPCLimit *)run->plimits->limitsList[PROCESS_LIMITER_ID_IPC];
|
||||
ipcLimit->mqCount--;
|
||||
run->limitStat.mqCount--;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return;
|
||||
}
|
||||
|
||||
UINT32 OsIPCLimitShmAlloc(UINT32 size)
|
||||
{
|
||||
UINT32 intSave;
|
||||
SCHEDULER_LOCK(intSave);
|
||||
LosProcessCB *run = OsCurrProcessGet();
|
||||
ProcIPCLimit *ipcLimit = (ProcIPCLimit *)run->plimits->limitsList[PROCESS_LIMITER_ID_IPC];
|
||||
if ((ipcLimit->shmSize + size) >= ipcLimit->shmSizeLimit) {
|
||||
ipcLimit->shmFailedCount++;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
run->limitStat.shmSize += size;
|
||||
ipcLimit->shmSize += size;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
VOID OsIPCLimitShmFree(UINT32 size)
|
||||
{
|
||||
UINT32 intSave;
|
||||
SCHEDULER_LOCK(intSave);
|
||||
LosProcessCB *run = OsCurrProcessGet();
|
||||
ProcIPCLimit *ipcLimit = (ProcIPCLimit *)run->plimits->limitsList[PROCESS_LIMITER_ID_IPC];
|
||||
ipcLimit->shmSize -= size;
|
||||
run->limitStat.shmSize -= size;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_IPCLIMIT_H
|
||||
#define _LOS_IPCLIMIT_H
|
||||
|
||||
#include "los_typedef.h"
|
||||
#include "los_atomic.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct ProcIPCLimit {
|
||||
Atomic rc;
|
||||
UINT32 mqCount;
|
||||
UINT32 mqFailedCount;
|
||||
UINT32 mqCountLimit;
|
||||
UINT32 shmSize;
|
||||
UINT32 shmFailedCount;
|
||||
UINT32 shmSizeLimit;
|
||||
UINT64 migrateTime;
|
||||
} ProcIPCLimit;
|
||||
|
||||
enum IPCStatType {
|
||||
IPC_STAT_TYPE_MQ = 0,
|
||||
IPC_STAT_TYPE_SHM = 3,
|
||||
IPC_STAT_TYPE_BUT // buttock
|
||||
};
|
||||
|
||||
enum IPCStatOffset {
|
||||
IPC_STAT_OFFSET_MQ = 0,
|
||||
IPC_STAT_OFFSET_SHM = 3,
|
||||
IPC_STAT_OFFSET_BUT // buttock
|
||||
};
|
||||
|
||||
enum StatItem {
|
||||
STAT_ITEM_TOTAL,
|
||||
STAT_ITEM_FAILED,
|
||||
STAT_ITEM_LIMIT,
|
||||
STAT_ITEM_BUT // buttock
|
||||
};
|
||||
|
||||
VOID OsIPCLimitInit(UINTPTR limite);
|
||||
VOID *OsIPCLimitAlloc(VOID);
|
||||
VOID OsIPCLimitFree(UINTPTR limite);
|
||||
VOID OsIPCLimitCopy(UINTPTR dest, UINTPTR src);
|
||||
BOOL OsIPCLimiteMigrateCheck(UINTPTR curr, UINTPTR parent);
|
||||
VOID OsIPCLimitMigrate(UINTPTR currLimit, UINTPTR parentLimit, UINTPTR process);
|
||||
BOOL OsIPCLimitAddProcessCheck(UINTPTR limit, UINTPTR process);
|
||||
VOID OsIPCLimitAddProcess(UINTPTR limit, UINTPTR process);
|
||||
VOID OsIPCLimitDelProcess(UINTPTR limit, UINTPTR process);
|
||||
UINT32 OsIPCLimitSetMqLimit(ProcIPCLimit *ipcLimit, UINT32 value);
|
||||
UINT32 OsIPCLimitSetShmLimit(ProcIPCLimit *ipcLimit, UINT32 value);
|
||||
UINT32 OsIPCLimitMqAlloc(VOID);
|
||||
VOID OsIPCLimitMqFree(VOID);
|
||||
UINT32 OsIPCLimitShmAlloc(UINT32 size);
|
||||
VOID OsIPCLimitShmFree(UINT32 size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_IPCIMIT_H */
|
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
* Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <securec.h>
|
||||
#include "los_config.h"
|
||||
#include "los_hook.h"
|
||||
#include "los_process_pri.h"
|
||||
#include "los_plimits.h"
|
||||
|
||||
#ifdef LOSCFG_KERNEL_MEM_PLIMIT
|
||||
STATIC ProcMemLimiter *g_procMemLimiter = NULL;
|
||||
|
||||
VOID OsMemLimiterInit(UINTPTR limite)
|
||||
{
|
||||
ProcMemLimiter *procMemLimiter = (ProcMemLimiter *)limite;
|
||||
procMemLimiter->limit = OS_NULL_INT;
|
||||
g_procMemLimiter = procMemLimiter;
|
||||
}
|
||||
|
||||
VOID OsMemLimitSetLimit(UINT32 limit)
|
||||
{
|
||||
g_procMemLimiter->limit = limit;
|
||||
}
|
||||
|
||||
VOID *OsMemLimiterAlloc(VOID)
|
||||
{
|
||||
ProcMemLimiter *plimite = (ProcMemLimiter *)LOS_KernelMalloc(sizeof(ProcMemLimiter));
|
||||
if (plimite == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
(VOID)memset_s(plimite, sizeof(ProcMemLimiter), 0, sizeof(ProcMemLimiter));
|
||||
LOS_AtomicSet(&plimite->rc, 1);
|
||||
return (VOID *)plimite;
|
||||
}
|
||||
|
||||
VOID OsMemLimiterFree(UINTPTR limite)
|
||||
{
|
||||
ProcMemLimiter *plimite = (ProcMemLimiter *)limite;
|
||||
if (plimite == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOS_AtomicDec(&plimite->rc);
|
||||
if (LOS_AtomicRead(&plimite->rc) <= 0) {
|
||||
LOS_KernelFree((VOID *)limite);
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsMemLimiterCopy(UINTPTR dest, UINTPTR src)
|
||||
{
|
||||
ProcMemLimiter *plimiteDest = (ProcMemLimiter *)dest;
|
||||
ProcMemLimiter *plimiteSrc = (ProcMemLimiter *)src;
|
||||
plimiteDest->limit = plimiteSrc->limit;
|
||||
return;
|
||||
}
|
||||
|
||||
BOOL MemLimiteMigrateCheck(UINTPTR curr, UINTPTR parent)
|
||||
{
|
||||
ProcMemLimiter *currMemLimit = (ProcMemLimiter *)curr;
|
||||
ProcMemLimiter *parentMemLimit = (ProcMemLimiter *)parent;
|
||||
if ((currMemLimit->usage + parentMemLimit->usage) >= parentMemLimit->limit) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID OsMemLimiterMigrate(UINTPTR currLimit, UINTPTR parentLimit, UINTPTR process)
|
||||
{
|
||||
ProcMemLimiter *currMemLimit = (ProcMemLimiter *)currLimit;
|
||||
ProcMemLimiter *parentMemLimit = (ProcMemLimiter *)parentLimit;
|
||||
LosProcessCB *pcb = (LosProcessCB *)process;
|
||||
|
||||
if (pcb == NULL) {
|
||||
parentMemLimit->usage += currMemLimit->usage;
|
||||
parentMemLimit->failcnt += currMemLimit->failcnt;
|
||||
if (parentMemLimit->peak < parentMemLimit->usage) {
|
||||
parentMemLimit->peak = parentMemLimit->usage;
|
||||
}
|
||||
LOS_AtomicInc(&parentMemLimit->rc);
|
||||
return;
|
||||
}
|
||||
|
||||
parentMemLimit->usage -= pcb->limitStat.memUsed;
|
||||
currMemLimit->usage += pcb->limitStat.memUsed;
|
||||
}
|
||||
|
||||
BOOL OsMemLimitAddProcessCheck(UINTPTR limit, UINTPTR process)
|
||||
{
|
||||
ProcMemLimiter *memLimit = (ProcMemLimiter *)limit;
|
||||
LosProcessCB *pcb = (LosProcessCB *)process;
|
||||
if ((memLimit->usage + pcb->limitStat.memUsed) > memLimit->limit) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID OsMemLimitAddProcess(UINTPTR limit, UINTPTR process)
|
||||
{
|
||||
LosProcessCB *pcb = (LosProcessCB *)process;
|
||||
ProcMemLimiter *plimits = (ProcMemLimiter *)limit;
|
||||
plimits->usage += pcb->limitStat.memUsed;
|
||||
if (plimits->peak < plimits->usage) {
|
||||
plimits->peak = plimits->usage;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
VOID OsMemLimitDelProcess(UINTPTR limit, UINTPTR process)
|
||||
{
|
||||
LosProcessCB *pcb = (LosProcessCB *)process;
|
||||
ProcMemLimiter *plimits = (ProcMemLimiter *)limit;
|
||||
|
||||
plimits->usage -= pcb->limitStat.memUsed;
|
||||
return;
|
||||
}
|
||||
|
||||
UINT32 OsMemLimitSetMemLimit(ProcMemLimiter *memLimit, UINT64 value)
|
||||
{
|
||||
UINT32 intSave;
|
||||
if ((memLimit == NULL) || (value == 0)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (memLimit == g_procMemLimiter) {
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
if (value < memLimit->usage) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
memLimit->limit = value;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
#define MEM_LIMIT_LOCK(state, locked) do { \
|
||||
if (SCHEDULER_HELD()) { \
|
||||
locked = TRUE; \
|
||||
} else { \
|
||||
SCHEDULER_LOCK(state); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define MEM_LIMIT_UNLOCK(state, locked) do { \
|
||||
if (!locked) { \
|
||||
SCHEDULER_UNLOCK(state); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
UINT32 OsMemLimitCheckAndMemAdd(UINT32 size)
|
||||
{
|
||||
UINT32 intSave;
|
||||
BOOL locked = FALSE;
|
||||
MEM_LIMIT_LOCK(intSave, locked);
|
||||
LosProcessCB *run = OsCurrProcessGet();
|
||||
UINT32 currProcessID = run->processID;
|
||||
if ((run == NULL) || (run->plimits == NULL)) {
|
||||
MEM_LIMIT_UNLOCK(intSave, locked);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
ProcMemLimiter *memLimit = (ProcMemLimiter *)run->plimits->limitsList[PROCESS_LIMITER_ID_MEM];
|
||||
if ((memLimit->usage + size) > memLimit->limit) {
|
||||
memLimit->failcnt++;
|
||||
MEM_LIMIT_UNLOCK(intSave, locked);
|
||||
PRINT_ERR("plimits: process %u adjust the memory limit of Plimits group\n", currProcessID);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
memLimit->usage += size;
|
||||
run->limitStat.memUsed += size;
|
||||
if (memLimit->peak < memLimit->usage) {
|
||||
memLimit->peak = memLimit->usage;
|
||||
}
|
||||
MEM_LIMIT_UNLOCK(intSave, locked);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
VOID OsMemLimitMemFree(UINT32 size)
|
||||
{
|
||||
UINT32 intSave;
|
||||
BOOL locked = FALSE;
|
||||
MEM_LIMIT_LOCK(intSave, locked);
|
||||
LosProcessCB *run = OsCurrProcessGet();
|
||||
if ((run == NULL) || (run->plimits == NULL)) {
|
||||
MEM_LIMIT_UNLOCK(intSave, locked);
|
||||
return;
|
||||
}
|
||||
|
||||
ProcMemLimiter *memLimit = (ProcMemLimiter *)run->plimits->limitsList[PROCESS_LIMITER_ID_MEM];
|
||||
if (run->limitStat.memUsed > size) {
|
||||
run->limitStat.memUsed -= size;
|
||||
memLimit->usage -= size;
|
||||
}
|
||||
MEM_LIMIT_UNLOCK(intSave, locked);
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_MEMLIMIT_H
|
||||
#define _LOS_MEMLIMIT_H
|
||||
|
||||
#include "los_typedef.h"
|
||||
#include "los_atomic.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct ProcMemLimiter {
|
||||
Atomic rc;
|
||||
UINT64 usage;
|
||||
UINT64 limit;
|
||||
UINT64 peak;
|
||||
UINT32 failcnt;
|
||||
} ProcMemLimiter;
|
||||
|
||||
VOID OsMemLimiterInit(UINTPTR limite);
|
||||
VOID *OsMemLimiterAlloc(VOID);
|
||||
VOID OsMemLimiterFree(UINTPTR limite);
|
||||
VOID OsMemLimiterCopy(UINTPTR dest, UINTPTR src);
|
||||
BOOL MemLimiteMigrateCheck(UINTPTR curr, UINTPTR parent);
|
||||
VOID OsMemLimiterMigrate(UINTPTR currLimit, UINTPTR parentLimit, UINTPTR process);
|
||||
BOOL OsMemLimitAddProcessCheck(UINTPTR limit, UINTPTR process);
|
||||
VOID OsMemLimitAddProcess(UINTPTR limit, UINTPTR process);
|
||||
VOID OsMemLimitDelProcess(UINTPTR limit, UINTPTR process);
|
||||
UINT32 OsMemLimitSetMemLimit(ProcMemLimiter *memLimit, UINT64 value);
|
||||
VOID OsMemLimitSetLimit(UINTPTR limit);
|
||||
UINT32 OsMemLimitCheckAndMemAdd(UINT32 size);
|
||||
VOID OsMemLimitMemFree(UINT32 size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_MEMLIMIT_H */
|
|
@ -0,0 +1,505 @@
|
|||
/*
|
||||
* Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_base.h"
|
||||
#include "los_process_pri.h"
|
||||
#include "hal_timer.h"
|
||||
#include "los_plimits.h"
|
||||
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
typedef struct PlimiteOperations {
|
||||
VOID (*LimiterInit)(UINTPTR);
|
||||
VOID *(*LimiterAlloc)(VOID);
|
||||
VOID (*LimiterFree)(UINTPTR);
|
||||
VOID (*LimiterCopy)(UINTPTR, UINTPTR);
|
||||
BOOL (*LimiterAddProcessCheck)(UINTPTR, UINTPTR);
|
||||
VOID (*LimiterAddProcess)(UINTPTR, UINTPTR);
|
||||
VOID (*LimiterDelProcess)(UINTPTR, UINTPTR);
|
||||
BOOL (*LimiterMigrateCheck)(UINTPTR, UINTPTR);
|
||||
VOID (*LimiterMigrate)(UINTPTR, UINTPTR, UINTPTR);
|
||||
} PlimiteOperations;
|
||||
|
||||
static PlimiteOperations g_limiteOps[PROCESS_LIMITER_COUNT] = {
|
||||
[PROCESS_LIMITER_ID_PIDS] = {
|
||||
.LimiterInit = PidLimiterInit,
|
||||
.LimiterAlloc = PidLimiterAlloc,
|
||||
.LimiterFree = PidLimterFree,
|
||||
.LimiterCopy = PidLimiterCopy,
|
||||
.LimiterAddProcessCheck = OsPidLimitAddProcessCheck,
|
||||
.LimiterAddProcess = OsPidLimitAddProcess,
|
||||
.LimiterDelProcess = OsPidLimitDelProcess,
|
||||
.LimiterMigrateCheck = PidLimitMigrateCheck,
|
||||
.LimiterMigrate = OsPidLimiterMigrate,
|
||||
},
|
||||
#ifdef LOSCFG_KERNEL_MEM_PLIMIT
|
||||
[PROCESS_LIMITER_ID_MEM] = {
|
||||
.LimiterInit = OsMemLimiterInit,
|
||||
.LimiterAlloc = OsMemLimiterAlloc,
|
||||
.LimiterFree = OsMemLimiterFree,
|
||||
.LimiterCopy = OsMemLimiterCopy,
|
||||
.LimiterAddProcessCheck = OsMemLimitAddProcessCheck,
|
||||
.LimiterAddProcess = OsMemLimitAddProcess,
|
||||
.LimiterDelProcess = OsMemLimitDelProcess,
|
||||
.LimiterMigrateCheck = MemLimiteMigrateCheck,
|
||||
.LimiterMigrate = OsMemLimiterMigrate,
|
||||
},
|
||||
#endif
|
||||
#ifdef LOSCFG_KERNEL_SCHED_PLIMIT
|
||||
[PROCESS_LIMITER_ID_SCHED] = {
|
||||
.LimiterInit = OsSchedLimitInit,
|
||||
.LimiterAlloc = OsSchedLimitAlloc,
|
||||
.LimiterFree = OsSchedLimitFree,
|
||||
.LimiterCopy = OsSchedLimitCopy,
|
||||
.LimiterAddProcessCheck = NULL,
|
||||
.LimiterAddProcess = NULL,
|
||||
.LimiterDelProcess = NULL,
|
||||
.LimiterMigrateCheck = NULL,
|
||||
.LimiterMigrate = OsSchedLimitMigrate,
|
||||
},
|
||||
#endif
|
||||
#ifdef LOSCFG_KERNEL_DEV_PLIMIT
|
||||
[PROCESS_LIMITER_ID_DEV] = {
|
||||
.LimiterInit = OsDevLimitInit,
|
||||
.LimiterAlloc = OsDevLimitAlloc,
|
||||
.LimiterFree = OsDevLimitFree,
|
||||
.LimiterCopy = OsDevLimitCopy,
|
||||
.LimiterAddProcessCheck = NULL,
|
||||
.LimiterAddProcess = NULL,
|
||||
.LimiterDelProcess = NULL,
|
||||
.LimiterMigrateCheck = NULL,
|
||||
.LimiterMigrate = OsDevLimitMigrate,
|
||||
},
|
||||
#endif
|
||||
#ifdef LOSCFG_KERNEL_IPC_PLIMIT
|
||||
[PROCESS_LIMITER_ID_IPC] = {
|
||||
.LimiterInit = OsIPCLimitInit,
|
||||
.LimiterAlloc = OsIPCLimitAlloc,
|
||||
.LimiterFree = OsIPCLimitFree,
|
||||
.LimiterCopy = OsIPCLimitCopy,
|
||||
.LimiterAddProcessCheck = OsIPCLimitAddProcessCheck,
|
||||
.LimiterAddProcess = OsIPCLimitAddProcess,
|
||||
.LimiterDelProcess = OsIPCLimitDelProcess,
|
||||
.LimiterMigrateCheck = OsIPCLimiteMigrateCheck,
|
||||
.LimiterMigrate = OsIPCLimitMigrate,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC ProcLimiterSet *g_rootPLimite = NULL;
|
||||
|
||||
ProcLimiterSet *OsRootPLimitsGet(VOID)
|
||||
{
|
||||
return g_rootPLimite;
|
||||
}
|
||||
|
||||
UINT32 OsProcLimiterSetInit(VOID)
|
||||
{
|
||||
g_rootPLimite = (ProcLimiterSet *)LOS_KernelMalloc(sizeof(ProcLimiterSet));
|
||||
if (g_rootPLimite == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
(VOID)memset_s(g_rootPLimite, sizeof(ProcLimiterSet), 0, sizeof(ProcLimiterSet));
|
||||
|
||||
LOS_ListInit(&g_rootPLimite->childList);
|
||||
LOS_ListInit(&g_rootPLimite->processList);
|
||||
|
||||
ProcLimiterSet *procLimiterSet = g_rootPLimite;
|
||||
for (INT32 plimiteID = 0; plimiteID < PROCESS_LIMITER_COUNT; ++plimiteID) {
|
||||
procLimiterSet->limitsList[plimiteID] = (UINTPTR)g_limiteOps[plimiteID].LimiterAlloc();
|
||||
if (procLimiterSet->limitsList[plimiteID] == (UINTPTR)NULL) {
|
||||
OsPLimitsFree(procLimiterSet);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
if (g_limiteOps[plimiteID].LimiterInit != NULL) {
|
||||
g_limiteOps[plimiteID].LimiterInit(procLimiterSet->limitsList[plimiteID]);
|
||||
}
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC UINT32 PLimitsAddProcess(ProcLimiterSet *plimits, LosProcessCB *processCB)
|
||||
{
|
||||
UINT32 limitsID;
|
||||
if (plimits == NULL) {
|
||||
plimits = g_rootPLimite;
|
||||
}
|
||||
|
||||
if (processCB->plimits == g_rootPLimite) {
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
if (processCB->plimits == plimits) {
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
for (limitsID = 0; limitsID < PROCESS_LIMITER_COUNT; limitsID++) {
|
||||
if (g_limiteOps[limitsID].LimiterAddProcessCheck == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!g_limiteOps[limitsID].LimiterAddProcessCheck(plimits->limitsList[limitsID], (UINTPTR)processCB)) {
|
||||
return EACCES;
|
||||
}
|
||||
}
|
||||
|
||||
for (limitsID = 0; limitsID < PROCESS_LIMITER_COUNT; limitsID++) {
|
||||
if (g_limiteOps[limitsID].LimiterAddProcess == NULL) {
|
||||
continue;
|
||||
}
|
||||
g_limiteOps[limitsID].LimiterAddProcess(plimits->limitsList[limitsID], (UINTPTR)processCB);
|
||||
}
|
||||
|
||||
LOS_ListTailInsert(&plimits->processList, &processCB->plimitsList);
|
||||
plimits->pidCount++;
|
||||
processCB->plimits = plimits;
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 OsPLimitsAddProcess(ProcLimiterSet *plimits, LosProcessCB *processCB)
|
||||
{
|
||||
UINT32 intSave;
|
||||
SCHEDULER_LOCK(intSave);
|
||||
UINT32 ret = PLimitsAddProcess(plimits, processCB);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
UINT32 OsPLimitsAddPid(ProcLimiterSet *plimits, UINT32 pid)
|
||||
{
|
||||
UINT32 intSave, ret;
|
||||
if ((plimits == NULL) || OS_PID_CHECK_INVALID(pid) || (pid == 0)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (plimits == g_rootPLimite) {
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
LosProcessCB *processCB = OS_PCB_FROM_PID((unsigned int)pid);
|
||||
if (OsProcessIsInactive(processCB)) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
ret = PLimitsAddProcess(plimits, processCB);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC VOID PLimitsDeleteProcess(LosProcessCB *processCB)
|
||||
{
|
||||
if ((processCB == NULL) || (processCB->plimits == NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ProcLimiterSet *plimits = processCB->plimits;
|
||||
for (UINT32 limitsID = 0; limitsID < PROCESS_LIMITER_COUNT; limitsID++) {
|
||||
if (g_limiteOps[limitsID].LimiterDelProcess == NULL) {
|
||||
continue;
|
||||
}
|
||||
g_limiteOps[limitsID].LimiterDelProcess(plimits->limitsList[limitsID], (UINTPTR)processCB);
|
||||
}
|
||||
plimits->pidCount--;
|
||||
LOS_ListDelete(&processCB->plimitsList);
|
||||
processCB->plimits = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
VOID OsPLimitsDeleteProcess(LosProcessCB *processCB)
|
||||
{
|
||||
UINT32 intSave;
|
||||
SCHEDULER_LOCK(intSave);
|
||||
PLimitsDeleteProcess(processCB);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
UINT32 OsPLimitsPidsGet(const ProcLimiterSet *plimits, UINT32 *pids, UINT32 size)
|
||||
{
|
||||
UINT32 intSave;
|
||||
LosProcessCB *processCB = NULL;
|
||||
UINT32 minSize = LOS_GetSystemProcessMaximum() * sizeof(UINT32);
|
||||
if ((plimits == NULL) || (pids == NULL) || (size < minSize)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
LOS_DL_LIST *listHead = (LOS_DL_LIST *)&plimits->processList;
|
||||
if (LOS_ListEmpty(listHead)) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(processCB, listHead, LosProcessCB, plimitsList) {
|
||||
pids[OsGetPid(processCB)] = 1;
|
||||
}
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC VOID PLimitsProcessMerge(ProcLimiterSet *currPLimits, ProcLimiterSet *parentPLimits)
|
||||
{
|
||||
LOS_DL_LIST *head = &currPLimits->processList;
|
||||
while (!LOS_ListEmpty(head)) {
|
||||
LosProcessCB *processCB = LOS_DL_LIST_ENTRY(head->pstNext, LosProcessCB, plimitsList);
|
||||
PLimitsDeleteProcess(processCB);
|
||||
PLimitsAddProcess(parentPLimits, processCB);
|
||||
}
|
||||
LOS_ListDelete(&currPLimits->childList);
|
||||
currPLimits->parent = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
STATIC UINT32 PLimitsMigrateCheck(ProcLimiterSet *currPLimits, ProcLimiterSet *parentPLimits)
|
||||
{
|
||||
for (UINT32 limiteID = 0; limiteID < PROCESS_LIMITER_COUNT; limiteID++) {
|
||||
UINTPTR currLimit = currPLimits->limitsList[limiteID];
|
||||
UINTPTR parentLimit = parentPLimits->limitsList[limiteID];
|
||||
if (g_limiteOps[limiteID].LimiterMigrateCheck == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!g_limiteOps[limiteID].LimiterMigrateCheck(currLimit, parentLimit)) {
|
||||
return EPERM;
|
||||
}
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 OsPLimitsFree(ProcLimiterSet *currPLimits)
|
||||
{
|
||||
UINT32 intSave, ret;
|
||||
if (currPLimits == NULL) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
ProcLimiterSet *parentPLimits = currPLimits->parent;
|
||||
ret = PLimitsMigrateCheck(currPLimits, parentPLimits);
|
||||
if (ret != LOS_OK) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
PLimitsProcessMerge(currPLimits, parentPLimits);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
|
||||
for (INT32 limiteID = 0; limiteID < PROCESS_LIMITER_COUNT; ++limiteID) {
|
||||
UINTPTR procLimiter = currPLimits->limitsList[limiteID];
|
||||
if (g_limiteOps[limiteID].LimiterFree != NULL) {
|
||||
g_limiteOps[limiteID].LimiterFree(procLimiter);
|
||||
}
|
||||
}
|
||||
LOS_KernelFree(currPLimits);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
ProcLimiterSet *OsPLimitsCreate(ProcLimiterSet *parentPLimits)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
ProcLimiterSet *newPLimits = (ProcLimiterSet *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcLimiterSet));
|
||||
if (newPLimits == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
(VOID)memset_s(newPLimits, sizeof(ProcLimiterSet), 0, sizeof(ProcLimiterSet));
|
||||
LOS_ListInit(&newPLimits->childList);
|
||||
LOS_ListInit(&newPLimits->processList);
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
newPLimits->parent = parentPLimits;
|
||||
newPLimits->level = parentPLimits->level + 1;
|
||||
newPLimits->mask = parentPLimits->mask;
|
||||
|
||||
for (INT32 plimiteID = 0; plimiteID < PROCESS_LIMITER_COUNT; ++plimiteID) {
|
||||
newPLimits->limitsList[plimiteID] = (UINTPTR)g_limiteOps[plimiteID].LimiterAlloc();
|
||||
if (newPLimits->limitsList[plimiteID] == (UINTPTR)NULL) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
OsPLimitsFree(newPLimits);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (g_limiteOps[plimiteID].LimiterCopy != NULL) {
|
||||
g_limiteOps[plimiteID].LimiterCopy(newPLimits->limitsList[plimiteID],
|
||||
parentPLimits->limitsList[plimiteID]);
|
||||
}
|
||||
}
|
||||
LOS_ListTailInsert(&g_rootPLimite->childList, &newPLimits->childList);
|
||||
|
||||
(VOID)PLimitsDeleteProcess(OsCurrProcessGet());
|
||||
(VOID)PLimitsAddProcess(newPLimits, OsCurrProcessGet());
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return newPLimits;
|
||||
}
|
||||
|
||||
UINT32 OsPLimitsAddLimiters(ProcLimiterSet *procLimiterSet, enum ProcLimiterID plimiteID)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT32 mask = BIT(plimiteID);
|
||||
if ((procLimiterSet == NULL) || (plimiteID > PROCESS_LIMITER_COUNT)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
if (procLimiterSet->level == 0) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
if (procLimiterSet->mask & mask) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
UINTPTR currLimit = procLimiterSet->limitsList[plimiteID];
|
||||
UINTPTR parentPLimit = procLimiterSet->parent->limitsList[plimiteID];
|
||||
procLimiterSet->limitsList[plimiteID] = (UINTPTR)g_limiteOps[plimiteID].LimiterAlloc();
|
||||
if (procLimiterSet->limitsList[plimiteID] == (UINTPTR)NULL) {
|
||||
procLimiterSet->limitsList[plimiteID] = parentPLimit;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
g_limiteOps[plimiteID].LimiterCopy(procLimiterSet->limitsList[plimiteID], parentPLimit);
|
||||
g_limiteOps[plimiteID].LimiterMigrate(procLimiterSet->limitsList[plimiteID],
|
||||
parentPLimit, (UINTPTR)OsCurrProcessGet());
|
||||
g_limiteOps[plimiteID].LimiterFree(currLimit);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 OsPLimitsDeleteLimiters(ProcLimiterSet *procLimiterSet, enum ProcLimiterID plimiteID, UINT32 *mask)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
if ((procLimiterSet == NULL) || (plimiteID > PROCESS_LIMITER_COUNT) || (mask == NULL)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
if (!(procLimiterSet->mask & BIT(plimiteID))) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (procLimiterSet->level == 0) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
UINTPTR currLimit = procLimiterSet->limitsList[plimiteID];
|
||||
UINTPTR parentPLimit = procLimiterSet->parent->limitsList[plimiteID];
|
||||
if ((g_limiteOps[plimiteID].LimiterMigrateCheck != NULL) &&
|
||||
!g_limiteOps[plimiteID].LimiterMigrateCheck(currLimit, parentPLimit)) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
g_limiteOps[plimiteID].LimiterMigrate(currLimit, parentPLimit, 0);
|
||||
procLimiterSet->limitsList[plimiteID] = parentPLimit;
|
||||
g_limiteOps[plimiteID].LimiterFree(currLimit);
|
||||
|
||||
procLimiterSet->mask &= (~BIT(plimiteID));
|
||||
*mask = procLimiterSet->mask;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_KERNEL_MEM_PLIMIT
|
||||
UINT32 OsPLimitsMemUsageGet(ProcLimiterSet *plimits, UINT64 *usage, UINT32 size)
|
||||
{
|
||||
UINT32 intSave;
|
||||
LosProcessCB *processCB = NULL;
|
||||
UINT32 minSize = LOS_GetSystemProcessMaximum() * sizeof(UINT64) + sizeof(ProcMemLimiter);
|
||||
ProcMemLimiter *memLimit = (ProcMemLimiter *)usage;
|
||||
UINT64 *memSuage = (UINT64 *)((UINTPTR)usage + sizeof(ProcMemLimiter));
|
||||
if ((plimits == NULL) || (usage == NULL) || (size < minSize)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
(VOID)memcpy_s(memLimit, sizeof(ProcMemLimiter),
|
||||
(VOID *)plimits->limitsList[PROCESS_LIMITER_ID_MEM], sizeof(ProcMemLimiter));
|
||||
LOS_DL_LIST *listHead = (LOS_DL_LIST *)&plimits->processList;
|
||||
if (LOS_ListEmpty(listHead)) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(processCB, listHead, LosProcessCB, plimitsList) {
|
||||
memSuage[OsGetPid(processCB)] = processCB->limitStat.memUsed;
|
||||
}
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_KERNEL_IPC_PLIMIT
|
||||
UINT32 OsPLimitsIPCStatGet(ProcLimiterSet *plimits, ProcIPCLimit *ipc, UINT32 size)
|
||||
{
|
||||
UINT32 intSave;
|
||||
if ((plimits == NULL) || (ipc == NULL) || (size != sizeof(ProcIPCLimit))) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
(VOID)memcpy_s(ipc, sizeof(ProcIPCLimit),
|
||||
(VOID *)plimits->limitsList[PROCESS_LIMITER_ID_IPC], sizeof(ProcIPCLimit));
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_KERNEL_SCHED_PLIMIT
|
||||
UINT32 OsPLimitsSchedUsageGet(ProcLimiterSet *plimits, UINT64 *usage, UINT32 size)
|
||||
{
|
||||
UINT32 intSave;
|
||||
LosProcessCB *processCB = NULL;
|
||||
UINT32 minSize = LOS_GetSystemProcessMaximum() * sizeof(UINT64);
|
||||
if ((plimits == NULL) || (usage == NULL) || (size < minSize)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
LOS_DL_LIST *listHead = (LOS_DL_LIST *)&plimits->processList;
|
||||
if (LOS_ListEmpty(listHead)) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(processCB, listHead, LosProcessCB, plimitsList) {
|
||||
usage[OsGetPid(processCB)] = processCB->limitStat.allRuntime;
|
||||
}
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_PLIMITS_H
|
||||
#define _LOS_PLIMITS_H
|
||||
|
||||
#include "los_list.h"
|
||||
#include "los_typedef.h"
|
||||
#include "los_processlimit.h"
|
||||
#include "los_memlimit.h"
|
||||
#include "los_ipclimit.h"
|
||||
#include "los_devicelimit.h"
|
||||
#include "los_schedlimit.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* proc limit set lock */
|
||||
#define PLIMITS_MIN_PERIOD_IN_US 1000000
|
||||
#define PLIMITS_MIN_QUOTA_IN_US 1
|
||||
#define PLIMITS_DELETE_WAIT_TIME 1000
|
||||
typedef struct ProcessCB LosProcessCB;
|
||||
|
||||
enum ProcLimiterID {
|
||||
PROCESS_LIMITER_ID_PIDS = 0,
|
||||
#ifdef LOSCFG_KERNEL_MEM_PLIMIT
|
||||
PROCESS_LIMITER_ID_MEM,
|
||||
#endif
|
||||
#ifdef LOSCFG_KERNEL_SCHED_PLIMIT
|
||||
PROCESS_LIMITER_ID_SCHED,
|
||||
#endif
|
||||
#ifdef LOSCFG_KERNEL_DEV_PLIMIT
|
||||
PROCESS_LIMITER_ID_DEV,
|
||||
#endif
|
||||
#ifdef LOSCFG_KERNEL_IPC_PLIMIT
|
||||
PROCESS_LIMITER_ID_IPC,
|
||||
#endif
|
||||
PROCESS_LIMITER_COUNT,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
#ifdef LOSCFG_KERNEL_MEM_PLIMIT
|
||||
UINT64 memUsed;
|
||||
#endif
|
||||
#ifdef LOSCFG_KERNEL_IPC_PLIMIT
|
||||
UINT32 mqCount;
|
||||
UINT32 shmSize;
|
||||
#endif
|
||||
#ifdef LOSCFG_KERNEL_SCHED_PLIMIT
|
||||
UINT64 allRuntime;
|
||||
#endif
|
||||
} PLimitsData;
|
||||
|
||||
typedef struct TagPLimiterSet {
|
||||
struct TagPLimiterSet *parent; /* plimite parent */
|
||||
LOS_DL_LIST childList; /* plimite childList */
|
||||
LOS_DL_LIST processList;
|
||||
UINT32 pidCount;
|
||||
UINTPTR limitsList[PROCESS_LIMITER_COUNT]; /* plimite list */
|
||||
UINT32 mask; /* each bit indicates that a limite exists */
|
||||
UINT8 level; /* plimits hierarchy level */
|
||||
} ProcLimiterSet;
|
||||
|
||||
typedef struct ProcessCB LosProcessCB;
|
||||
ProcLimiterSet *OsRootPLimitsGet(VOID);
|
||||
UINT32 OsPLimitsAddProcess(ProcLimiterSet *plimits, LosProcessCB *processCB);
|
||||
UINT32 OsPLimitsAddPid(ProcLimiterSet *plimits, UINT32 pid);
|
||||
VOID OsPLimitsDeleteProcess(LosProcessCB *processCB);
|
||||
UINT32 OsPLimitsPidsGet(const ProcLimiterSet *plimits, UINT32 *pids, UINT32 size);
|
||||
UINT32 OsPLimitsFree(ProcLimiterSet *currPLimits);
|
||||
ProcLimiterSet *OsPLimitsCreate(ProcLimiterSet *parentProcLimiterSet);
|
||||
UINT32 OsProcLimiterSetInit(VOID);
|
||||
|
||||
UINT32 OsPLimitsAddLimiters(ProcLimiterSet *procLimiterSet, enum ProcLimiterID plimiteID);
|
||||
UINT32 OsPLimitsDeleteLimiters(ProcLimiterSet *procLimiterSet, enum ProcLimiterID plimiteID, UINT32 *mask);
|
||||
|
||||
UINT32 OsPLimitsMemUsageGet(ProcLimiterSet *plimits, UINT64 *usage, UINT32 size);
|
||||
UINT32 OsPLimitsIPCStatGet(ProcLimiterSet *plimits, ProcIPCLimit *ipc, UINT32 size);
|
||||
UINT32 OsPLimitsSchedUsageGet(ProcLimiterSet *plimits, UINT64 *usage, UINT32 size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_PLIMITS_H */
|
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_config.h"
|
||||
#include "los_process_pri.h"
|
||||
#include "los_process.h"
|
||||
#include "los_plimits.h"
|
||||
#include "los_task_pri.h"
|
||||
#include "los_processlimit.h"
|
||||
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
STATIC PidLimit *g_rootPidLimit = NULL;
|
||||
|
||||
VOID PidLimiterInit(UINTPTR limit)
|
||||
{
|
||||
PidLimit *pidLimit = (PidLimit *)limit;
|
||||
if (pidLimit == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
pidLimit->pidLimit = LOS_GetSystemProcessMaximum();
|
||||
pidLimit->priorityLimit = OS_USER_PROCESS_PRIORITY_HIGHEST;
|
||||
g_rootPidLimit = pidLimit;
|
||||
}
|
||||
|
||||
VOID *PidLimiterAlloc(VOID)
|
||||
{
|
||||
PidLimit *plimite = (PidLimit *)LOS_KernelMalloc(sizeof(PidLimit));
|
||||
if (plimite == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
(VOID)memset_s(plimite, sizeof(PidLimit), 0, sizeof(PidLimit));
|
||||
LOS_AtomicSet(&plimite->rc, 1);
|
||||
return (VOID *)plimite;
|
||||
}
|
||||
|
||||
VOID PidLimterFree(UINTPTR limit)
|
||||
{
|
||||
PidLimit *pidLimit = (PidLimit *)limit;
|
||||
if (pidLimit == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOS_AtomicDec(&pidLimit->rc);
|
||||
if (LOS_AtomicRead(&pidLimit->rc) <= 0) {
|
||||
LOS_KernelFree((VOID *)limit);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL PidLimitMigrateCheck(UINTPTR curr, UINTPTR parent)
|
||||
{
|
||||
PidLimit *currPidLimit = (PidLimit *)curr;
|
||||
PidLimit *parentPidLimit = (PidLimit *)parent;
|
||||
if ((currPidLimit == NULL) || (parentPidLimit == NULL)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((currPidLimit->pidCount + parentPidLimit->pidCount) >= parentPidLimit->pidLimit) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID OsPidLimiterMigrate(UINTPTR currLimit, UINTPTR parentLimit, UINTPTR process)
|
||||
{
|
||||
(VOID)currLimit;
|
||||
|
||||
PidLimit *parentPidLimit = (PidLimit *)parentLimit;
|
||||
LosProcessCB *pcb = (LosProcessCB *)process;
|
||||
|
||||
if (pcb == NULL) {
|
||||
LOS_AtomicInc(&parentPidLimit->rc);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL OsPidLimitAddProcessCheck(UINTPTR limit, UINTPTR process)
|
||||
{
|
||||
(VOID)process;
|
||||
PidLimit *pidLimit = (PidLimit *)limit;
|
||||
if (pidLimit->pidCount >= pidLimit->pidLimit) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID OsPidLimitAddProcess(UINTPTR limit, UINTPTR process)
|
||||
{
|
||||
(VOID)process;
|
||||
PidLimit *plimits = (PidLimit *)limit;
|
||||
|
||||
plimits->pidCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
VOID OsPidLimitDelProcess(UINTPTR limit, UINTPTR process)
|
||||
{
|
||||
(VOID)process;
|
||||
PidLimit *plimits = (PidLimit *)limit;
|
||||
|
||||
plimits->pidCount--;
|
||||
return;
|
||||
}
|
||||
|
||||
VOID PidLimiterCopy(UINTPTR curr, UINTPTR parent)
|
||||
{
|
||||
PidLimit *currPidLimit = (PidLimit *)curr;
|
||||
PidLimit *parentPidLimit = (PidLimit *)parent;
|
||||
if ((currPidLimit == NULL) || (parentPidLimit == NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
currPidLimit->pidLimit = parentPidLimit->pidLimit;
|
||||
currPidLimit->priorityLimit = parentPidLimit->priorityLimit;
|
||||
currPidLimit->pidCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
UINT32 PidLimitSetPidLimit(PidLimit *pidLimit, UINT32 pidMax)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
if ((pidLimit == NULL) || (pidMax > LOS_GetSystemProcessMaximum())) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (pidLimit == g_rootPidLimit) {
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
if (pidLimit->pidCount >= pidMax) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
pidLimit->pidLimit = pidMax;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 PidLimitSetPriorityLimit(PidLimit *pidLimit, UINT32 priority)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
if ((pidLimit == NULL) ||
|
||||
(priority < OS_USER_PROCESS_PRIORITY_HIGHEST) ||
|
||||
(priority > OS_PROCESS_PRIORITY_LOWEST)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (pidLimit == g_rootPidLimit) {
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
pidLimit->priorityLimit = priority;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT16 OsPidLimitGetPriorityLimit(VOID)
|
||||
{
|
||||
UINT32 intSave;
|
||||
SCHEDULER_LOCK(intSave);
|
||||
LosProcessCB *run = OsCurrProcessGet();
|
||||
PidLimit *pidLimit = (PidLimit *)run->plimits->limitsList[PROCESS_LIMITER_ID_PIDS];
|
||||
UINT16 priority = pidLimit->priorityLimit;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return priority;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_PROCESSLIMIT_H
|
||||
#define _LOS_PROCESSLIMIT_H
|
||||
|
||||
#include "los_list.h"
|
||||
#include "los_typedef.h"
|
||||
#include "los_atomic.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct PidLimit {
|
||||
Atomic rc;
|
||||
UINT32 pidLimit;
|
||||
UINT32 priorityLimit;
|
||||
UINT32 pidCount;
|
||||
} PidLimit;
|
||||
|
||||
VOID PidLimiterInit(UINTPTR limit);
|
||||
VOID *PidLimiterAlloc(VOID);
|
||||
VOID PidLimterFree(UINTPTR limit);
|
||||
VOID PidLimiterCopy(UINTPTR curr, UINTPTR parent);
|
||||
BOOL PidLimitMigrateCheck(UINTPTR curr, UINTPTR parent);
|
||||
VOID OsPidLimiterMigrate(UINTPTR currLimit, UINTPTR parentLimit, UINTPTR process);
|
||||
BOOL OsPidLimitAddProcessCheck(UINTPTR limit, UINTPTR process);
|
||||
VOID OsPidLimitAddProcess(UINTPTR limit, UINTPTR process);
|
||||
VOID OsPidLimitDelProcess(UINTPTR limit, UINTPTR process);
|
||||
UINT32 PidLimitSetPidLimit(PidLimit *pidLimit, UINT32 pidMax);
|
||||
UINT32 PidLimitSetPriorityLimit(PidLimit *pidLimit, UINT32 priority);
|
||||
UINT16 OsPidLimitGetPriorityLimit(VOID);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_schedlimit.h"
|
||||
#include "los_process_pri.h"
|
||||
|
||||
#ifdef LOSCFG_KERNEL_SCHED_PLIMIT
|
||||
STATIC ProcSchedLimiter *g_procSchedLimit = NULL;
|
||||
|
||||
VOID OsSchedLimitInit(UINTPTR limit)
|
||||
{
|
||||
ProcSchedLimiter *schedLimit = (ProcSchedLimiter *)limit;
|
||||
schedLimit->period = 0;
|
||||
schedLimit->quota = 0;
|
||||
g_procSchedLimit = schedLimit;
|
||||
}
|
||||
|
||||
VOID *OsSchedLimitAlloc(VOID)
|
||||
{
|
||||
ProcSchedLimiter *plimit = (ProcSchedLimiter *)LOS_KernelMalloc(sizeof(ProcSchedLimiter));
|
||||
if (plimit == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
(VOID)memset_s(plimit, sizeof(ProcSchedLimiter), 0, sizeof(ProcSchedLimiter));
|
||||
LOS_AtomicSet(&plimit->rc, 1);
|
||||
return (VOID *)plimit;
|
||||
}
|
||||
|
||||
VOID OsSchedLimitFree(UINTPTR limit)
|
||||
{
|
||||
ProcSchedLimiter *schedLimit = (ProcSchedLimiter *)limit;
|
||||
if (schedLimit == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOS_AtomicDec(&schedLimit->rc);
|
||||
if (LOS_AtomicRead(&schedLimit->rc) <= 0) {
|
||||
LOS_KernelFree((VOID *)limit);
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsSchedLimitCopy(UINTPTR dest, UINTPTR src)
|
||||
{
|
||||
ProcSchedLimiter *plimitDest = (ProcSchedLimiter *)dest;
|
||||
ProcSchedLimiter *plimitSrc = (ProcSchedLimiter *)src;
|
||||
plimitDest->period = plimitSrc->period;
|
||||
plimitDest->quota = plimitSrc->quota;
|
||||
return;
|
||||
}
|
||||
|
||||
VOID OsSchedLimitMigrate(UINTPTR currLimit, UINTPTR parentLimit, UINTPTR process)
|
||||
{
|
||||
(VOID)currLimit;
|
||||
ProcSchedLimiter *parentSchedLimit = (ProcSchedLimiter *)parentLimit;
|
||||
LosProcessCB *pcb = (LosProcessCB *)process;
|
||||
if (pcb == NULL) {
|
||||
LOS_AtomicInc(&parentSchedLimit->rc);
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsSchedLimitUpdateRuntime(LosTaskCB *runTask, UINT64 currTime, INT32 incTime)
|
||||
{
|
||||
LosProcessCB *run = (LosProcessCB *)runTask->processCB;
|
||||
if ((run == NULL) || (run->plimits == NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ProcSchedLimiter *schedLimit = (ProcSchedLimiter *)run->plimits->limitsList[PROCESS_LIMITER_ID_SCHED];
|
||||
|
||||
run->limitStat.allRuntime += incTime;
|
||||
if ((schedLimit->period <= 0) || (schedLimit->quota <= 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((schedLimit->startTime <= currTime) && (schedLimit->allRuntime < schedLimit->quota)) {
|
||||
schedLimit->allRuntime += incTime;
|
||||
return;
|
||||
}
|
||||
|
||||
if (schedLimit->startTime <= currTime) {
|
||||
schedLimit->startTime = currTime + schedLimit->period;
|
||||
schedLimit->allRuntime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL OsSchedLimitCheckTime(LosTaskCB *task)
|
||||
{
|
||||
UINT64 currTime = OsGetCurrSchedTimeCycle();
|
||||
LosProcessCB *processCB = (LosProcessCB *)task->processCB;
|
||||
if ((processCB == NULL) || (processCB->plimits == NULL)) {
|
||||
return TRUE;
|
||||
}
|
||||
ProcSchedLimiter *schedLimit = (ProcSchedLimiter *)processCB->plimits->limitsList[PROCESS_LIMITER_ID_SCHED];
|
||||
if (schedLimit->startTime >= currTime) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
UINT32 OsSchedLimitSetPeriod(ProcSchedLimiter *schedLimit, UINT64 value)
|
||||
{
|
||||
UINT32 intSave;
|
||||
if (schedLimit == NULL) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (schedLimit == g_procSchedLimit) {
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
schedLimit->period = value;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 OsSchedLimitSetQuota(ProcSchedLimiter *schedLimit, UINT64 value)
|
||||
{
|
||||
UINT32 intSave;
|
||||
if (schedLimit == NULL) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (schedLimit == g_procSchedLimit) {
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
if (value > (UINT64)schedLimit->period) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
schedLimit->quota = value;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_SCHEDLIMIT_H
|
||||
#define _LOS_SCHEDLIMIT_H
|
||||
|
||||
#include "los_typedef.h"
|
||||
#include "los_atomic.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define CORE_US_PER_SECOND (1000 * 1000) /* 1000 * 1000 us per second */
|
||||
typedef struct TagTaskCB LosTaskCB;
|
||||
|
||||
typedef struct ProcSchedLimiter {
|
||||
Atomic rc;
|
||||
UINT64 startTime;
|
||||
UINT64 endTime;
|
||||
UINT64 period;
|
||||
UINT64 quota;
|
||||
UINT64 allRuntime;
|
||||
UINT64 overrunTime;
|
||||
UINT64 stat;
|
||||
} ProcSchedLimiter;
|
||||
|
||||
VOID OsSchedLimitInit(UINTPTR limit);
|
||||
VOID *OsSchedLimitAlloc(VOID);
|
||||
VOID OsSchedLimitFree(UINTPTR limit);
|
||||
VOID OsSchedLimitCopy(UINTPTR dest, UINTPTR src);
|
||||
VOID OsSchedLimitMigrate(UINTPTR currLimit, UINTPTR parentLimit, UINTPTR process);
|
||||
VOID OsSchedLimitUpdateRuntime(LosTaskCB *runTask, UINT64 currTime, INT32 incTime);
|
||||
UINT32 OsSchedLimitSetPeriod(ProcSchedLimiter *schedLimit, UINT64 value);
|
||||
UINT32 OsSchedLimitSetQuota(ProcSchedLimiter *schedLimit, UINT64 value);
|
||||
BOOL OsSchedLimitCheckTime(LosTaskCB *task);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_SCHEDLIMIT_H */
|
|
@ -156,6 +156,12 @@ int SysSchedSetScheduler(int id, int policy, int prio, int flag)
|
|||
id = (int)LOS_GetCurrProcessID();
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
if (prio < OsPidLimitGetPriorityLimit()) {
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = OsPermissionToCheck(id, LOS_GetCurrProcessID());
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
|
@ -210,6 +216,12 @@ int SysSetProcessPriority(int which, int who, unsigned int prio)
|
|||
who = (int)LOS_GetCurrProcessID();
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
if (prio < OsPidLimitGetPriorityLimit()) {
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = OsPermissionToCheck(who, LOS_GetCurrProcessID());
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
|
@ -224,6 +236,12 @@ int SysSchedSetParam(int id, unsigned int prio, int flag)
|
|||
return -OsUserTaskSchedulerSet(id, LOS_SCHED_RR, prio, false);
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_KERNEL_PLIMITS
|
||||
if (prio < OsPidLimitGetPriorityLimit()) {
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return SysSetProcessPriority(LOS_PRIO_PROCESS, id, prio);
|
||||
}
|
||||
|
||||
|
|
|
@ -194,6 +194,13 @@ ifeq ($(LOSCFG_KERNEL_SYSCALL), y)
|
|||
LITEOS_BASELIB += -lsyscall
|
||||
LIB_SUBDIRS += syscall
|
||||
endif
|
||||
|
||||
ifeq ($(LOSCFG_KERNEL_PLIMITS), y)
|
||||
LITEOS_BASELIB += -lplimit
|
||||
LIB_SUBDIRS += kernel/extended/plimit
|
||||
LITEOS_PLIMITS_INCLUDE = -I $(LITEOSTOPDIR)/kernel/extended/plimit
|
||||
endif
|
||||
|
||||
LIB_SUBDIRS += kernel/user
|
||||
|
||||
################################### Kernel Option End ################################
|
||||
|
@ -517,7 +524,7 @@ LITEOS_EXTKERNEL_INCLUDE := $(LITEOS_CPPSUPPORT_INCLUDE) $(LITEOS_DYNLOAD_INCL
|
|||
$(LITEOS_VDSO_INCLUDE) $(LITEOS_LITEIPC_INCLUDE) \
|
||||
$(LITEOS_PIPE_INCLUDE) $(LITEOS_CPUP_INCLUDE) \
|
||||
$(LITEOS_PERF_INCLUDE) $(LITEOS_LMS_INCLUDE) \
|
||||
$(LITEOS_PM_INCLUDE)
|
||||
$(LITEOS_PM_INCLUDE) $(LITEOS_PLIMITS_INCLUDE)
|
||||
LITEOS_COMPAT_INCLUDE := $(LITEOS_POSIX_INCLUDE) $(LITEOS_LINUX_INCLUDE) \
|
||||
$(LITEOS_BSD_INCLUDE)
|
||||
LITEOS_FS_INCLUDE := $(LITEOS_VFS_INCLUDE) $(LITEOS_FAT_CACHE_INCLUDE) \
|
||||
|
|
Loading…
Reference in New Issue