3 * @author Ruslan Soloviev
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 * Copyright (C) Samsung Electronics, 2014
24 * @section DESCRIPTION
26 * Web application profiling
29 #include <linux/module.h>
30 #include <linux/slab.h>
31 #include <us_manager/us_manager.h>
32 #include <us_manager/pf/pf_group.h>
33 #include <us_manager/probes/probe_info_new.h>
34 #include <uprobe/swap_uprobes.h>
35 #include <parser/msg_cmd.h>
36 #include <master/swap_initializer.h>
39 #include "webprobe_debugfs.h"
42 struct web_prof_data {
43 struct dentry *app_dentry;
44 struct dentry *lib_dentry;
51 static DEFINE_MUTEX(web_mutex);
52 static const char *CHROMIUM_EWK = "/usr/lib/libchromium-ewk.so";
53 static struct web_prof_data *web_data;
55 /* function tick handler */
56 static int tick_handler(struct uprobe *p, struct pt_regs *regs);
57 static struct probe_desc pin_tick_handler = MAKE_UPROBE(tick_handler);
58 static struct probe_new tick_probe = {
59 .desc = &pin_tick_handler
62 /* function inspector port */
63 static int insport_rhandler(struct uretprobe_instance *ri,
64 struct pt_regs *regs);
65 static struct probe_desc pin_insport_rhandler =
66 MAKE_URPROBE(NULL, insport_rhandler, 0);
67 static struct probe_new insport_probe = {
68 .desc = &pin_insport_rhandler
71 static int insport_rhandler(struct uretprobe_instance *ri,
74 set_wrt_launcher_port((int)regs_return_value(regs));
79 static int tick_handler(struct uprobe *p, struct pt_regs *regs)
86 u64 *web_prof_addr_ptr(enum web_prof_addr_t type)
90 mutex_lock(&web_mutex);
92 case INSPSERVER_START:
93 addr_ptr = &web_data->inspserver_addr;
96 addr_ptr = &web_data->tick_addr;
99 pr_err("ERROR: WEB_PROF_ADDR_PTR_TYPE=0x%x\n", type);
102 mutex_unlock(&web_mutex);
107 int web_prof_data_set(char *app_path, char *app_id)
111 mutex_lock(&web_mutex);
112 web_data->app_dentry = dentry_by_path(app_path);
113 if (!web_data->app_dentry) {
118 web_data->lib_dentry = dentry_by_path(CHROMIUM_EWK);
119 if (!web_data->lib_dentry) {
125 put_pf_group(web_data->pfg);
127 web_data->pfg = get_pf_group_by_comm(app_id, web_data->app_dentry);
128 if (!web_data->pfg) {
134 mutex_unlock(&web_mutex);
139 bool web_prof_enabled(void)
143 mutex_lock(&web_mutex);
144 ret = web_data->enable;
145 mutex_unlock(&web_mutex);
150 static void __web_prof_disable(struct web_prof_data *data)
152 pin_unregister(&tick_probe, data->pfg, data->lib_dentry);
153 pin_unregister(&insport_probe, data->pfg, data->lib_dentry);
156 static int __web_prof_enable(struct web_prof_data *data)
160 tick_probe.offset = data->tick_addr;
161 ret = pin_register(&tick_probe, data->pfg, data->lib_dentry);
165 insport_probe.offset = data->inspserver_addr;
166 ret = pin_register(&insport_probe, data->pfg, data->lib_dentry);
173 pin_unregister(&tick_probe, data->pfg, data->lib_dentry);
178 int web_prof_enable(void)
182 mutex_lock(&web_mutex);
183 if (web_data->enable) {
184 pr_err("ERROR: Web profiling is already enabled\n");
189 if (!web_data->inspserver_addr) {
190 pr_err("bad inspserver addr 0x%llx\n",
191 web_data->inspserver_addr);
195 if (!web_data->tick_addr) {
196 pr_err("bad tick addr 0x%llx\n", web_data->tick_addr);
200 ret = __web_prof_enable(web_data);
202 pr_err("failed to enable Web profiling\n");
206 web_data->enable = true;
209 mutex_unlock(&web_mutex);
214 int web_prof_disable(void)
218 mutex_lock(&web_mutex);
219 if (!web_data->enable) {
220 pr_err("ERROR: Web profiling is already disabled\n");
225 __web_prof_disable(web_data);
226 web_data->enable = false;
229 mutex_unlock(&web_mutex);
233 static int webprobe_module_init(void)
235 mutex_lock(&web_mutex);
236 web_data = kzalloc(sizeof(*web_data), GFP_KERNEL);
240 web_data->enable = false;
241 mutex_unlock(&web_mutex);
246 static void webprobe_module_exit(void)
248 mutex_lock(&web_mutex);
249 if (web_data->enable)
250 __web_prof_disable(web_data);
253 put_pf_group(web_data->pfg);
257 mutex_unlock(&web_mutex);
260 SWAP_LIGHT_INIT_MODULE(NULL, webprobe_module_init, webprobe_module_exit,
261 webprobe_debugfs_init, webprobe_debugfs_exit);
263 MODULE_LICENSE("GPL");
264 MODULE_DESCRIPTION("SWAP webprobe");
265 MODULE_AUTHOR("Ruslan Soloviev <r.soloviev@samsung.com>"
266 "Anastasia Lyupa <a.lyupa@samsung.com>");