|
@@ -530,8 +530,8 @@ static int create_key_field(struct hist_trigger_data *hist_data,
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
|
|
- if (is_string_field(field)) /* should be last key field */
|
|
|
|
- key_size = HIST_KEY_SIZE_MAX - key_offset;
|
|
|
|
|
|
+ if (is_string_field(field))
|
|
|
|
+ key_size = MAX_FILTER_STR_VAL;
|
|
else
|
|
else
|
|
key_size = field->size;
|
|
key_size = field->size;
|
|
}
|
|
}
|
|
@@ -830,9 +830,34 @@ static void hist_trigger_elt_update(struct hist_trigger_data *hist_data,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static inline void add_to_key(char *compound_key, void *key,
|
|
|
|
+ struct hist_field *key_field, void *rec)
|
|
|
|
+{
|
|
|
|
+ size_t size = key_field->size;
|
|
|
|
+
|
|
|
|
+ if (key_field->flags & HIST_FIELD_FL_STRING) {
|
|
|
|
+ struct ftrace_event_field *field;
|
|
|
|
+
|
|
|
|
+ field = key_field->field;
|
|
|
|
+ if (field->filter_type == FILTER_DYN_STRING)
|
|
|
|
+ size = *(u32 *)(rec + field->offset) >> 16;
|
|
|
|
+ else if (field->filter_type == FILTER_PTR_STRING)
|
|
|
|
+ size = strlen(key);
|
|
|
|
+ else if (field->filter_type == FILTER_STATIC_STRING)
|
|
|
|
+ size = field->size;
|
|
|
|
+
|
|
|
|
+ /* ensure NULL-termination */
|
|
|
|
+ if (size > key_field->size - 1)
|
|
|
|
+ size = key_field->size - 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ memcpy(compound_key + key_field->offset, key, size);
|
|
|
|
+}
|
|
|
|
+
|
|
static void event_hist_trigger(struct event_trigger_data *data, void *rec)
|
|
static void event_hist_trigger(struct event_trigger_data *data, void *rec)
|
|
{
|
|
{
|
|
struct hist_trigger_data *hist_data = data->private_data;
|
|
struct hist_trigger_data *hist_data = data->private_data;
|
|
|
|
+ bool use_compound_key = (hist_data->n_keys > 1);
|
|
unsigned long entries[HIST_STACKTRACE_DEPTH];
|
|
unsigned long entries[HIST_STACKTRACE_DEPTH];
|
|
char compound_key[HIST_KEY_SIZE_MAX];
|
|
char compound_key[HIST_KEY_SIZE_MAX];
|
|
struct stack_trace stacktrace;
|
|
struct stack_trace stacktrace;
|
|
@@ -842,8 +867,7 @@ static void event_hist_trigger(struct event_trigger_data *data, void *rec)
|
|
void *key = NULL;
|
|
void *key = NULL;
|
|
unsigned int i;
|
|
unsigned int i;
|
|
|
|
|
|
- if (hist_data->n_keys > 1)
|
|
|
|
- memset(compound_key, 0, hist_data->key_size);
|
|
|
|
|
|
+ memset(compound_key, 0, hist_data->key_size);
|
|
|
|
|
|
for_each_hist_key_field(i, hist_data) {
|
|
for_each_hist_key_field(i, hist_data) {
|
|
key_field = hist_data->fields[i];
|
|
key_field = hist_data->fields[i];
|
|
@@ -860,35 +884,18 @@ static void event_hist_trigger(struct event_trigger_data *data, void *rec)
|
|
key = entries;
|
|
key = entries;
|
|
} else {
|
|
} else {
|
|
field_contents = key_field->fn(key_field, rec);
|
|
field_contents = key_field->fn(key_field, rec);
|
|
- if (key_field->flags & HIST_FIELD_FL_STRING)
|
|
|
|
|
|
+ if (key_field->flags & HIST_FIELD_FL_STRING) {
|
|
key = (void *)(unsigned long)field_contents;
|
|
key = (void *)(unsigned long)field_contents;
|
|
- else
|
|
|
|
|
|
+ use_compound_key = true;
|
|
|
|
+ } else
|
|
key = (void *)&field_contents;
|
|
key = (void *)&field_contents;
|
|
-
|
|
|
|
- if (hist_data->n_keys > 1) {
|
|
|
|
- /* ensure NULL-termination */
|
|
|
|
- size_t size = key_field->size - 1;
|
|
|
|
-
|
|
|
|
- if (key_field->flags & HIST_FIELD_FL_STRING) {
|
|
|
|
- struct ftrace_event_field *field;
|
|
|
|
-
|
|
|
|
- field = key_field->field;
|
|
|
|
- if (field->filter_type == FILTER_DYN_STRING)
|
|
|
|
- size = *(u32 *)(rec + field->offset) >> 16;
|
|
|
|
- else if (field->filter_type == FILTER_PTR_STRING)
|
|
|
|
- size = strlen(key);
|
|
|
|
-
|
|
|
|
- if (size > key_field->size - 1)
|
|
|
|
- size = key_field->size - 1;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- memcpy(compound_key + key_field->offset, key,
|
|
|
|
- size);
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (use_compound_key)
|
|
|
|
+ add_to_key(compound_key, key, key_field, rec);
|
|
}
|
|
}
|
|
|
|
|
|
- if (hist_data->n_keys > 1)
|
|
|
|
|
|
+ if (use_compound_key)
|
|
key = compound_key;
|
|
key = compound_key;
|
|
|
|
|
|
elt = tracing_map_insert(hist_data->map, key);
|
|
elt = tracing_map_insert(hist_data->map, key);
|