• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# plimits
2
3## Overview
4
5The complexity of app environments and growing number of processes will cause contention and waste of resources if restrictions are applied on containers. Process Limits (plimits) is a mechanism provided by the kernel to limit the resources used by a single process or multiple processes. It can implement refined control on resources such as CPUs and memory.
6
7plimitsfs is a file system that provides an interface for creating and deleting plimits. plimitsfs enables processes and process resources to be grouped for management through operations on files. Plimiters are configured to restrict the usage of resources, such as memory and sched, in process groups.
8
9## Basic Concepts
10
11- plimits: a feature provided by the kernel to limit, record, and isolate the resources used by a group of processes.
12- plimitsfs: a file system, which provides an interface for users to create and delete plimits and displays the plimits directories.
13- plimiter: a collection of resource limiters. plimiter includes the memory limiter, pids limiter, and sched limiter.
14- sched limiter: limits the time to use CPUs for all processes in a plimits group in a specified period.
15- memory limiter: limits the total memory that can be used by all processes in a plimits group.
16- pids limiter: limits the maximum number of processes that can be mounted in a plimits group.
17
18## Working Principles
19
20During the system initialization process, the **plimits** directory is mounted to the **proc** directory.
21
22```
23├─proc
24│  ├─plimits
25│  │  ├─plimits.plimiter_add
26│  │  ├─plimits.plimiter_delete
27│  │  ├─plimits.procs
28│  │  ├─plimits.limiters
29│  │  ├─pids.max
30│  │  ├─sched.period
31│  │  ├─sched.quota
32│  │  ├─sched.stat
33│  │  ├─memory.failcnt
34│  │  ├─memory.limit
35│  │  ├─memory.peak
36│  │  ├─memory.usage
37│  │  ├─memory.oom_ctrl
38│  │  └─memory.stat
39```
40
41- plimits groups
42
43  **Figure 1** Creating or deleting plimits
44
45  ![](figures/create_delete_plimits.png)
46
47- sched limiter
48
49  **Figure 2** sched limiter configuration
50
51  ![](figures/sched_limiter.png)
52
53- Memory limiter
54
55  **Figure 3** Memory limiter configuration
56
57  ![](figures/memory_limiter.png)
58
59- pids limiter
60
61  **Figure 4** pids limiter configuration
62
63  ![](figures/pids_limiter.png)
64
65
66## How to Develop
67
68
69### Available APIs
70
71The plimits root directory of LiteOS-A is in **/proc/plimits**. All files in this directory are read-only. The values setting in the limiter file are maximum values by default. You can view the status of process resources in the group from the files.
72Run the **mkdir** command to create a **plimitsA** directory to group process resources and restrict resource allocation. The created **plimitsA** directory inherits its parent **plimits** directory.
73
74The following table lists the files in the **plimitsA** directory.
75
76| Permissions | Size| User| User Group|         File        | Description|
77| --------- | ---- | ---- | ------ | ---------------------- | --------- |
78|-r--r--r-- | 0    | u:0  | g:0    | sched.stat             | Time slice of each thread in the last period. The time slice information is used for test and verification.|
79|-rw-r--r-- | 0    | u:0  | g:0    | sched.quota            | Sum of time slices of all processes in a group in a period, in ns.|
80|-rw-r--r-- | 0    | u:0  | g:0    | sched.period           | Statistical period of the time slice, in ns.|
81|-r--r--r-- | 0    | u:0  | g:0    | memory.stat            | Memory usage statistics, in bytes.|
82|-r--r--r-- | 0    | u:0  | g:0    | memory.usage           | Memory quota used, in bytes.|
83|-r--r--r-- | 0    | u:0  | g:0    | memory.peak            | Historical peak memory usage, in bytes.|
84|-rw-r--r-- | 0    | u:0  | g:0    | memory.limit           | Memory usage limit, in bytes.|
85|-r--r--r-- | 0    | u:0  | g:0    | memory.failcnt         | Number of memory allocation failures when the memory usage exceeds the limit.|
86|-rw-r--r-- | 0    | u:0  | g:0    | pids.max               | Maximum number of processes that can be mounted to a group.|
87|-rw-r--r-- | 0    | u:0  | g:0    | plimits.procs          | All processes mounted to a group.|
88|-rw-r--r-- | 0    | u:0  | g:0    | plimits.limiter_delete | Used to delete a limiter. |
89|-rw-r--r-- | 0    | u:0  | g:0    | plimits.limiter_add    | Used to add a limiter. |
90|-r--r--r-- | 0    | u:0  | g:0    | plimits.limiters       | Used to view the limiters of a group. |
91
92All the files in the **plimitsA** directory in **/proc/plimits/** are readable, and some are writable. You can allocate and restrict process resources by writing data to the files in the **plimitsA** directory. You can:
93- Write time, in ns, to the **sched.quota** file to limit the time for all processes in the group to use CPUs.
94- Write time, in ns, to the **sched.period** file to set the period for collecting statistics in a group.
95- Write the memory, in bytes, to the **memory.limit** file to limit the memory that can be used by a group.
96- Write a decimal number to the **pids.max** file to limit the number of processes that can be mounted to a group.
97- Write process IDs (PIDs) to the **plimits.procs** file to mount processes to different plimits groups.
98- Read files to view the resource usage configuration of a group.
99
100#### Deleting the **plimitsA** Group
101
102Write **sched**, **memory**, and **pids** to the **/proc/plimits/plimitsA/plimits.limiter_delete** file in sequence to delete the limiters, and then run the **rmdir** command to delete **plimitsA**.
103
104|    Permissions  |   Size |  User | User Group|         File         |
105| --------- | ------- | ------ | ------ | ----------------------- |
106|-rw-r--r-- | 0       | u:0    | g:0    | plimits.procs           |
107|-rw-r--r-- | 0       | u:0    | g:0    | plimits.limiter_delete  |
108|-rw-r--r-- | 0       | u:0    | g:0    | plimits.limiter_add     |
109|-r--r--r-- | 0       | u:0    | g:0    | plimits.limiters        |
110
111### How to Develop
112
1131. Create **plimitsA** and write PIDs to **/plimitsA/plimits.procs** to group process resources.
1142. Write the **/plimitsA/memory.limit** file to limit the maximum memory that can be used by the **plimitsA** group.
1153. Write a decimal number to the **/plimitsA/pids.max** file to limit the number of processes that can be mounted to the **plimitsA** group.
1164. Configure the limiter files in the **plimitsA** group to allocate and limit resources. If you do not want to limit the use of resources, delete **plimitsA**.
117
118### Development Example
119
120The following example demonstrates how to create the **plimitsA** group and implement resource control of this group by reading and writing the files of **plimitsA**.
121
122```
123#include <stdio.h>
124#include <unistd.h>
125#include <stdlib.h>
126#include <string.h>
127#include <sys/types.h>
128#include <sys/stat.h>
129#include <fcntl.h>
130
131#define LOS_OK 0
132#define LOS_NOK -1
133
134int main ()
135{
136    int ret;
137    ssize_t len;
138    int fd = -1;
139    //get main pid
140    int mainpid = getpid();
141    char plimitsA[128] = "/proc/plimits/plimitsA";
142    char plimitsAPids[128] = "/proc/plimits/plimitsA/pids.max";
143    char plimitsAMemoryLimit[128] = "/proc/plimits/plimitsA/memory.limit";
144    char plimitsAMemoryUsage[128] = "/proc/plimits/plimitsA/memory.usage";
145    char plimitsAProcs[128] = "/proc/plimits/plimitsA/plimits.procs";
146    char plimitsAAdd[128] = "/proc/plimits/plimitsA/plimits.limiter_add";
147    char plimitsADelete[128] = "/proc/plimits/plimitsA/plimits.limiter_delete";
148    char plimitsMem[128] = "/proc/plimits/memory.usage";
149    char plimitsPid[128] = "/proc/plimits/plimits.procs";
150    char *mem = NULL;
151    char writeBuf[128];
152    char readBuf[128];
153
154    /* Check the processes in the plimits group. */
155    memset(readBuf, 0, sizeof(readBuf));
156    fd = open(plimitsPid, O_RDONLY);
157    len = read(fd, readBuf, sizeof(readBuf));
158    if (len != strlen(readBuf)) {
159        printf("read file failed.\n");
160        return LOS_NOK;
161    }
162    close(fd);
163    printf ("Processes in /proc/plimits: %s\n," readBuf);
164
165    /* Check the memory usage of the plimits group. */
166    memset(readBuf, 0, sizeof(readBuf));
167    fd = open(plimitsMem, O_RDONLY);
168    len = read(fd, readBuf, sizeof(readBuf));
169    if (len != strlen(readBuf)) {
170        printf("read file failed.\n");
171        return LOS_NOK;
172    }
173    close(fd);
174    printf ("Memory used in /proc/plimits: %s\n," readBuf);
175
176
177    /* Create plimitsA "/proc/plimits/plimitsA". */
178    ret = mkdir(plimitsA, 0777);
179    if (ret != LOS_OK) {
180        printf("mkdir failed.\n");
181        return LOS_NOK;
182    }
183
184    /* Set the number of processes that can be mounted to the plimitsA group. */
185    memset(writeBuf, 0, sizeof(writeBuf));
186    sprintf(writeBuf, "%d", 3);
187    fd = open(plimitsAPids, O_WRONLY);
188    len = write(fd, writeBuf, strlen(writeBuf));
189    if (len != strlen(writeBuf)) {
190        printf("write file failed.\n");
191        return LOS_NOK;
192    }
193    close(fd);
194
195    /* Mount processes to the plimitsA group. */
196    memset(writeBuf, 0, sizeof(writeBuf));
197    sprintf(writeBuf, "%d", mainpid);
198    fd = open(plimitsAProcs, O_WRONLY);
199    len = write(fd, writeBuf, strlen(writeBuf));
200    if (len != strlen(writeBuf)) {
201        printf("write file failed.\n");
202        return LOS_NOK;
203    }
204    close(fd);
205
206    /* Set the memory allocation limit in the plimitsA group. */
207    memset(writeBuf, 0, sizeof(writeBuf));
208    //limit memory
209    sprintf(writeBuf, "%d", (1024*1024*3));
210    fd = open(plimitsAMemoryLimit, O_WRONLY);
211    len = write(fd, writeBuf, strlen(writeBuf));
212    if (len != strlen(writeBuf)) {
213        printf("write file failed.\n");
214        return LOS_NOK;
215    }
216    close(fd);
217
218    /* Check the maximum memory that can be used in the plimitsA group. */
219    memset(readBuf, 0, sizeof(readBuf));
220    fd = open(plimitsAMemoryLimit, O_RDONLY);
221    len = read(fd, readBuf, sizeof(readBuf));
222    if (len != strlen(readBuf)) {
223        printf("read file failed.\n");
224        return LOS_NOK;
225    }
226    close(fd);
227    printf ("Maximum memory allowed for /proc/plimits/plimitsA: %s\n," readBuf);
228
229    /* Check the processes mounted to the plimitsA group. */
230    memset(readBuf, 0, sizeof(readBuf));
231    fd = open(plimitsAProcs, O_RDONLY);
232    len = read(fd, readBuf, sizeof(readBuf));
233    if (len != strlen(readBuf)) {
234        printf("read file failed.\n");
235        return LOS_NOK;
236    }
237    close(fd);
238    printf ("Process mounted to /proc/plimits/plimitsA: %s\n," readBuf);
239
240    /* Check the memory usage of the plimitsA group. */
241    mem = (char*)malloc(1024*1024);
242    memset(mem, 0, 1024);
243    memset(readBuf, 0, sizeof(readBuf));
244    fd = open(plimitsAMemoryUsage, O_RDONLY);
245    len = read(fd, readBuf, sizeof(readBuf));
246    if (len != strlen(readBuf)) {
247        printf("read file failed.\n");
248        return LOS_NOK;
249    }
250    close(fd);
251    printf ("Memory used by /proc/plimits/plimitsA: %s\n," readBuf);
252
253    /* Delete the memory limiter for the plimitsA group. */
254    memset(writeBuf, 0, sizeof(writeBuf));
255    sprintf(writeBuf, "%s", "memory");
256    fd = open(plimitsADelete, O_WRONLY);
257    len = write(fd, writeBuf, strlen(writeBuf));
258    if (len != strlen(writeBuf)) {
259        printf("write file failed.\n");
260        return LOS_NOK;
261    }
262    close(fd);
263
264    /* Add a memory limiter to the plimitsA group. */
265    memset(writeBuf, 0, sizeof(writeBuf));
266    sprintf(writeBuf, "%s", "memory");
267    fd = open(plimitsAAdd, O_WRONLY);
268    len = write(fd, writeBuf, strlen(writeBuf));
269    if (len != strlen(writeBuf)) {
270        printf("write file failed.\n");
271        return LOS_NOK;
272    }
273    close(fd);
274
275    /* Delete the plimitsA group. You need to delete the memory, pids, and sched limiters first. */
276    memset(writeBuf, 0, sizeof(writeBuf));
277    sprintf(writeBuf, "%s", "memory");
278    fd = open(plimitsADelete, O_WRONLY);
279    len = write(fd, writeBuf, strlen(writeBuf));
280    if (len != strlen(writeBuf)) {
281        printf("write file failed.\n");
282        return LOS_NOK;
283    }
284    memset(writeBuf, 0, sizeof(writeBuf));
285    sprintf(writeBuf, "%s", "pids");
286    fd = open(plimitsADelete, O_WRONLY);
287    len = write(fd, writeBuf, strlen(writeBuf));
288
289    memset(writeBuf, 0, sizeof(writeBuf));
290    sprintf(writeBuf, "%s", "sched");
291    fd = open(plimitsADelete, O_WRONLY);
292    len = write(fd, writeBuf, strlen(writeBuf));
293    close(fd);
294    ret = rmdir(plimitsA);
295    if (ret != LOS_OK) {
296        printf("rmdir failed.\n");
297        return LOS_NOK;
298    }
299
300    return 0;
301}
302```
303
304
305### Verification
306
307The development is successful if the return result is as follows:
308
309
310```
311Processes in the /proc/plimits group:
3121
3132
3143
3154
3165
3176
3187
3198
3209
32110
32211
32312
32413
32514
32615
327
328Memory used in /proc/plimits: 28016640
329
330Maximum memory allowed for /proc/plimits/plimitsA: 3145728
331
332Process mounted to /proc/plimits/plimitsA:
33315
334
335Memory used by /proc/plimits/plimitsA: 4096
336```
337