[DTrace-devel] [PATCH 09/13] Defer creation of uprobes and kprobes for dtrace and fbt

Kris Van Hees kris.van.hees at oracle.com
Mon Jul 6 22:18:43 PDT 2020


On Wed, Jul 01, 2020 at 10:41:14PM -0400, eugene.loh at oracle.com wrote:
> From: Eugene Loh <eugene.loh at oracle.com>
> 
> The dtrace and fbt providers were creating uprobes and kprobes
> unnecessarily early.  Those probes are not needed for determining
> argument types since these providers do not provide typed arguments.
> Hence, the uprobes and kprobes do not need to be created until and
> unless we are going to attach BPF programs to them.  This avoids,
> for example, the unnecessary creation of many tens of thousands of
> kprobes for "dtrace -lP fbt" (once that works) or "dtrace -lv".
> 
> Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
> ---
>  libdtrace/dt_prov_dtrace.c | 96 ++++++++++++++++++++------------------
>  libdtrace/dt_prov_fbt.c    | 91 +++++++++++++++++++-----------------
>  2 files changed, 100 insertions(+), 87 deletions(-)
> 
> diff --git a/libdtrace/dt_prov_dtrace.c b/libdtrace/dt_prov_dtrace.c
> index c5c2a84d..9300b69f 100644
> --- a/libdtrace/dt_prov_dtrace.c
> +++ b/libdtrace/dt_prov_dtrace.c
> @@ -245,57 +245,63 @@ out:
>  static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
>  		      int *argcp, dt_argdesc_t **argvp)
>  {
> -	char	*spec;
> -	char	*fn = NULL;
> -	int	fd;
> -	FILE	*f;
> -	int	rc = -ENOENT;
> -	size_t	len;
> -	int	*idp = &((prv_data_t *)(prp->prv_data))->event_id;
> -
> -        /* if we have an event ID, no need to retrieve it again */
> -        if (*idp != -1)
> -		return -1;
> -
>  	*argcp = 0;			/* no arguments */
>  	*argvp = NULL;
>  
> -	/* get a uprobe specification for this probe */
> -	spec = uprobe_spec(dtp, prp->desc->prb);
> -	if (spec == NULL)
> -		return -ENOENT;
> -
> -	/* add a uprobe */
> -	fd = open(UPROBE_EVENTS, O_WRONLY | O_APPEND);
> -	if (fd == -1)
> -		goto out;
> -
> -	rc = dprintf(fd, "p:" GROUP_FMT "/%s %s\n",
> -		     GROUP_DATA, prp->desc->prb, spec);
> -	close(fd);
> -	if (rc == -1)
> -		goto out;
> -
> -	len = snprintf(NULL, 0, "%s" GROUP_FMT "/%s/format",
> -		       EVENTSFS, GROUP_DATA, prp->desc->prb) + 1;
> -	fn = dt_alloc(dtp, len);
> -	if (fn == NULL)
> -		goto out;
> +	return 0;
> +}
>  
> -	snprintf(fn, len, "%s" GROUP_FMT "/%s/format",
> -		 EVENTSFS, GROUP_DATA, prp->desc->prb);
> -	f = fopen(fn, "r");
> -	if (f == NULL)
> -		goto out;
> +static int attach(dtrace_hdl_t *dtp, const dt_probe_t *prp, int bpf_fd)
> +{
> +	prv_data_t *datap = prp->prv_data;

Based on comments to earlier patches in the series this would use
tp_probe_t *

> -	rc = tp_event_info(dtp, f, 0, idp, NULL, NULL);
> -	fclose(f);
> +	if (datap->event_id == -1) {
> +		char	*spec;
> +		char	*fn;
> +		FILE	*f;
> +		size_t	len;
> +		int	fd, rc = -1;
>  
> -out:
> -	dt_free(dtp, spec);
> -	dt_free(dtp, fn);
> +		/* get a uprobe specification for this probe */
> +		spec = uprobe_spec(dtp, prp->desc->prb);
> +		if (spec == NULL)
> +			return -ENOENT;
> +
> +		/* add a uprobe */
> +		fd = open(UPROBE_EVENTS, O_WRONLY | O_APPEND);
> +		if (fd != -1) {
> +			rc = dprintf(fd, "p:" GROUP_FMT "/%s %s\n",
> +				     GROUP_DATA, prp->desc->prb, spec);
> +			close(fd);
> +		}
> +		dt_free(dtp, spec);
> +		if (rc == -1)
> +			return -ENOENT;
> +
> +		/* open format file */
> +		len = snprintf(NULL, 0, "%s" GROUP_FMT "/%s/format",
> +			       EVENTSFS, GROUP_DATA, prp->desc->prb) + 1;
> +		fn = dt_alloc(dtp, len);
> +		if (fn == NULL)
> +			return -ENOENT;
> +
> +		snprintf(fn, len, "%s" GROUP_FMT "/%s/format",
> +			 EVENTSFS, GROUP_DATA, prp->desc->prb);
> +		f = fopen(fn, "r");
> +		dt_free(dtp, fn);
> +		if (f == NULL)
> +			return -ENOENT;
> +
> +		/* read event id from format file */
> +		rc = tp_event_info(dtp, f, 0, &datap->event_id, NULL, NULL);
> +		fclose(f);
> +
> +		if (rc < 0)
> +			return -ENOENT;
> +	}
>  
> -	return rc;
> +	/* attach BPF program to the probe */
> +	return tp_event_attach(dtp, prp, bpf_fd);
>  }
>  
>  /*
> @@ -335,6 +341,6 @@ dt_provimpl_t	dt_dtrace = {
>  	.populate	= &populate,
>  	.trampoline	= &trampoline,
>  	.probe_info	= &probe_info,
> -	.attach		= &tp_event_attach,
> +	.attach		= &attach,
>  	.probe_fini	= &probe_fini,
>  };
> diff --git a/libdtrace/dt_prov_fbt.c b/libdtrace/dt_prov_fbt.c
> index a58584c0..2cd3b378 100644
> --- a/libdtrace/dt_prov_fbt.c
> +++ b/libdtrace/dt_prov_fbt.c
> @@ -291,54 +291,61 @@ static void trampoline(dt_pcb_t *pcb)
>  static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
>  		      int *argcp, dt_argdesc_t **argvp)
>  {
> -	int	fd;
> -	char	*fn;
> -	size_t	len;
> -	FILE	*f;
> -	int	rc = -1;
> -	int	*idp = &((prv_data_t *)(prp->prv_data))->event_id;
> -
> -        /* if we have an event ID, no need to retrieve it again */
> -        if (*idp != -1)
> -		return -1;
> -
>  	*argcp = 0;			/* no arguments by default */
>  	*argvp = NULL;
>  
> -	/*
> -	 * Register the kprobe with the tracing subsystem.  This will
> -	 * create a tracepoint event.
> -	 */
> -	fd = open(KPROBE_EVENTS, O_WRONLY | O_APPEND);
> -	if (fd == -1)
> -		return -1;
> -
> -	rc = dprintf(fd, "%c:" FBT_GROUP_FMT "/%s %s\n",
> -		     prp->desc->prb[0] == 'e' ? 'p' : 'r', FBT_GROUP_DATA,
> -		     prp->desc->fun, prp->desc->fun);
> -	close(fd);
> -	if (rc == -1)
> -		return -1;
> -
> -	len = snprintf(NULL, 0, "%s" FBT_GROUP_FMT "/%s/format", EVENTSFS,
> -		       FBT_GROUP_DATA, prp->desc->fun) + 1;
> -	fn = dt_alloc(dtp, len);
> -	if (fn == NULL)
> -		goto out;
> +	return 0;
> +}
>  
> -	snprintf(fn, len, "%s" FBT_GROUP_FMT "/%s/format", EVENTSFS,
> -		 FBT_GROUP_DATA, prp->desc->fun);
> -	f = fopen(fn, "r");
> -	if (f == NULL)
> -		goto out;
> +static int attach(dtrace_hdl_t *dtp, const dt_probe_t *prp, int bpf_fd)
> +{
> +	prv_data_t *datap = prp->prv_data;

tp_probe_t *

> -	rc = tp_event_info(dtp, f, 0, idp, NULL, NULL);
> -	fclose(f);
> +	if (datap->event_id == -1) {
> +		char	*fn;
> +		FILE	*f;
> +		size_t	len;
> +		int	fd, rc = -1;
>  
> -out:
> -	dt_free(dtp, fn);
> +		/*
> +		 * Register the kprobe with the tracing subsystem.  This will
> +		 * create a tracepoint event.
> +		 */
> +		fd = open(KPROBE_EVENTS, O_WRONLY | O_APPEND);
> +		if (fd == -1)
> +			return -ENOENT;
> +
> +		rc = dprintf(fd, "%c:" FBT_GROUP_FMT "/%s %s\n",
> +			     prp->desc->prb[0] == 'e' ? 'p' : 'r', FBT_GROUP_DATA,
> +			     prp->desc->fun, prp->desc->fun);
> +		close(fd);
> +		if (rc == -1)
> +			return -ENOENT;
> +
> +		/* open format file */
> +		len = snprintf(NULL, 0, "%s" FBT_GROUP_FMT "/%s/format", EVENTSFS,
> +			       FBT_GROUP_DATA, prp->desc->fun) + 1;
> +		fn = dt_alloc(dtp, len);
> +		if (fn == NULL)
> +			return -ENOENT;
> +
> +		snprintf(fn, len, "%s" FBT_GROUP_FMT "/%s/format", EVENTSFS,
> +			 FBT_GROUP_DATA, prp->desc->fun);
> +		f = fopen(fn, "r");
> +		dt_free(dtp, fn);
> +		if (f == NULL)
> +			return -ENOENT;
> +
> +		/* read event id from format file */
> +		rc = tp_event_info(dtp, f, 0, &datap->event_id, NULL, NULL);
> +		fclose(f);
> +
> +		if (rc < 0)
> +			return -ENOENT;
> +	}
>  
> -	return rc;
> +	/* attach BPF program to the probe */
> +	return tp_event_attach(dtp, prp, bpf_fd);
>  }
>  
>  /*
> @@ -379,6 +386,6 @@ dt_provimpl_t	dt_fbt = {
>  	.populate	= &populate,
>  	.trampoline	= &trampoline,
>  	.probe_info	= &probe_info,
> -	.attach		= &tp_event_attach,
> +	.attach		= &attach,
>  	.probe_fini	= &probe_fini,
>  };
> -- 
> 2.18.2
> 
> 
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel



More information about the DTrace-devel mailing list