From d0254c7c0bb43c62abafdf866b16de0da1ad4d5d Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Sat, 6 Aug 2011 02:33:48 -0400 Subject: [PATCH] Add calibrate command Signed-off-by: Mathieu Desnoyers --- include/lttng-kernel.h | 8 + include/lttng/lttng.h | 14 ++ libkernelctl/kernel-ioctl.h | 2 + libkernelctl/libkernelctl.c | 5 + libkernelctl/libkernelctl.h | 1 + liblttngctl/liblttngctl.c | 16 ++ liblttsessiondcomm/liblttsessiondcomm.h | 2 + ltt-sessiond/kernel-ctl.c | 17 ++ ltt-sessiond/kernel-ctl.h | 1 + ltt-sessiond/ltt-sessiond.h | 2 +- ltt-sessiond/main.c | 64 ++++++-- lttng/Makefile.am | 2 +- lttng/cmd.h | 1 + lttng/commands/calibrate.c | 198 ++++++++++++++++++++++++ lttng/lttng.c | 2 + 15 files changed, 320 insertions(+), 15 deletions(-) create mode 100644 lttng/commands/calibrate.c diff --git a/include/lttng-kernel.h b/include/lttng-kernel.h index 9eb207bb2..95f003f2d 100644 --- a/include/lttng-kernel.h +++ b/include/lttng-kernel.h @@ -105,4 +105,12 @@ struct lttng_kernel_tracer_version { uint32_t sublevel; }; +enum lttng_kernel_calibrate_type { + LTTNG_KERNEL_CALIBRATE_KRETPROBE, +}; + +struct lttng_kernel_calibrate { + enum lttng_kernel_calibrate_type type; /* type (input) */ +}; + #endif /* _LTTNG_KERNEL_H */ diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h index eb34a7349..c08580ac2 100644 --- a/include/lttng/lttng.h +++ b/include/lttng/lttng.h @@ -90,6 +90,10 @@ enum lttng_event_context_type { LTTNG_EVENT_CONTEXT_VPPID = 9, }; +enum lttng_calibrate_type { + LTTNG_CALIBRATE_FUNCTION = 0, +}; + struct lttng_domain { enum lttng_domain_type type; union { @@ -167,6 +171,10 @@ struct lttng_channel { struct lttng_channel_attr attr; }; +struct lttng_calibrate { + enum lttng_calibrate_type type; +}; + /* * Basic session information. * @@ -333,4 +341,10 @@ extern int lttng_disable_event(struct lttng_domain *domain, const char *name, extern int lttng_disable_channel(struct lttng_domain *domain, const char *name); +/* + * Calibrate LTTng overhead. + */ +extern int lttng_calibrate(struct lttng_domain *domain, + struct lttng_calibrate *calibrate); + #endif /* _LTTNG_H */ diff --git a/libkernelctl/kernel-ioctl.h b/libkernelctl/kernel-ioctl.h index 848ecbc46..408535d43 100644 --- a/libkernelctl/kernel-ioctl.h +++ b/libkernelctl/kernel-ioctl.h @@ -54,6 +54,8 @@ _IOR(0xF6, 0x41, struct lttng_kernel_tracer_version) #define LTTNG_KERNEL_TRACEPOINT_LIST _IO(0xF6, 0x42) #define LTTNG_KERNEL_WAIT_QUIESCENT _IO(0xF6, 0x43) +#define LTTNG_KERNEL_CALIBRATE \ + _IOWR(0xF6, 0x44, struct lttng_kernel_calibrate) /* Session FD ioctl */ #define LTTNG_KERNEL_METADATA \ diff --git a/libkernelctl/libkernelctl.c b/libkernelctl/libkernelctl.c index 1f30c77c0..78b256347 100644 --- a/libkernelctl/libkernelctl.c +++ b/libkernelctl/libkernelctl.c @@ -166,3 +166,8 @@ int kernctl_wait_quiescent(int fd) { return ioctl(fd, LTTNG_KERNEL_WAIT_QUIESCENT); } + +int kernctl_calibrate(int fd, struct lttng_kernel_calibrate *calibrate) +{ + return ioctl(fd, LTTNG_KERNEL_CALIBRATE, calibrate); +} diff --git a/libkernelctl/libkernelctl.h b/libkernelctl/libkernelctl.h index 25e5d0c1b..026f58d21 100644 --- a/libkernelctl/libkernelctl.h +++ b/libkernelctl/libkernelctl.h @@ -50,5 +50,6 @@ int kernctl_stop_session(int fd); int kernctl_tracepoint_list(int fd); int kernctl_tracer_version(int fd, struct lttng_kernel_tracer_version *v); int kernctl_wait_quiescent(int fd); +int kernctl_calibrate(int fd, struct lttng_kernel_calibrate *calibrate); #endif /* _LTT_LIBKERNELCTL_H */ diff --git a/liblttngctl/liblttngctl.c b/liblttngctl/liblttngctl.c index 37e202f2c..4faf8414f 100644 --- a/liblttngctl/liblttngctl.c +++ b/liblttngctl/liblttngctl.c @@ -575,6 +575,22 @@ int lttng_set_tracing_group(const char *name) return 0; } +/* + * lttng_calibrate + */ +int lttng_calibrate(struct lttng_domain *domain, + struct lttng_calibrate *calibrate) +{ + int ret; + + copy_lttng_domain(domain); + + memcpy(&lsm.u.calibrate, calibrate, sizeof(struct lttng_calibrate)); + ret = ask_sessiond(LTTNG_CALIBRATE, NULL); + + return ret; +} + /* * lttng_check_session_daemon * diff --git a/liblttsessiondcomm/liblttsessiondcomm.h b/liblttsessiondcomm/liblttsessiondcomm.h index fa178aae1..a06bb9175 100644 --- a/liblttsessiondcomm/liblttsessiondcomm.h +++ b/liblttsessiondcomm/liblttsessiondcomm.h @@ -59,6 +59,7 @@ enum lttcomm_sessiond_command { LTTNG_LIST_TRACEPOINTS, LTTNG_START_TRACE, LTTNG_STOP_TRACE, + LTTNG_CALIBRATE, }; /* @@ -152,6 +153,7 @@ struct lttcomm_session_msg { struct { char channel_name[NAME_MAX]; } list; + struct lttng_calibrate calibrate; } u; }; diff --git a/ltt-sessiond/kernel-ctl.c b/ltt-sessiond/kernel-ctl.c index 27210708e..3dd146dd4 100644 --- a/ltt-sessiond/kernel-ctl.c +++ b/ltt-sessiond/kernel-ctl.c @@ -408,6 +408,23 @@ void kernel_wait_quiescent(int fd) } } +/* + * kernel_calibrate + */ +int kernel_calibrate(int fd, struct lttng_kernel_calibrate *calibrate) +{ + int ret; + + ret = kernctl_calibrate(fd, calibrate); + if (ret < 0) { + perror("calibrate ioctl"); + return -1; + } + + return 0; +} + + /* * kernel_metadata_flush_buffer * diff --git a/ltt-sessiond/kernel-ctl.h b/ltt-sessiond/kernel-ctl.h index 22250417d..df0cca2af 100644 --- a/ltt-sessiond/kernel-ctl.h +++ b/ltt-sessiond/kernel-ctl.h @@ -51,5 +51,6 @@ int kernel_start_session(struct ltt_kernel_session *session); int kernel_stop_session(struct ltt_kernel_session *session); ssize_t kernel_list_events(int tracer_fd, struct lttng_event **event_list); void kernel_wait_quiescent(int fd); +int kernel_calibrate(int fd, struct lttng_kernel_calibrate *calibrate); #endif /* _LTT_KERNEL_CTL_H */ diff --git a/ltt-sessiond/ltt-sessiond.h b/ltt-sessiond/ltt-sessiond.h index febc4eb12..acdc9724b 100644 --- a/ltt-sessiond/ltt-sessiond.h +++ b/ltt-sessiond/ltt-sessiond.h @@ -31,11 +31,11 @@ struct module_param { /* LTTng kernel tracer modules list */ const struct module_param kernel_modules_list[] = { - { "ltt-relay", 1 }, { "lttng-ftrace", 0 }, { "lttng-kprobes", 0 }, { "lttng-kretprobes", 0 }, { "lib-ring-buffer", 1 }, + { "ltt-relay", 1 }, { "ltt-ring-buffer-client-discard", 1 }, { "ltt-ring-buffer-client-overwrite", 1 }, { "ltt-ring-buffer-metadata-client", 1 }, diff --git a/ltt-sessiond/main.c b/ltt-sessiond/main.c index b3dc0e3a6..5636700d8 100644 --- a/ltt-sessiond/main.c +++ b/ltt-sessiond/main.c @@ -1321,6 +1321,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) case LTTNG_CREATE_SESSION: case LTTNG_LIST_SESSIONS: case LTTNG_LIST_TRACEPOINTS: + case LTTNG_CALIBRATE: break; default: DBG("Getting session %s by name", cmd_ctx->lsm->session.name); @@ -1341,7 +1342,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) } /* - * Check domain type for specifif "pre-action". + * Check domain type for specific "pre-action". */ switch (cmd_ctx->lsm->domain.type) { case LTTNG_DOMAIN_KERNEL: @@ -1355,21 +1356,27 @@ static int process_client_msg(struct command_ctx *cmd_ctx) } /* Need a session for kernel command */ - if (cmd_ctx->lsm->cmd_type != LTTNG_LIST_TRACEPOINTS && - cmd_ctx->session->kernel_session == NULL) { - - ret = create_kernel_session(cmd_ctx->session); - if (ret < 0) { - ret = LTTCOMM_KERN_SESS_FAIL; - goto error; - } - - /* Start the kernel consumer daemon */ - if (kconsumerd_pid == 0) { - ret = start_kconsumerd(); + switch (cmd_ctx->lsm->cmd_type) { + case LTTNG_CREATE_SESSION: + case LTTNG_LIST_SESSIONS: + case LTTNG_LIST_TRACEPOINTS: + case LTTNG_CALIBRATE: + break; + default: + if (cmd_ctx->session->kernel_session == NULL) { + ret = create_kernel_session(cmd_ctx->session); if (ret < 0) { + ret = LTTCOMM_KERN_SESS_FAIL; goto error; } + + /* Start the kernel consumer daemon */ + if (kconsumerd_pid == 0) { + ret = start_kconsumerd(); + if (ret < 0) { + goto error; + } + } } } break; @@ -2049,6 +2056,37 @@ static int process_client_msg(struct command_ctx *cmd_ctx) ret = LTTCOMM_OK; break; } + + case LTTNG_CALIBRATE: + { + /* Setup lttng message with no payload */ + ret = setup_lttng_msg(cmd_ctx, 0); + if (ret < 0) { + goto setup_error; + } + + switch (cmd_ctx->lsm->domain.type) { + case LTTNG_DOMAIN_KERNEL: + { + struct lttng_kernel_calibrate kcalibrate; + + kcalibrate.type = cmd_ctx->lsm->u.calibrate.type; + ret = kernel_calibrate(kernel_tracer_fd, &kcalibrate); + if (ret < 0) { + ret = LTTCOMM_KERN_ENABLE_FAIL; + goto error; + } + break; + } + default: + /* TODO: Userspace tracing */ + ret = LTTCOMM_NOT_IMPLEMENTED; + goto error; + } + ret = LTTCOMM_OK; + break; + } + default: /* Undefined command */ ret = setup_lttng_msg(cmd_ctx, 0); diff --git a/lttng/Makefile.am b/lttng/Makefile.am index 9d696aa01..8dc68e45b 100644 --- a/lttng/Makefile.am +++ b/lttng/Makefile.am @@ -8,7 +8,7 @@ lttng_SOURCES = cmd.h conf.c conf.h commands/start.c \ commands/disable_events.c commands/enable_channels.c \ commands/disable_channels.c commands/add_context.c \ commands/set_session.c commands/version.c \ - utils.c utils.h lttng.c + commands/calibrate.c utils.c utils.h lttng.c lttng_LDADD = \ $(top_builddir)/liblttngctl/liblttngctl.la diff --git a/lttng/cmd.h b/lttng/cmd.h index 85efd734a..257d0a1c4 100644 --- a/lttng/cmd.h +++ b/lttng/cmd.h @@ -49,5 +49,6 @@ extern int cmd_disable_channels(int argc, const char **argv); extern int cmd_add_context(int argc, const char **argv); extern int cmd_set_session(int argc, const char **argv); extern int cmd_version(int argc, const char **argv); +extern int cmd_calibrate(int argc, const char **argv); #endif /* _LTTNG_CMD_H */ diff --git a/lttng/commands/calibrate.c b/lttng/commands/calibrate.c new file mode 100644 index 000000000..40d1c45c2 --- /dev/null +++ b/lttng/commands/calibrate.c @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2011 - David Goulet + * Copyright (C) 2011 - Mathieu Desnoyers + * + * 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; only version 2 + * of the License. + * + * 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. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../cmd.h" +#include "../conf.h" +#include "../utils.h" + +static int opt_event_type; +static char *opt_kernel; +static char *opt_cmd_name; +static int opt_pid_all; +static int opt_userspace; +static pid_t opt_pid; + +enum { + OPT_HELP = 1, + OPT_USERSPACE, + OPT_TRACEPOINT, + OPT_MARKER, + OPT_PROBE, + OPT_FUNCTION, + OPT_FUNCTION_ENTRY, +}; + +static struct poptOption long_options[] = { + /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ + {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0}, + {"kernel", 'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0}, + {"userspace", 'u', POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, 0, OPT_USERSPACE, 0, 0}, + {"all", 0, POPT_ARG_VAL, &opt_pid_all, 1, 0, 0}, + {"pid", 'p', POPT_ARG_INT, &opt_pid, 0, 0, 0}, + {"tracepoint", 0, POPT_ARG_NONE, 0, OPT_TRACEPOINT, 0, 0}, + {"marker", 0, POPT_ARG_NONE, 0, OPT_MARKER, 0, 0}, + {"probe", 0, POPT_ARG_NONE, 0, OPT_PROBE, 0, 0}, + {"function", 0, POPT_ARG_NONE, 0, OPT_FUNCTION, 0, 0}, + {"function:entry", 0, POPT_ARG_NONE, 0, OPT_FUNCTION_ENTRY, 0, 0}, + {0, 0, 0, 0, 0, 0, 0} +}; + +/* + * usage + */ +static void usage(FILE *ofp) +{ + fprintf(ofp, "usage: lttng calibrate [options] [calibrate_options]\n"); + fprintf(ofp, "\n"); + fprintf(ofp, " -h, --help Show this help\n"); + fprintf(ofp, " -k, --kernel Apply for the kernel tracer\n"); + fprintf(ofp, " -u, --userspace [CMD] Apply for the user-space tracer\n"); + fprintf(ofp, " --all If -u, apply on all traceable apps\n"); + fprintf(ofp, " -p, --pid PID If -u, apply on a specific PID\n"); + fprintf(ofp, "\n"); + fprintf(ofp, "Calibrate options:\n"); + fprintf(ofp, " --tracepoint Tracepoint event (default)\n"); + fprintf(ofp, " --probe\n"); + fprintf(ofp, " Dynamic probe.\n"); + fprintf(ofp, " --function\n"); + fprintf(ofp, " Dynamic function entry/return probe.\n"); + fprintf(ofp, " --function:entry symbol\n"); + fprintf(ofp, " Function tracer event\n"); + fprintf(ofp, " --marker User-space marker (deprecated)\n"); + fprintf(ofp, "\n"); +} + +/* + * calibrate_lttng + * + * Calibrate LTTng. + */ +static int calibrate_lttng(void) +{ + int ret = CMD_SUCCESS; + struct lttng_domain dom; + struct lttng_calibrate calibrate; + + /* Create lttng domain */ + if (opt_kernel) { + dom.type = LTTNG_DOMAIN_KERNEL; + } + + /* Kernel tracer action */ + if (opt_kernel) { + switch (opt_event_type) { + case LTTNG_EVENT_TRACEPOINT: + DBG("Calibrating kernel tracepoints"); + break; + case LTTNG_EVENT_PROBE: + DBG("Calibrating kernel probes"); + break; + case LTTNG_EVENT_FUNCTION: + DBG("Calibrating kernel functions"); + calibrate.type = LTTNG_CALIBRATE_FUNCTION; + ret = lttng_calibrate(&dom, &calibrate); + break; + case LTTNG_EVENT_FUNCTION_ENTRY: + DBG("Calibrating kernel function entry"); + break; + default: + ret = CMD_NOT_IMPLEMENTED; + goto end; + } + } else if (opt_userspace) { /* User-space tracer action */ + /* + * TODO: Waiting on lttng UST 2.0 + */ + if (opt_pid_all) { + } else if (opt_pid != 0) { + } + ret = CMD_NOT_IMPLEMENTED; + goto end; + } else { + ERR("Please specify a tracer (kernel or user-space)"); + goto end; + } +end: + return ret; +} + +/* + * cmd_calibrate + * + * Calibrate LTTng tracer. + */ +int cmd_calibrate(int argc, const char **argv) +{ + int opt, ret; + static poptContext pc; + + pc = poptGetContext(NULL, argc, argv, long_options, 0); + poptReadDefaultConfig(pc, 0); + + /* Default event type */ + opt_event_type = LTTNG_EVENT_TRACEPOINT; + + while ((opt = poptGetNextOpt(pc)) != -1) { + switch (opt) { + case OPT_HELP: + usage(stderr); + ret = CMD_SUCCESS; + goto end; + case OPT_USERSPACE: + opt_userspace = 1; + opt_cmd_name = poptGetOptArg(pc); + break; + case OPT_TRACEPOINT: + ret = CMD_NOT_IMPLEMENTED; + break; + case OPT_MARKER: + ret = CMD_NOT_IMPLEMENTED; + goto end; + case OPT_PROBE: + ret = CMD_NOT_IMPLEMENTED; + break; + case OPT_FUNCTION: + opt_event_type = LTTNG_EVENT_FUNCTION; + break; + case OPT_FUNCTION_ENTRY: + ret = CMD_NOT_IMPLEMENTED; + break; + default: + usage(stderr); + ret = CMD_UNDEFINED; + goto end; + } + } + + ret = calibrate_lttng(); + +end: + return ret; +} diff --git a/lttng/lttng.c b/lttng/lttng.c index 3e5f1b187..4d81d2a1d 100644 --- a/lttng/lttng.c +++ b/lttng/lttng.c @@ -71,6 +71,7 @@ static struct cmd_struct commands[] = { { "add-context", cmd_add_context}, { "set-session", cmd_set_session}, { "version", cmd_version}, + { "calibrate", cmd_calibrate}, { NULL, NULL} /* Array closure */ }; @@ -91,6 +92,7 @@ static void usage(FILE *ofp) fprintf(ofp, "\n"); fprintf(ofp, "Commands:\n"); fprintf(ofp, " add-context Add context to event or/and channel\n"); + fprintf(ofp, " calibrate Quantify LTTng overhead\n"); fprintf(ofp, " create Create tracing session\n"); fprintf(ofp, " destroy Teardown tracing session\n"); fprintf(ofp, " enable-channel Enable tracing channel\n"); -- 2.34.1