• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification,
5  * are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this list of
8  *    conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11  *    of conditions and the following disclaimer in the documentation and/or other materials
12  *    provided with the distribution.
13  *
14  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15  *    to endorse or promote products derived from this software without specific prior written
16  *    permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #ifdef LOSCFG_KERNEL_IPC_PLIMIT
32 #include "los_ipclimit.h"
33 #include "los_process_pri.h"
34 
35 STATIC ProcIPCLimit *g_rootIPCLimit = NULL;
36 #define PLIMIT_IPC_SHM_LIMIT_MAX 0xFFFFFFFF
37 
OsIPCLimitInit(UINTPTR limite)38 VOID OsIPCLimitInit(UINTPTR limite)
39 {
40     ProcIPCLimit *plimite = (ProcIPCLimit *)limite;
41     plimite->mqCountLimit = LOSCFG_BASE_IPC_QUEUE_LIMIT;
42     plimite->shmSizeLimit = PLIMIT_IPC_SHM_LIMIT_MAX;
43     g_rootIPCLimit = plimite;
44 }
45 
OsIPCLimitAlloc(VOID)46 VOID *OsIPCLimitAlloc(VOID)
47 {
48     ProcIPCLimit *plimite = (ProcIPCLimit *)LOS_MemAlloc(m_aucSysMem1, sizeof(ProcIPCLimit));
49     if (plimite == NULL) {
50         return NULL;
51     }
52     (VOID)memset_s(plimite, sizeof(ProcIPCLimit), 0, sizeof(ProcIPCLimit));
53     return (VOID *)plimite;
54 }
55 
OsIPCLimitFree(UINTPTR limite)56 VOID OsIPCLimitFree(UINTPTR limite)
57 {
58     ProcIPCLimit *plimite = (ProcIPCLimit *)limite;
59     if (plimite == NULL) {
60         return;
61     }
62 
63     (VOID)LOS_MemFree(m_aucSysMem1, (VOID *)plimite);
64 }
65 
OsIPCLimitCopy(UINTPTR dest,UINTPTR src)66 VOID OsIPCLimitCopy(UINTPTR dest, UINTPTR src)
67 {
68     ProcIPCLimit *plimiteDest = (ProcIPCLimit *)dest;
69     ProcIPCLimit *plimiteSrc = (ProcIPCLimit *)src;
70     plimiteDest->mqCountLimit = plimiteSrc->mqCountLimit;
71     plimiteDest->shmSizeLimit = plimiteSrc->shmSizeLimit;
72     return;
73 }
74 
OsIPCLimiteMigrateCheck(UINTPTR curr,UINTPTR parent)75 BOOL OsIPCLimiteMigrateCheck(UINTPTR curr, UINTPTR parent)
76 {
77     ProcIPCLimit *currIpcLimit = (ProcIPCLimit *)curr;
78     ProcIPCLimit *parentIpcLimit = (ProcIPCLimit *)parent;
79     if ((currIpcLimit->mqCount + parentIpcLimit->mqCount) >= parentIpcLimit->mqCountLimit) {
80         return FALSE;
81     }
82 
83     if ((currIpcLimit->shmSize + parentIpcLimit->shmSize) >= parentIpcLimit->shmSizeLimit) {
84         return FALSE;
85     }
86     return TRUE;
87 }
88 
OsIPCLimitMigrate(UINTPTR currLimit,UINTPTR parentLimit,UINTPTR process)89 VOID OsIPCLimitMigrate(UINTPTR currLimit, UINTPTR parentLimit, UINTPTR process)
90 {
91     ProcIPCLimit *currIpcLimit = (ProcIPCLimit *)currLimit;
92     ProcIPCLimit *parentIpcLimit = (ProcIPCLimit *)parentLimit;
93     LosProcessCB *pcb = (LosProcessCB *)process;
94 
95     if (pcb == NULL) {
96         parentIpcLimit->mqCount += currIpcLimit->mqCount;
97         parentIpcLimit->mqFailedCount += currIpcLimit->mqFailedCount;
98         parentIpcLimit->shmSize += currIpcLimit->shmSize;
99         parentIpcLimit->shmFailedCount += currIpcLimit->shmFailedCount;
100         return;
101     }
102 
103     parentIpcLimit->mqCount -= pcb->limitStat.mqCount;
104     parentIpcLimit->shmSize -= pcb->limitStat.shmSize;
105     currIpcLimit->mqCount += pcb->limitStat.mqCount;
106     currIpcLimit->shmSize += pcb->limitStat.shmSize;
107 }
108 
OsIPCLimitAddProcessCheck(UINTPTR limit,UINTPTR process)109 BOOL OsIPCLimitAddProcessCheck(UINTPTR limit, UINTPTR process)
110 {
111     ProcIPCLimit *ipcLimit = (ProcIPCLimit *)limit;
112     LosProcessCB *pcb = (LosProcessCB *)process;
113     if ((ipcLimit->mqCount + pcb->limitStat.mqCount) >= ipcLimit->mqCountLimit) {
114         return FALSE;
115     }
116 
117     if ((ipcLimit->shmSize + pcb->limitStat.shmSize) >= ipcLimit->shmSizeLimit) {
118         return FALSE;
119     }
120 
121     return TRUE;
122 }
123 
OsIPCLimitAddProcess(UINTPTR limit,UINTPTR process)124 VOID OsIPCLimitAddProcess(UINTPTR limit, UINTPTR process)
125 {
126     LosProcessCB *pcb = (LosProcessCB *)process;
127     ProcIPCLimit *plimits = (ProcIPCLimit *)limit;
128     plimits->mqCount += pcb->limitStat.mqCount;
129     plimits->shmSize += pcb->limitStat.shmSize;
130     return;
131 }
132 
OsIPCLimitDelProcess(UINTPTR limit,UINTPTR process)133 VOID OsIPCLimitDelProcess(UINTPTR limit, UINTPTR process)
134 {
135     LosProcessCB *pcb = (LosProcessCB *)process;
136     ProcIPCLimit *plimits = (ProcIPCLimit *)limit;
137 
138     plimits->mqCount -= pcb->limitStat.mqCount;
139     plimits->shmSize -= pcb->limitStat.shmSize;
140     return;
141 }
142 
OsIPCLimitSetMqLimit(ProcIPCLimit * ipcLimit,UINT32 value)143 UINT32 OsIPCLimitSetMqLimit(ProcIPCLimit *ipcLimit, UINT32 value)
144 {
145     UINT32 intSave;
146 
147     if ((ipcLimit == NULL) || (value == 0) || (value > LOSCFG_BASE_IPC_QUEUE_LIMIT)) {
148         return EINVAL;
149     }
150 
151     if (ipcLimit == g_rootIPCLimit) {
152         return EPERM;
153     }
154 
155     SCHEDULER_LOCK(intSave);
156     if (value < ipcLimit->mqCount) {
157         SCHEDULER_UNLOCK(intSave);
158         return EINVAL;
159     }
160 
161     ipcLimit->mqCountLimit = value;
162     SCHEDULER_UNLOCK(intSave);
163     return LOS_OK;
164 }
165 
OsIPCLimitSetShmLimit(ProcIPCLimit * ipcLimit,UINT32 value)166 UINT32 OsIPCLimitSetShmLimit(ProcIPCLimit *ipcLimit, UINT32 value)
167 {
168     UINT32 intSave;
169 
170     if ((ipcLimit == NULL) || (value == 0) || (value > PLIMIT_IPC_SHM_LIMIT_MAX)) {
171         return EINVAL;
172     }
173 
174     if (ipcLimit == g_rootIPCLimit) {
175         return EPERM;
176     }
177 
178     SCHEDULER_LOCK(intSave);
179     if (value < ipcLimit->shmSize) {
180         SCHEDULER_UNLOCK(intSave);
181         return EINVAL;
182     }
183 
184     ipcLimit->shmSizeLimit = value;
185     SCHEDULER_UNLOCK(intSave);
186     return LOS_OK;
187 }
188 
OsIPCLimitMqAlloc(VOID)189 UINT32 OsIPCLimitMqAlloc(VOID)
190 {
191     UINT32 intSave;
192     SCHEDULER_LOCK(intSave);
193     LosProcessCB *run = OsCurrProcessGet();
194     ProcIPCLimit *ipcLimit = (ProcIPCLimit *)run->plimits->limitsList[PROCESS_LIMITER_ID_IPC];
195     if (ipcLimit->mqCount >= ipcLimit->mqCountLimit) {
196         ipcLimit->mqFailedCount++;
197         SCHEDULER_UNLOCK(intSave);
198         return EINVAL;
199     }
200 
201     run->limitStat.mqCount++;
202     ipcLimit->mqCount++;
203     SCHEDULER_UNLOCK(intSave);
204     return LOS_OK;
205 }
206 
OsIPCLimitMqFree(VOID)207 VOID OsIPCLimitMqFree(VOID)
208 {
209     UINT32 intSave;
210     SCHEDULER_LOCK(intSave);
211     LosProcessCB *run = OsCurrProcessGet();
212     ProcIPCLimit *ipcLimit = (ProcIPCLimit *)run->plimits->limitsList[PROCESS_LIMITER_ID_IPC];
213     ipcLimit->mqCount--;
214     run->limitStat.mqCount--;
215     SCHEDULER_UNLOCK(intSave);
216     return;
217 }
218 
OsIPCLimitShmAlloc(UINT32 size)219 UINT32 OsIPCLimitShmAlloc(UINT32 size)
220 {
221     UINT32 intSave;
222     SCHEDULER_LOCK(intSave);
223     LosProcessCB *run = OsCurrProcessGet();
224     ProcIPCLimit *ipcLimit = (ProcIPCLimit *)run->plimits->limitsList[PROCESS_LIMITER_ID_IPC];
225     if ((ipcLimit->shmSize + size) >= ipcLimit->shmSizeLimit) {
226         ipcLimit->shmFailedCount++;
227         SCHEDULER_UNLOCK(intSave);
228         return EINVAL;
229     }
230 
231     run->limitStat.shmSize += size;
232     ipcLimit->shmSize += size;
233     SCHEDULER_UNLOCK(intSave);
234     return LOS_OK;
235 }
236 
OsIPCLimitShmFree(UINT32 size)237 VOID OsIPCLimitShmFree(UINT32 size)
238 {
239     UINT32 intSave;
240     SCHEDULER_LOCK(intSave);
241     LosProcessCB *run = OsCurrProcessGet();
242     ProcIPCLimit *ipcLimit = (ProcIPCLimit *)run->plimits->limitsList[PROCESS_LIMITER_ID_IPC];
243     ipcLimit->shmSize -= size;
244     run->limitStat.shmSize -= size;
245     SCHEDULER_UNLOCK(intSave);
246     return;
247 }
248 
249 #endif
250