• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  *    conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12  *    of conditions and the following disclaimer in the documentation and/or other materials
13  *    provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16  *    to endorse or promote products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "fcntl.h"
33 #include "user_copy.h"
34 #include "sys/ioctl.h"
35 #include "fs/driver.h"
36 #include "los_dev_perf.h"
37 #include "los_perf.h"
38 #include "los_init.h"
39 
40 #define PERF_DRIVER "/dev/perf"
41 #define PERF_DRIVER_MODE 0666
42 
43 /* perf ioctl */
44 #define PERF_IOC_MAGIC     'T'
45 #define PERF_START         _IO(PERF_IOC_MAGIC, 1)
46 #define PERF_STOP          _IO(PERF_IOC_MAGIC, 2)
47 
PerfOpen(struct file * filep)48 static int PerfOpen(struct file *filep)
49 {
50     (void)filep;
51     return 0;
52 }
53 
PerfClose(struct file * filep)54 static int PerfClose(struct file *filep)
55 {
56     (void)filep;
57     return 0;
58 }
59 
PerfRead(struct file * filep,char * buffer,size_t buflen)60 static ssize_t PerfRead(struct file *filep, char *buffer, size_t buflen)
61 {
62     /* perf record buffer read */
63     (void)filep;
64     int ret;
65     int realLen;
66 
67     char *records = LOS_MemAlloc(m_aucSysMem0, buflen);
68     if (records == NULL) {
69         return -ENOMEM;
70     }
71 
72     realLen = LOS_PerfDataRead(records, buflen); /* get sample data */
73     if (realLen == 0) {
74         PRINT_ERR("Perf read failed, check whether perf is configured to sample mode.\n");
75         ret = -EINVAL;
76         goto EXIT;
77     }
78 
79     ret = LOS_CopyFromKernel((void *)buffer, buflen, (void *)records, realLen);
80     if (ret != 0) {
81         ret = -EINVAL;
82         goto EXIT;
83     }
84 
85     ret = realLen;
86 EXIT:
87     LOS_MemFree(m_aucSysMem0, records);
88     return ret;
89 }
90 
PerfConfig(struct file * filep,const char * buffer,size_t buflen)91 static ssize_t PerfConfig(struct file *filep, const char *buffer, size_t buflen)
92 {
93     (void)filep;
94     int ret;
95     PerfConfigAttr attr = {0};
96     int attrlen = sizeof(PerfConfigAttr);
97 
98     if (buflen != attrlen) {
99         PRINT_ERR("PerfConfigAttr is %d bytes not %d\n", attrlen, buflen);
100         return -EINVAL;
101     }
102 
103     ret = LOS_CopyToKernel(&attr, attrlen, buffer, buflen);
104     if (ret != 0) {
105         return -EINVAL;
106     }
107 
108     ret = LOS_PerfConfig(&attr);
109     if (ret != LOS_OK) {
110         PRINT_ERR("perf config error %u\n", ret);
111         return -EINVAL;
112     }
113 
114     return 0;
115 }
116 
PerfIoctl(struct file * filep,int cmd,unsigned long arg)117 static int PerfIoctl(struct file *filep, int cmd, unsigned long arg)
118 {
119     (void)filep;
120     switch (cmd) {
121         case PERF_START:
122             LOS_PerfStart((UINT32)arg);
123             break;
124         case PERF_STOP:
125             LOS_PerfStop();
126             break;
127         default:
128             PRINT_ERR("Unknown perf ioctl cmd:%d\n", cmd);
129             return -EINVAL;
130     }
131     return 0;
132 }
133 
134 static const struct file_operations_vfs g_perfDevOps = {
135     PerfOpen,        /* open */
136     PerfClose,       /* close */
137     PerfRead,        /* read */
138     PerfConfig,      /* write */
139     NULL,            /* seek */
140     PerfIoctl,       /* ioctl */
141     NULL,            /* mmap */
142 #ifndef CONFIG_DISABLE_POLL
143     NULL,            /* poll */
144 #endif
145     NULL,            /* unlink */
146 };
147 
DevPerfRegister(void)148 int DevPerfRegister(void)
149 {
150     return register_driver(PERF_DRIVER, &g_perfDevOps, PERF_DRIVER_MODE, 0); /* 0666: file mode */
151 }
152 
153 LOS_MODULE_INIT(DevPerfRegister, LOS_INIT_LEVEL_KMOD_EXTENDED);
154