]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - tools/perf/builtin-script.c
Merge tag 'tegra-for-3.8-fixes-for-rc1' of git://git.kernel.org/pub/scm/linux/kernel...
[karo-tx-linux.git] / tools / perf / builtin-script.c
index fb9625083a2ed6d9d4bd25b94bc306895f18d6fc..b363e7b292b26fa2ff41bd5a86977ec8a7f8e3c4 100644 (file)
@@ -520,8 +520,8 @@ static struct perf_tool perf_script = {
        .sample          = process_sample_event,
        .mmap            = perf_event__process_mmap,
        .comm            = perf_event__process_comm,
-       .exit            = perf_event__process_task,
-       .fork            = perf_event__process_task,
+       .exit            = perf_event__process_exit,
+       .fork            = perf_event__process_fork,
        .attr            = perf_event__process_attr,
        .event_type      = perf_event__process_event_type,
        .tracing_data    = perf_event__process_tracing_data,
@@ -1029,6 +1029,68 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
        exit(0);
 }
 
+/*
+ * Some scripts specify the required events in their "xxx-record" file,
+ * this function will check if the events in perf.data match those
+ * mentioned in the "xxx-record".
+ *
+ * Fixme: All existing "xxx-record" are all in good formats "-e event ",
+ * which is covered well now. And new parsing code should be added to
+ * cover the future complexing formats like event groups etc.
+ */
+static int check_ev_match(char *dir_name, char *scriptname,
+                       struct perf_session *session)
+{
+       char filename[MAXPATHLEN], evname[128];
+       char line[BUFSIZ], *p;
+       struct perf_evsel *pos;
+       int match, len;
+       FILE *fp;
+
+       sprintf(filename, "%s/bin/%s-record", dir_name, scriptname);
+
+       fp = fopen(filename, "r");
+       if (!fp)
+               return -1;
+
+       while (fgets(line, sizeof(line), fp)) {
+               p = ltrim(line);
+               if (*p == '#')
+                       continue;
+
+               while (strlen(p)) {
+                       p = strstr(p, "-e");
+                       if (!p)
+                               break;
+
+                       p += 2;
+                       p = ltrim(p);
+                       len = strcspn(p, " \t");
+                       if (!len)
+                               break;
+
+                       snprintf(evname, len + 1, "%s", p);
+
+                       match = 0;
+                       list_for_each_entry(pos,
+                                       &session->evlist->entries, node) {
+                               if (!strcmp(perf_evsel__name(pos), evname)) {
+                                       match = 1;
+                                       break;
+                               }
+                       }
+
+                       if (!match) {
+                               fclose(fp);
+                               return -1;
+                       }
+               }
+       }
+
+       fclose(fp);
+       return 0;
+}
+
 /*
  * Return -1 if none is found, otherwise the actual scripts number.
  *
@@ -1039,17 +1101,23 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
 int find_scripts(char **scripts_array, char **scripts_path_array)
 {
        struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
-       char scripts_path[MAXPATHLEN];
+       char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
        DIR *scripts_dir, *lang_dir;
-       char lang_path[MAXPATHLEN];
+       struct perf_session *session;
        char *temp;
        int i = 0;
 
+       session = perf_session__new(input_name, O_RDONLY, 0, false, NULL);
+       if (!session)
+               return -1;
+
        snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());
 
        scripts_dir = opendir(scripts_path);
-       if (!scripts_dir)
+       if (!scripts_dir) {
+               perf_session__delete(session);
                return -1;
+       }
 
        for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
                snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
@@ -1077,10 +1145,18 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
                        snprintf(scripts_array[i],
                                (temp - script_dirent.d_name) + 1,
                                "%s", script_dirent.d_name);
+
+                       if (check_ev_match(lang_path,
+                                       scripts_array[i], session))
+                               continue;
+
                        i++;
                }
+               closedir(lang_dir);
        }
 
+       closedir(scripts_dir);
+       perf_session__delete(session);
        return i;
 }
 
@@ -1175,7 +1251,6 @@ static int have_cmd(int argc, const char **argv)
 int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
 {
        bool show_full_info = false;
-       const char *input_name = NULL;
        char *rec_script_path = NULL;
        char *rep_script_path = NULL;
        struct perf_session *session;