|
@@ -8368,30 +8368,39 @@ static struct pmu perf_tracepoint = {
|
|
|
*
|
|
|
* PERF_PROBE_CONFIG_IS_RETPROBE if set, create kretprobe/uretprobe
|
|
|
* if not set, create kprobe/uprobe
|
|
|
+ *
|
|
|
+ * The following values specify a reference counter (or semaphore in the
|
|
|
+ * terminology of tools like dtrace, systemtap, etc.) Userspace Statically
|
|
|
+ * Defined Tracepoints (USDT). Currently, we use 40 bit for the offset.
|
|
|
+ *
|
|
|
+ * PERF_UPROBE_REF_CTR_OFFSET_BITS # of bits in config as th offset
|
|
|
+ * PERF_UPROBE_REF_CTR_OFFSET_SHIFT # of bits to shift left
|
|
|
*/
|
|
|
enum perf_probe_config {
|
|
|
PERF_PROBE_CONFIG_IS_RETPROBE = 1U << 0, /* [k,u]retprobe */
|
|
|
+ PERF_UPROBE_REF_CTR_OFFSET_BITS = 32,
|
|
|
+ PERF_UPROBE_REF_CTR_OFFSET_SHIFT = 64 - PERF_UPROBE_REF_CTR_OFFSET_BITS,
|
|
|
};
|
|
|
|
|
|
PMU_FORMAT_ATTR(retprobe, "config:0");
|
|
|
+#endif
|
|
|
|
|
|
-static struct attribute *probe_attrs[] = {
|
|
|
+#ifdef CONFIG_KPROBE_EVENTS
|
|
|
+static struct attribute *kprobe_attrs[] = {
|
|
|
&format_attr_retprobe.attr,
|
|
|
NULL,
|
|
|
};
|
|
|
|
|
|
-static struct attribute_group probe_format_group = {
|
|
|
+static struct attribute_group kprobe_format_group = {
|
|
|
.name = "format",
|
|
|
- .attrs = probe_attrs,
|
|
|
+ .attrs = kprobe_attrs,
|
|
|
};
|
|
|
|
|
|
-static const struct attribute_group *probe_attr_groups[] = {
|
|
|
- &probe_format_group,
|
|
|
+static const struct attribute_group *kprobe_attr_groups[] = {
|
|
|
+ &kprobe_format_group,
|
|
|
NULL,
|
|
|
};
|
|
|
-#endif
|
|
|
|
|
|
-#ifdef CONFIG_KPROBE_EVENTS
|
|
|
static int perf_kprobe_event_init(struct perf_event *event);
|
|
|
static struct pmu perf_kprobe = {
|
|
|
.task_ctx_nr = perf_sw_context,
|
|
@@ -8401,7 +8410,7 @@ static struct pmu perf_kprobe = {
|
|
|
.start = perf_swevent_start,
|
|
|
.stop = perf_swevent_stop,
|
|
|
.read = perf_swevent_read,
|
|
|
- .attr_groups = probe_attr_groups,
|
|
|
+ .attr_groups = kprobe_attr_groups,
|
|
|
};
|
|
|
|
|
|
static int perf_kprobe_event_init(struct perf_event *event)
|
|
@@ -8433,6 +8442,24 @@ static int perf_kprobe_event_init(struct perf_event *event)
|
|
|
#endif /* CONFIG_KPROBE_EVENTS */
|
|
|
|
|
|
#ifdef CONFIG_UPROBE_EVENTS
|
|
|
+PMU_FORMAT_ATTR(ref_ctr_offset, "config:32-63");
|
|
|
+
|
|
|
+static struct attribute *uprobe_attrs[] = {
|
|
|
+ &format_attr_retprobe.attr,
|
|
|
+ &format_attr_ref_ctr_offset.attr,
|
|
|
+ NULL,
|
|
|
+};
|
|
|
+
|
|
|
+static struct attribute_group uprobe_format_group = {
|
|
|
+ .name = "format",
|
|
|
+ .attrs = uprobe_attrs,
|
|
|
+};
|
|
|
+
|
|
|
+static const struct attribute_group *uprobe_attr_groups[] = {
|
|
|
+ &uprobe_format_group,
|
|
|
+ NULL,
|
|
|
+};
|
|
|
+
|
|
|
static int perf_uprobe_event_init(struct perf_event *event);
|
|
|
static struct pmu perf_uprobe = {
|
|
|
.task_ctx_nr = perf_sw_context,
|
|
@@ -8442,12 +8469,13 @@ static struct pmu perf_uprobe = {
|
|
|
.start = perf_swevent_start,
|
|
|
.stop = perf_swevent_stop,
|
|
|
.read = perf_swevent_read,
|
|
|
- .attr_groups = probe_attr_groups,
|
|
|
+ .attr_groups = uprobe_attr_groups,
|
|
|
};
|
|
|
|
|
|
static int perf_uprobe_event_init(struct perf_event *event)
|
|
|
{
|
|
|
int err;
|
|
|
+ unsigned long ref_ctr_offset;
|
|
|
bool is_retprobe;
|
|
|
|
|
|
if (event->attr.type != perf_uprobe.type)
|
|
@@ -8463,7 +8491,8 @@ static int perf_uprobe_event_init(struct perf_event *event)
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
is_retprobe = event->attr.config & PERF_PROBE_CONFIG_IS_RETPROBE;
|
|
|
- err = perf_uprobe_init(event, is_retprobe);
|
|
|
+ ref_ctr_offset = event->attr.config >> PERF_UPROBE_REF_CTR_OFFSET_SHIFT;
|
|
|
+ err = perf_uprobe_init(event, ref_ctr_offset, is_retprobe);
|
|
|
if (err)
|
|
|
return err;
|
|
|
|