From: Vyacheslav Cherkashin Date: Wed, 10 Jun 2015 10:42:19 +0000 (+0300) Subject: [FEATURE] native setup profiling implement X-Git-Tag: submit/tizen/20151105.065919~76^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8802159464660d187b3a18e66d5a415bf5bf0415;p=platform%2Fcore%2Fsystem%2Fswap-manager.git [FEATURE] native setup profiling implement Change-Id: If7945d80108486b0d943790798fc6cb7cf61ea44 Signed-off-by: Vyacheslav Cherkashin --- diff --git a/daemon/Makefile b/daemon/Makefile index a6c0cf1..abbf69d 100644 --- a/daemon/Makefile +++ b/daemon/Makefile @@ -84,6 +84,7 @@ SRC_CPP := \ cpp/features/feature_manager.cpp \ cpp/features/feature_manager_c.cpp \ cpp/features/feature_wsp.cpp \ + cpp/features/feature_nsp.cpp \ \ cpp/inst/AppInst.cpp \ cpp/inst/AppInstCont.cpp @@ -104,9 +105,11 @@ all: debug GENERATED_DIR = include/generated GENERATED_WSI_PROF_H = include/generated/wsi_prof.h GENERATED_WSP_H = include/generated/wsp_data.h +GENERATED_NSP_H = include/generated/nsp_data.h GENERATED_HEADERS := \ $(GENERATED_WSI_PROF_H) \ - $(GENERATED_WSP_H) + $(GENERATED_WSP_H) \ + $(GENERATED_NSP_H) $(GENERATED_WSI_PROF_H): ../scripts/gen_wsi_prof.sh sh $< > $@ @@ -114,6 +117,9 @@ $(GENERATED_WSI_PROF_H): ../scripts/gen_wsi_prof.sh $(GENERATED_WSP_H): ../scripts/gen_wsp_data.sh sh $< > $@ +$(GENERATED_NSP_H): ../scripts/gen_nsp_data.sh + sh $< > $@ + $(GENERATED_DIR): mkdir -p $(GENERATED_DIR) diff --git a/daemon/cpp/common.h b/daemon/cpp/common.h index 2e9b1b9..1e3feea 100644 --- a/daemon/cpp/common.h +++ b/daemon/cpp/common.h @@ -30,6 +30,13 @@ #include +static inline std::string int2str(int val) +{ + std::stringstream ss; + ss << val; + return ss.str(); +} + static inline std::string addr2hex(unsigned long val) { std::stringstream ss; diff --git a/daemon/cpp/features/feature_manager_c.cpp b/daemon/cpp/features/feature_manager_c.cpp index 38d3b10..1722fd9 100644 --- a/daemon/cpp/features/feature_manager_c.cpp +++ b/daemon/cpp/features/feature_manager_c.cpp @@ -24,6 +24,7 @@ #include "feature_manager_c.h" #include "feature_manager.h" +#include "inst/AppInstCont.h" #include "debug.h" @@ -94,7 +95,9 @@ extern "C" int fm_stop(void) extern "C" int fm_set(uint64_t f0, uint64_t f1) { /* fill actual features (f0_support and f1_support) */ - const uint64_t f0_support = f0 & (FL_WEB_STARTUP_PROFILING); + const uint64_t f0_support = f0 & (FL_WEB_STARTUP_PROFILING | + FL_APP_STARTUP + ); const uint64_t f1_support = f1 & (0); std::string f(u64toString(f1_support) + u64toString(f0_support)); @@ -105,3 +108,38 @@ extern "C" int fm_set(uint64_t f0, uint64_t f1) return 0; } + +static AppType to_apptype(uint32_t val) +{ + switch (val) { + case APP_TYPE_TIZEN: + return AT_TIZEN; + case APP_TYPE_RUNNING: + return AT_RUNNING; + case APP_TYPE_COMMON: + return AT_COMMON; + case APP_TYPE_WEB: + return AT_WEB; + } + + return AT_UNKNOWN; +} + + +extern "C" int fm_app_add(uint32_t app_type, const char *id, const char *path, + const void *data, size_t size) +{ + ByteArray ba(size); + memcpy(ba.data(), data, size); + + int ret = AppInstCont::instance().add(to_apptype(app_type), id, path, ba); + if (ret) + LOGE("add app error, ret=%d\n", ret); + + return ret; +} + +extern "C" void fm_app_clear(void) +{ + AppInstCont::instance().clear(); +} diff --git a/daemon/cpp/features/feature_manager_c.h b/daemon/cpp/features/feature_manager_c.h index 2080043..c3cbf22 100644 --- a/daemon/cpp/features/feature_manager_c.h +++ b/daemon/cpp/features/feature_manager_c.h @@ -29,6 +29,7 @@ extern "C" { #include +#include int fm_init(void); @@ -39,6 +40,10 @@ int fm_stop(void); int fm_set(uint64_t f0, uint64_t f1); +int fm_app_add(uint32_t app_type, const char *id, const char *path, + const void *data, size_t size); +void fm_app_clear(void); + #ifdef __cplusplus } diff --git a/daemon/cpp/features/feature_nsp.cpp b/daemon/cpp/features/feature_nsp.cpp new file mode 100644 index 0000000..67ea720 --- /dev/null +++ b/daemon/cpp/features/feature_nsp.cpp @@ -0,0 +1,176 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) Samsung Electronics, 2015 + * + * 2015 Vyacheslav Cherkashin + * + */ + + +#include +#include +#include +#include "feature.h" +#include "feature_manager.h" + +#include "common.h" +#include "utils.h" +#include "debug.h" +#include "nsp_data.h" /* auto generate */ +#include "inst/AppInstTizen.h" +#include "inst/AppInstCont.h" + + +static const char path_enabled[] = "/sys/kernel/debug/swap/nsp/enabled"; +static const char path_cmd[] = "/sys/kernel/debug/swap/nsp/cmd"; + + +enum { + CB_OFFSET_CRAEATE = offsetof(struct appcore_ops, create), + CB_OFFSET_RESET = offsetof(struct appcore_ops, reset) +}; + + +static int addApp(const AppInstTizen &app) +{ + std::string cmd("a " + app.info().path()); + + int ret = write_to_file(path_cmd, cmd); + if (ret < 0) { + LOGE("write to file '%s', cmd=%s\n", path_cmd, cmd.c_str()); + return ret; + } + + return 0; +} + +static int rmAppAll() +{ + int ret = write_to_file(path_cmd, "c"); + + return ret > 0 ? 0 : ret; +} + +static void funcInst(const AppInstTizen &app, int &ret) +{ + if (ret) + return; + + ret = addApp(app); +} + +static int instApps() +{ + int ret = 0; + + AppInstCont::instance().for_each(funcInst, ret); + if (ret) { + int err = rmAppAll(); + if (err) + LOGE("cannot all apps remove, err=%d\n", err); + } + + return ret; +} + +static int nspEnable() +{ + int ret = write_to_file(path_enabled, "1"); + if (ret < 0) { + LOGE("cannot NSP enable\n"); + return ret; + } + + return 0; +} + +static int nspDisable() +{ + int ret = write_to_file(path_enabled, "0"); + if (ret < 0) { + LOGE("cannot NSP enable\n"); + return ret; + } + + return 0; +} + +class FeatureNSP : public Feature +{ + int doInit() + { + int ret; + std::string cmd; + + cmd = "s offset_create " + int2str(CB_OFFSET_CRAEATE); + ret = write_to_file(path_cmd, cmd); + if (ret < 0) { + LOGE("write to file '%s', cmd=%s\n", path_cmd, cmd.c_str()); + return ret; + } + + cmd = "s offset_reset " + int2str(CB_OFFSET_RESET); + ret = write_to_file(path_cmd, cmd); + if (ret < 0) { + LOGE("write to file '%s', cmd=%s\n", path_cmd, cmd.c_str()); + return ret; + } + + cmd = "b " + addr2hex(ADDR_DLOPEN_PLT_LPAD) + ":" + + addr2hex(ADDR_DLSYM_PLT_LPAD) + ":" + PATH_LAUNCHPAD; + ret = write_to_file(path_cmd, cmd); + if (ret < 0) { + LOGE("write to file '%s', cmd=%s\n", path_cmd, cmd.c_str()); + return ret; + } + + cmd = "l " + addr2hex(ADDR_APPCORE_EFL_MAIN) + ":" + PATH_LIBAPPCORE_EFL; + ret = write_to_file(path_cmd, cmd); + if (ret < 0) { + LOGE("write to file '%s', cmd=%s\n", path_cmd, cmd.c_str()); + return ret; + } + + return 0; + } + + int doEnable() + { + int ret = instApps(); + if (ret) + LOGE("cannot all apps install\n"); + + ret = nspEnable(); + + return ret; + } + + int doDisable() + { + nspDisable(); + + int ret = rmAppAll(); + if (ret) + LOGE("cannot all apps remove, ret=%d\n", ret); + + return ret; + } + + std::string _data; +}; + + +REGISTER_FEATURE(FeatureNSP, val2bit(FL_APP_STARTUP), "NSP"); diff --git a/daemon/da_protocol.c b/daemon/da_protocol.c index 730f43a..5af277d 100644 --- a/daemon/da_protocol.c +++ b/daemon/da_protocol.c @@ -511,6 +511,7 @@ int check_running_status(const struct prof_session_t *prof_session) static void reset_app_inst(struct user_space_inst_t *us_inst) { + fm_app_clear(); free_data_list((struct data_list_t **)&us_inst->app_inst_list); us_inst->app_num = 0; us_inst->app_inst_list = NULL; diff --git a/daemon/da_protocol.h b/daemon/da_protocol.h index 5882977..e15a852 100644 --- a/daemon/da_protocol.h +++ b/daemon/da_protocol.h @@ -241,6 +241,11 @@ struct app_info_t { uint32_t app_type; char *app_id; char *exe_path; + + struct { + size_t size; + char data[8]; + } setup_data; }; diff --git a/daemon/da_protocol_inst.c b/daemon/da_protocol_inst.c index e9b7d11..dd5e0ae 100644 --- a/daemon/da_protocol_inst.c +++ b/daemon/da_protocol_inst.c @@ -30,6 +30,7 @@ #include "da_inst.h" #include "da_protocol_check.h" #include "ld_preload_probe_lib.h" +#include "cpp/features/feature_manager_c.h" //----------------- hash static uint32_t calc_lib_hash(struct us_lib_inst_t *lib) @@ -286,6 +287,37 @@ int parse_lib_inst_list(struct msg_buf_t *msg, return 1; } +static int parse_inst_app_setup_data(struct msg_buf_t *msg, + struct app_info_t *app_info) +{ + switch (app_info->app_type) { + case APP_TYPE_TIZEN: { + void *data = msg->cur_pos; + enum { data_len = 8 }; + uint64_t val; + + /* skip 8 bytes */ + if (!parse_int64(msg, &val)) { + LOGE("main address parsing error\n"); + return -EINVAL; + } + + app_info->setup_data.size = data_len; + memcpy(app_info->setup_data.data, data, data_len); + return 0; + } + case APP_TYPE_RUNNING: + case APP_TYPE_COMMON: + case APP_TYPE_WEB: + app_info->setup_data.size = 0; + return 0; + default: + return -EINVAL; + } + + return 0; +} + int parse_inst_app(struct msg_buf_t *msg, struct app_list_t **dest) { int res = 1; @@ -331,6 +363,11 @@ int parse_inst_app(struct msg_buf_t *msg, struct app_list_t **dest) goto exit_free_err; } + if (parse_inst_app_setup_data(msg, app_info)) { + LOGE("setup data parsing error\n"); + goto exit_free_err; + } + (*dest)->size += (end - start) + sizeof((*dest)->func_num); (*dest)->hash = calc_app_hash(app_info); goto exit; @@ -357,12 +394,24 @@ int parse_app_inst_list(struct msg_buf_t *msg, parse_deb("app_int_num = %d\n", *num); for (i = 0; i < *num; i++) { + int err; + struct app_info_t *info; + parse_deb("app_int #%d\n", i); if (!parse_inst_app(msg, &app)) { // TODO maybe need free allocated memory up there LOGE("parse is inst app #%d failed\n", i + 1); return 0; } + + info = app->app; + err = fm_app_add(info->app_type, info->app_id, info->exe_path, + info->setup_data.data, info->setup_data.size); + if (err) { + LOGE("add app, ret=%d\n", err); + return 0; + } + data_list_append((struct data_list_t **)app_list, (struct data_list_t *)app); } diff --git a/packaging/swap-manager.spec b/packaging/swap-manager.spec index 1368657..75409e8 100644 --- a/packaging/swap-manager.spec +++ b/packaging/swap-manager.spec @@ -18,6 +18,9 @@ BuildRequires: pkgconfig(ecore) BuildRequires: swap-probe-devel BuildRequires: webkit2-efl BuildRequires: webkit2-efl-debuginfo +BuildRequires: launchpad +BuildRequires: app-core-efl +BuildRequires: app-core-common-devel %if "%_project" != "Kirana_SWA_OPEN:Build" && "%_project" != "Kirana_SWA_OPEN:Daily" Requires: swap-modules %endif diff --git a/scripts/gen_nsp_data.sh b/scripts/gen_nsp_data.sh new file mode 100755 index 0000000..0243655 --- /dev/null +++ b/scripts/gen_nsp_data.sh @@ -0,0 +1,80 @@ +#!/bin/bash + + +gen_define() +{ + name=$1 + val=$2 + + echo "#define $name $val" +} + +gen_define_str() +{ + name=$1 + val=$2 + + echo "#define $name \"$val\"" +} + +check_null_or_exit() +{ + name=$1 + val=${!1} + src=$BASH_SOURCE + line=$BASH_LINENO + + if [ -z "$val" ]; then + echo "$src:$line ERROR: value '$name' is null" >&2 + exit 1 + fi +} + +# get appcore_efl_main addr +path_app_core_efl=$(rpm -ql app-core-efl | grep libappcore-efl | head -1) +check_null_or_exit path_app_core_efl + +addr_appcore_efl_main=$(readelf -s ${path_app_core_efl} | grep appcore_efl_main | awk '{print $2}' | head -1) +check_null_or_exit addr_appcore_efl_main + +# get dlopen@plt and dlsym@plt addrs +path_launchpad=$(rpm -ql launchpad | grep launchpad-loader | head -1) +path_launchpad=${path_launchpad:-$(rpm -ql launchpad | grep launchpad-process-pool | head -1)} +check_null_or_exit path_launchpad + +tmp=$(mktemp) +su root -c "objdump -d --section=.plt $path_launchpad" | grep ">:" > $tmp +addr_dlopen_plt=$(cat $tmp | grep " /sys/kernel/debug/swap/enable +rmmod swap_nsp rmmod swap_wsp rmmod swap_preload rmmod swap_task_data