* [PATCH v3 00/12] plugins/execlog: add data address match and address range support
@ 2024-03-01 17:45 Sven Schnelle
2024-03-01 17:45 ` [PATCH v3 01/12] util/log: convert debug_regions to GList Sven Schnelle
` (11 more replies)
0 siblings, 12 replies; 20+ messages in thread
From: Sven Schnelle @ 2024-03-01 17:45 UTC (permalink / raw)
To: Alex Bennée, Alexandre Iooss, Mahmoud Mandour,
Pierrick Bouvier
Cc: qemu-devel, deller, Sven Schnelle
Hi List,
this patchset adds a new -dfilter option and address range matching. With this
execlog can match only a certain range of address for both instruction and
data adresses.
Example usage:
qemu-system-xxx <other options> -d plugin -plugin libexeclog.so,afilter=0x1000-0x2000,dfilter=0x388
This would only log instruction in the address range 0x1000 to 0x2000
and accessing data at address 0x388.
Changes in v3:
- extend plugin api to re-use the existing range parsing infrastructure
- export error report api
Changes in v2:
- rebased on top of latest master
Sven Schnelle (12):
util/log: convert debug_regions to GList
util/log: make qemu_set_dfilter_ranges() take a GList
util/range: move range_list_from_string() to range.c
util/range: add range_list_free()
util/range: use append_new_range() in range_list_from_string()
util/range: split up range_list_from_string()
util/range: make range_list_from_string() accept a single number
qemu/range: add range_list_contains() function
plugins: add API to print errors
plugins: add range list API
plugins/execlog: use range list api
plugins/execlog: add data address match
contrib/plugins/execlog.c | 55 +++++++++++--------
include/qemu/qemu-plugin.h | 53 ++++++++++++++++++
include/qemu/range.h | 24 +++++++++
plugins/api.c | 25 +++++++++
plugins/qemu-plugins.symbols | 4 ++
util/log.c | 84 ++---------------------------
util/range.c | 102 +++++++++++++++++++++++++++++++++++
7 files changed, 244 insertions(+), 103 deletions(-)
--
2.43.2
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v3 01/12] util/log: convert debug_regions to GList
2024-03-01 17:45 [PATCH v3 00/12] plugins/execlog: add data address match and address range support Sven Schnelle
@ 2024-03-01 17:45 ` Sven Schnelle
2024-03-04 10:34 ` Alex Bennée
2024-03-01 17:45 ` [PATCH v3 02/12] util/log: make qemu_set_dfilter_ranges() take a GList Sven Schnelle
` (10 subsequent siblings)
11 siblings, 1 reply; 20+ messages in thread
From: Sven Schnelle @ 2024-03-01 17:45 UTC (permalink / raw)
To: Alex Bennée, Alexandre Iooss, Mahmoud Mandour,
Pierrick Bouvier
Cc: qemu-devel, deller, Sven Schnelle
In preparation of making the parsing part of qemu_set_dfilter_ranges()
available to other users, convert it to return a GList, so the result
can be used with other functions taking a GList of struct Range.
Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
util/log.c | 36 ++++++++++++++++++------------------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/util/log.c b/util/log.c
index d36c98da0b..779c0689a9 100644
--- a/util/log.c
+++ b/util/log.c
@@ -46,7 +46,7 @@ static __thread Notifier qemu_log_thread_cleanup_notifier;
int qemu_loglevel;
static bool log_per_thread;
-static GArray *debug_regions;
+static GList *debug_regions;
/* Returns true if qemu_log() will really write somewhere. */
bool qemu_log_enabled(void)
@@ -368,38 +368,36 @@ bool qemu_set_log_filename_flags(const char *name, int flags, Error **errp)
*/
bool qemu_log_in_addr_range(uint64_t addr)
{
- if (debug_regions) {
- int i = 0;
- for (i = 0; i < debug_regions->len; i++) {
- Range *range = &g_array_index(debug_regions, Range, i);
- if (range_contains(range, addr)) {
- return true;
- }
- }
- return false;
- } else {
+ GList *p;
+
+ if (!debug_regions) {
return true;
}
-}
+ for (p = g_list_first(debug_regions); p; p = g_list_next(p)) {
+ if (range_contains(p->data, addr)) {
+ return true;
+ }
+ }
+ return false;
+}
void qemu_set_dfilter_ranges(const char *filter_spec, Error **errp)
{
gchar **ranges = g_strsplit(filter_spec, ",", 0);
+ struct Range *range = NULL;
int i;
if (debug_regions) {
- g_array_unref(debug_regions);
+ g_list_free_full(debug_regions, g_free);
debug_regions = NULL;
}
- debug_regions = g_array_sized_new(FALSE, FALSE,
- sizeof(Range), g_strv_length(ranges));
for (i = 0; ranges[i]; i++) {
const char *r = ranges[i];
const char *range_op, *r2, *e;
uint64_t r1val, r2val, lob, upb;
- struct Range range;
+ range = g_new0(struct Range, 1);
range_op = strstr(r, "-");
r2 = range_op ? range_op + 1 : NULL;
@@ -448,10 +446,12 @@ void qemu_set_dfilter_ranges(const char *filter_spec, Error **errp)
error_setg(errp, "Invalid range");
goto out;
}
- range_set_bounds(&range, lob, upb);
- g_array_append_val(debug_regions, range);
+ range_set_bounds(range, lob, upb);
+ debug_regions = g_list_append(debug_regions, range);
+ range = NULL;
}
out:
+ g_free(range);
g_strfreev(ranges);
}
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 02/12] util/log: make qemu_set_dfilter_ranges() take a GList
2024-03-01 17:45 [PATCH v3 00/12] plugins/execlog: add data address match and address range support Sven Schnelle
2024-03-01 17:45 ` [PATCH v3 01/12] util/log: convert debug_regions to GList Sven Schnelle
@ 2024-03-01 17:45 ` Sven Schnelle
2024-03-01 17:46 ` [PATCH v3 03/12] util/range: move range_list_from_string() to range.c Sven Schnelle
` (9 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Sven Schnelle @ 2024-03-01 17:45 UTC (permalink / raw)
To: Alex Bennée, Alexandre Iooss, Mahmoud Mandour,
Pierrick Bouvier
Cc: qemu-devel, deller, Sven Schnelle
In preparation of making qemu_set_dfilter_ranges() available
to other users, move the code to a new function range_list_from_string()
which takes an additional GList argument.
Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
util/log.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/util/log.c b/util/log.c
index 779c0689a9..f183ea4e4d 100644
--- a/util/log.c
+++ b/util/log.c
@@ -382,15 +382,16 @@ bool qemu_log_in_addr_range(uint64_t addr)
return false;
}
-void qemu_set_dfilter_ranges(const char *filter_spec, Error **errp)
+static void range_list_from_string(GList **out_ranges, const char *filter_spec,
+ Error **errp)
{
gchar **ranges = g_strsplit(filter_spec, ",", 0);
struct Range *range = NULL;
int i;
- if (debug_regions) {
- g_list_free_full(debug_regions, g_free);
- debug_regions = NULL;
+ if (*out_ranges) {
+ g_list_free_full(*out_ranges, g_free);
+ *out_ranges = NULL;
}
for (i = 0; ranges[i]; i++) {
@@ -447,7 +448,7 @@ void qemu_set_dfilter_ranges(const char *filter_spec, Error **errp)
goto out;
}
range_set_bounds(range, lob, upb);
- debug_regions = g_list_append(debug_regions, range);
+ *out_ranges = g_list_append(*out_ranges, range);
range = NULL;
}
out:
@@ -455,6 +456,11 @@ out:
g_strfreev(ranges);
}
+void qemu_set_dfilter_ranges(const char *filter_spec, Error **errp)
+{
+ range_list_from_string(&debug_regions, filter_spec, errp);
+}
+
const QEMULogItem qemu_log_items[] = {
{ CPU_LOG_TB_OUT_ASM, "out_asm",
"show generated host assembly code for each compiled TB" },
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 03/12] util/range: move range_list_from_string() to range.c
2024-03-01 17:45 [PATCH v3 00/12] plugins/execlog: add data address match and address range support Sven Schnelle
2024-03-01 17:45 ` [PATCH v3 01/12] util/log: convert debug_regions to GList Sven Schnelle
2024-03-01 17:45 ` [PATCH v3 02/12] util/log: make qemu_set_dfilter_ranges() take a GList Sven Schnelle
@ 2024-03-01 17:46 ` Sven Schnelle
2024-03-01 17:46 ` [PATCH v3 04/12] util/range: add range_list_free() Sven Schnelle
` (8 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Sven Schnelle @ 2024-03-01 17:46 UTC (permalink / raw)
To: Alex Bennée, Alexandre Iooss, Mahmoud Mandour,
Pierrick Bouvier
Cc: qemu-devel, deller, Sven Schnelle
Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
include/qemu/range.h | 7 ++++
util/log.c | 74 ------------------------------------------
util/range.c | 76 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 83 insertions(+), 74 deletions(-)
diff --git a/include/qemu/range.h b/include/qemu/range.h
index 205e1da76d..530b0c7db1 100644
--- a/include/qemu/range.h
+++ b/include/qemu/range.h
@@ -233,4 +233,11 @@ void range_inverse_array(GList *in_ranges,
GList **out_ranges,
uint64_t low, uint64_t high);
+/*
+ * Parse a comma separated list of address ranges into a @GArray
+ * of @Range entries. On error @errp is set.
+ */
+void range_list_from_string(GList **out_ranges, const char *filter_spec,
+ Error **errp);
+
#endif
diff --git a/util/log.c b/util/log.c
index f183ea4e4d..90897ef0f9 100644
--- a/util/log.c
+++ b/util/log.c
@@ -382,80 +382,6 @@ bool qemu_log_in_addr_range(uint64_t addr)
return false;
}
-static void range_list_from_string(GList **out_ranges, const char *filter_spec,
- Error **errp)
-{
- gchar **ranges = g_strsplit(filter_spec, ",", 0);
- struct Range *range = NULL;
- int i;
-
- if (*out_ranges) {
- g_list_free_full(*out_ranges, g_free);
- *out_ranges = NULL;
- }
-
- for (i = 0; ranges[i]; i++) {
- const char *r = ranges[i];
- const char *range_op, *r2, *e;
- uint64_t r1val, r2val, lob, upb;
- range = g_new0(struct Range, 1);
-
- range_op = strstr(r, "-");
- r2 = range_op ? range_op + 1 : NULL;
- if (!range_op) {
- range_op = strstr(r, "+");
- r2 = range_op ? range_op + 1 : NULL;
- }
- if (!range_op) {
- range_op = strstr(r, "..");
- r2 = range_op ? range_op + 2 : NULL;
- }
- if (!range_op) {
- error_setg(errp, "Bad range specifier");
- goto out;
- }
-
- if (qemu_strtou64(r, &e, 0, &r1val)
- || e != range_op) {
- error_setg(errp, "Invalid number to the left of %.*s",
- (int)(r2 - range_op), range_op);
- goto out;
- }
- if (qemu_strtou64(r2, NULL, 0, &r2val)) {
- error_setg(errp, "Invalid number to the right of %.*s",
- (int)(r2 - range_op), range_op);
- goto out;
- }
-
- switch (*range_op) {
- case '+':
- lob = r1val;
- upb = r1val + r2val - 1;
- break;
- case '-':
- upb = r1val;
- lob = r1val - (r2val - 1);
- break;
- case '.':
- lob = r1val;
- upb = r2val;
- break;
- default:
- g_assert_not_reached();
- }
- if (lob > upb) {
- error_setg(errp, "Invalid range");
- goto out;
- }
- range_set_bounds(range, lob, upb);
- *out_ranges = g_list_append(*out_ranges, range);
- range = NULL;
- }
-out:
- g_free(range);
- g_strfreev(ranges);
-}
-
void qemu_set_dfilter_ranges(const char *filter_spec, Error **errp)
{
range_list_from_string(&debug_regions, filter_spec, errp);
diff --git a/util/range.c b/util/range.c
index f3f40098d5..bd2d0961bd 100644
--- a/util/range.c
+++ b/util/range.c
@@ -19,6 +19,8 @@
#include "qemu/osdep.h"
#include "qemu/range.h"
+#include "qemu/cutils.h"
+#include "qapi/error.h"
int range_compare(Range *a, Range *b)
{
@@ -121,3 +123,77 @@ void range_inverse_array(GList *in, GList **rev,
exit:
*rev = out;
}
+
+void range_list_from_string(GList **out_ranges, const char *filter_spec,
+ Error **errp)
+{
+ gchar **ranges = g_strsplit(filter_spec, ",", 0);
+ struct Range *range = NULL;
+ int i;
+
+ if (*out_ranges) {
+ g_list_free_full(*out_ranges, g_free);
+ *out_ranges = NULL;
+ }
+
+ for (i = 0; ranges[i]; i++) {
+ const char *r = ranges[i];
+ const char *range_op, *r2, *e;
+ uint64_t r1val, r2val, lob, upb;
+ range = g_new0(struct Range, 1);
+
+ range_op = strstr(r, "-");
+ r2 = range_op ? range_op + 1 : NULL;
+ if (!range_op) {
+ range_op = strstr(r, "+");
+ r2 = range_op ? range_op + 1 : NULL;
+ }
+ if (!range_op) {
+ range_op = strstr(r, "..");
+ r2 = range_op ? range_op + 2 : NULL;
+ }
+ if (!range_op) {
+ error_setg(errp, "Bad range specifier");
+ goto out;
+ }
+
+ if (qemu_strtou64(r, &e, 0, &r1val)
+ || e != range_op) {
+ error_setg(errp, "Invalid number to the left of %.*s",
+ (int)(r2 - range_op), range_op);
+ goto out;
+ }
+ if (qemu_strtou64(r2, NULL, 0, &r2val)) {
+ error_setg(errp, "Invalid number to the right of %.*s",
+ (int)(r2 - range_op), range_op);
+ goto out;
+ }
+
+ switch (*range_op) {
+ case '+':
+ lob = r1val;
+ upb = r1val + r2val - 1;
+ break;
+ case '-':
+ upb = r1val;
+ lob = r1val - (r2val - 1);
+ break;
+ case '.':
+ lob = r1val;
+ upb = r2val;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ if (lob > upb) {
+ error_setg(errp, "Invalid range");
+ goto out;
+ }
+ range_set_bounds(range, lob, upb);
+ *out_ranges = g_list_append(*out_ranges, range);
+ range = NULL;
+ }
+out:
+ g_free(range);
+ g_strfreev(ranges);
+}
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 04/12] util/range: add range_list_free()
2024-03-01 17:45 [PATCH v3 00/12] plugins/execlog: add data address match and address range support Sven Schnelle
` (2 preceding siblings ...)
2024-03-01 17:46 ` [PATCH v3 03/12] util/range: move range_list_from_string() to range.c Sven Schnelle
@ 2024-03-01 17:46 ` Sven Schnelle
2024-03-01 17:46 ` [PATCH v3 05/12] util/range: use append_new_range() in range_list_from_string() Sven Schnelle
` (7 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Sven Schnelle @ 2024-03-01 17:46 UTC (permalink / raw)
To: Alex Bennée, Alexandre Iooss, Mahmoud Mandour,
Pierrick Bouvier
Cc: qemu-devel, deller, Sven Schnelle
Introduce range_list_free(), which takes a GList of ranges
and frees the list and each range.
Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
include/qemu/range.h | 5 +++++
util/range.c | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/include/qemu/range.h b/include/qemu/range.h
index 530b0c7db1..4ff9799d89 100644
--- a/include/qemu/range.h
+++ b/include/qemu/range.h
@@ -240,4 +240,9 @@ void range_inverse_array(GList *in_ranges,
void range_list_from_string(GList **out_ranges, const char *filter_spec,
Error **errp);
+/*
+ * Free a list of ranges.
+ */
+void range_list_free(GList *ranges);
+
#endif
diff --git a/util/range.c b/util/range.c
index bd2d0961bd..7234ab7a53 100644
--- a/util/range.c
+++ b/util/range.c
@@ -197,3 +197,8 @@ out:
g_free(range);
g_strfreev(ranges);
}
+
+void range_list_free(GList *ranges)
+{
+ g_list_free_full(ranges, g_free);
+}
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 05/12] util/range: use append_new_range() in range_list_from_string()
2024-03-01 17:45 [PATCH v3 00/12] plugins/execlog: add data address match and address range support Sven Schnelle
` (3 preceding siblings ...)
2024-03-01 17:46 ` [PATCH v3 04/12] util/range: add range_list_free() Sven Schnelle
@ 2024-03-01 17:46 ` Sven Schnelle
2024-03-01 17:46 ` [PATCH v3 06/12] util/range: split up range_list_from_string() Sven Schnelle
` (6 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Sven Schnelle @ 2024-03-01 17:46 UTC (permalink / raw)
To: Alex Bennée, Alexandre Iooss, Mahmoud Mandour,
Pierrick Bouvier
Cc: qemu-devel, deller, Sven Schnelle
Use append_new_ranges() instead of manually allocating and
filling the new range member.
Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
util/range.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/util/range.c b/util/range.c
index 7234ab7a53..db535de9a7 100644
--- a/util/range.c
+++ b/util/range.c
@@ -128,7 +128,6 @@ void range_list_from_string(GList **out_ranges, const char *filter_spec,
Error **errp)
{
gchar **ranges = g_strsplit(filter_spec, ",", 0);
- struct Range *range = NULL;
int i;
if (*out_ranges) {
@@ -140,7 +139,6 @@ void range_list_from_string(GList **out_ranges, const char *filter_spec,
const char *r = ranges[i];
const char *range_op, *r2, *e;
uint64_t r1val, r2val, lob, upb;
- range = g_new0(struct Range, 1);
range_op = strstr(r, "-");
r2 = range_op ? range_op + 1 : NULL;
@@ -189,12 +187,9 @@ void range_list_from_string(GList **out_ranges, const char *filter_spec,
error_setg(errp, "Invalid range");
goto out;
}
- range_set_bounds(range, lob, upb);
- *out_ranges = g_list_append(*out_ranges, range);
- range = NULL;
+ *out_ranges = append_new_range(*out_ranges, lob, upb);
}
out:
- g_free(range);
g_strfreev(ranges);
}
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 06/12] util/range: split up range_list_from_string()
2024-03-01 17:45 [PATCH v3 00/12] plugins/execlog: add data address match and address range support Sven Schnelle
` (4 preceding siblings ...)
2024-03-01 17:46 ` [PATCH v3 05/12] util/range: use append_new_range() in range_list_from_string() Sven Schnelle
@ 2024-03-01 17:46 ` Sven Schnelle
2024-03-01 17:46 ` [PATCH v3 07/12] util/range: make range_list_from_string() accept a single number Sven Schnelle
` (5 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Sven Schnelle @ 2024-03-01 17:46 UTC (permalink / raw)
To: Alex Bennée, Alexandre Iooss, Mahmoud Mandour,
Pierrick Bouvier
Cc: qemu-devel, deller, Sven Schnelle
Makes the code a bit easier to read and maintain.
Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
util/range.c | 119 ++++++++++++++++++++++++++++++---------------------
1 file changed, 70 insertions(+), 49 deletions(-)
diff --git a/util/range.c b/util/range.c
index db535de9a7..8c463995e7 100644
--- a/util/range.c
+++ b/util/range.c
@@ -124,6 +124,74 @@ exit:
*rev = out;
}
+static const char *split_single_range(const char *r, const char **r2)
+{
+ char *range_op;
+
+ range_op = strstr(r, "-");
+ if (range_op) {
+ *r2 = range_op + 1;
+ return range_op;
+ }
+ range_op = strstr(r, "+");
+ if (range_op) {
+ *r2 = range_op + 1;
+ return range_op;
+ }
+ range_op = strstr(r, "..");
+ if (range_op) {
+ *r2 = range_op + 2;
+ return range_op;
+ }
+ return NULL;
+}
+
+static int parse_single_range(const char *r, Error **errp,
+ uint64_t *lob, uint64_t *upb)
+{
+ const char *range_op, *r2, *e;
+ uint64_t r1val, r2val;
+
+ range_op = split_single_range(r, &r2);
+ if (!range_op) {
+ error_setg(errp, "Bad range specifier");
+ return 1;
+ }
+ if (qemu_strtou64(r, &e, 0, &r1val)
+ || e != range_op) {
+ error_setg(errp, "Invalid number to the left of %.*s",
+ (int)(r2 - range_op), range_op);
+ return 1;
+ }
+ if (qemu_strtou64(r2, NULL, 0, &r2val)) {
+ error_setg(errp, "Invalid number to the right of %.*s",
+ (int)(r2 - range_op), range_op);
+ return 1;
+ }
+
+ switch (*range_op) {
+ case '+':
+ *lob = r1val;
+ *upb = r1val + r2val - 1;
+ break;
+ case '-':
+ *upb = r1val;
+ *lob = r1val - (r2val - 1);
+ break;
+ case '.':
+ *lob = r1val;
+ *upb = r2val;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ if (*lob > *upb) {
+ error_setg(errp, "Invalid range");
+ return 1;
+ }
+ return 0;
+}
+
void range_list_from_string(GList **out_ranges, const char *filter_spec,
Error **errp)
{
@@ -136,60 +204,13 @@ void range_list_from_string(GList **out_ranges, const char *filter_spec,
}
for (i = 0; ranges[i]; i++) {
- const char *r = ranges[i];
- const char *range_op, *r2, *e;
- uint64_t r1val, r2val, lob, upb;
-
- range_op = strstr(r, "-");
- r2 = range_op ? range_op + 1 : NULL;
- if (!range_op) {
- range_op = strstr(r, "+");
- r2 = range_op ? range_op + 1 : NULL;
- }
- if (!range_op) {
- range_op = strstr(r, "..");
- r2 = range_op ? range_op + 2 : NULL;
- }
- if (!range_op) {
- error_setg(errp, "Bad range specifier");
- goto out;
- }
-
- if (qemu_strtou64(r, &e, 0, &r1val)
- || e != range_op) {
- error_setg(errp, "Invalid number to the left of %.*s",
- (int)(r2 - range_op), range_op);
- goto out;
- }
- if (qemu_strtou64(r2, NULL, 0, &r2val)) {
- error_setg(errp, "Invalid number to the right of %.*s",
- (int)(r2 - range_op), range_op);
- goto out;
- }
+ uint64_t lob, upb;
- switch (*range_op) {
- case '+':
- lob = r1val;
- upb = r1val + r2val - 1;
+ if (parse_single_range(ranges[i], errp, &lob, &upb)) {
break;
- case '-':
- upb = r1val;
- lob = r1val - (r2val - 1);
- break;
- case '.':
- lob = r1val;
- upb = r2val;
- break;
- default:
- g_assert_not_reached();
- }
- if (lob > upb) {
- error_setg(errp, "Invalid range");
- goto out;
}
*out_ranges = append_new_range(*out_ranges, lob, upb);
}
-out:
g_strfreev(ranges);
}
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 07/12] util/range: make range_list_from_string() accept a single number
2024-03-01 17:45 [PATCH v3 00/12] plugins/execlog: add data address match and address range support Sven Schnelle
` (5 preceding siblings ...)
2024-03-01 17:46 ` [PATCH v3 06/12] util/range: split up range_list_from_string() Sven Schnelle
@ 2024-03-01 17:46 ` Sven Schnelle
2024-03-01 17:46 ` [PATCH v3 08/12] qemu/range: add range_list_contains() function Sven Schnelle
` (4 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Sven Schnelle @ 2024-03-01 17:46 UTC (permalink / raw)
To: Alex Bennée, Alexandre Iooss, Mahmoud Mandour,
Pierrick Bouvier
Cc: qemu-devel, deller, Sven Schnelle
To use range_list_from_string() as a replacement in the execlog
plugin, make it accept single numbers instead of a range. This
might also be useful for the already present debug_ranges filtering.
Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
util/range.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/util/range.c b/util/range.c
index 8c463995e7..7784c21b12 100644
--- a/util/range.c
+++ b/util/range.c
@@ -154,6 +154,11 @@ static int parse_single_range(const char *r, Error **errp,
range_op = split_single_range(r, &r2);
if (!range_op) {
+ if (!qemu_strtou64(r, &e, 0, &r1val) && *e == '\0') {
+ *lob = r1val;
+ *upb = r1val;
+ return 0;
+ }
error_setg(errp, "Bad range specifier");
return 1;
}
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 08/12] qemu/range: add range_list_contains() function
2024-03-01 17:45 [PATCH v3 00/12] plugins/execlog: add data address match and address range support Sven Schnelle
` (6 preceding siblings ...)
2024-03-01 17:46 ` [PATCH v3 07/12] util/range: make range_list_from_string() accept a single number Sven Schnelle
@ 2024-03-01 17:46 ` Sven Schnelle
2024-03-01 17:46 ` [PATCH v3 09/12] plugins: add API to print errors Sven Schnelle
` (3 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Sven Schnelle @ 2024-03-01 17:46 UTC (permalink / raw)
To: Alex Bennée, Alexandre Iooss, Mahmoud Mandour,
Pierrick Bouvier
Cc: qemu-devel, deller, Sven Schnelle
Add a small inline function to match an address against
a list of ranges.
Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
include/qemu/range.h | 12 ++++++++++++
util/log.c | 10 +---------
2 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/include/qemu/range.h b/include/qemu/range.h
index 4ff9799d89..7ef9b3d5fb 100644
--- a/include/qemu/range.h
+++ b/include/qemu/range.h
@@ -57,6 +57,18 @@ static inline bool range_contains(const Range *range, uint64_t val)
return val >= range->lob && val <= range->upb;
}
+static inline bool range_list_contains(GList *ranges, uint64_t val)
+{
+ GList *p;
+
+ for (p = g_list_first(ranges); p; p = g_list_next(p)) {
+ if (range_contains(p->data, val)) {
+ return true;
+ }
+ }
+ return false;
+}
+
/* Initialize @range to the empty range */
static inline void range_make_empty(Range *range)
{
diff --git a/util/log.c b/util/log.c
index 90897ef0f9..032110d700 100644
--- a/util/log.c
+++ b/util/log.c
@@ -368,18 +368,10 @@ bool qemu_set_log_filename_flags(const char *name, int flags, Error **errp)
*/
bool qemu_log_in_addr_range(uint64_t addr)
{
- GList *p;
-
if (!debug_regions) {
return true;
}
-
- for (p = g_list_first(debug_regions); p; p = g_list_next(p)) {
- if (range_contains(p->data, addr)) {
- return true;
- }
- }
- return false;
+ return range_list_contains(debug_regions, addr);
}
void qemu_set_dfilter_ranges(const char *filter_spec, Error **errp)
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 09/12] plugins: add API to print errors
2024-03-01 17:45 [PATCH v3 00/12] plugins/execlog: add data address match and address range support Sven Schnelle
` (7 preceding siblings ...)
2024-03-01 17:46 ` [PATCH v3 08/12] qemu/range: add range_list_contains() function Sven Schnelle
@ 2024-03-01 17:46 ` Sven Schnelle
2024-03-01 17:46 ` [PATCH v3 10/12] plugins: add range list API Sven Schnelle
` (2 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Sven Schnelle @ 2024-03-01 17:46 UTC (permalink / raw)
To: Alex Bennée, Alexandre Iooss, Mahmoud Mandour,
Pierrick Bouvier
Cc: qemu-devel, deller, Sven Schnelle
add qemu_plugin_error_print() which is a wrapper around
error_report_err(). This will be used by
qemu_plugin_parse_filter_ranges() to report parse failures.
Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
include/qemu/qemu-plugin.h | 12 ++++++++++++
plugins/api.c | 7 +++++++
plugins/qemu-plugins.symbols | 1 +
3 files changed, 20 insertions(+)
diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h
index 45e2ebc8f8..5839feea4d 100644
--- a/include/qemu/qemu-plugin.h
+++ b/include/qemu/qemu-plugin.h
@@ -752,5 +752,17 @@ QEMU_PLUGIN_API
int qemu_plugin_read_register(struct qemu_plugin_register *handle,
GByteArray *buf);
+typedef struct Error Error;
+
+/**
+ * qemu_plugin_error_print() - print and free error
+ *
+ * @err: a @Error handle
+ *
+ * This function shows and and frees the supplied error.
+ */
+
+QEMU_PLUGIN_API
+void qemu_plugin_error_print(Error *err);
#endif /* QEMU_QEMU_PLUGIN_H */
diff --git a/plugins/api.c b/plugins/api.c
index 81f43c9ce8..8fd3a8964a 100644
--- a/plugins/api.c
+++ b/plugins/api.c
@@ -45,6 +45,7 @@
#include "exec/ram_addr.h"
#include "disas/disas.h"
#include "plugin.h"
+#include "qapi/error.h"
#ifndef CONFIG_USER_ONLY
#include "qemu/plugin-memory.h"
#include "hw/boards.h"
@@ -465,3 +466,9 @@ int qemu_plugin_read_register(struct qemu_plugin_register *reg, GByteArray *buf)
return gdb_read_register(current_cpu, buf, GPOINTER_TO_INT(reg));
}
+
+void qemu_plugin_error_print(Error *err)
+{
+ error_report_err(err);
+}
+
diff --git a/plugins/qemu-plugins.symbols b/plugins/qemu-plugins.symbols
index 27fe97239b..b142d11e58 100644
--- a/plugins/qemu-plugins.symbols
+++ b/plugins/qemu-plugins.symbols
@@ -2,6 +2,7 @@
qemu_plugin_bool_parse;
qemu_plugin_end_code;
qemu_plugin_entry_code;
+ qemu_plugin_error_print;
qemu_plugin_get_hwaddr;
qemu_plugin_get_registers;
qemu_plugin_hwaddr_device_name;
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 10/12] plugins: add range list API
2024-03-01 17:45 [PATCH v3 00/12] plugins/execlog: add data address match and address range support Sven Schnelle
` (8 preceding siblings ...)
2024-03-01 17:46 ` [PATCH v3 09/12] plugins: add API to print errors Sven Schnelle
@ 2024-03-01 17:46 ` Sven Schnelle
2024-03-03 17:45 ` Bernhard Beschow
2024-03-01 17:46 ` [PATCH v3 11/12] plugins/execlog: use range list api Sven Schnelle
2024-03-01 17:46 ` [PATCH v3 12/12] plugins/execlog: add data address match Sven Schnelle
11 siblings, 1 reply; 20+ messages in thread
From: Sven Schnelle @ 2024-03-01 17:46 UTC (permalink / raw)
To: Alex Bennée, Alexandre Iooss, Mahmoud Mandour,
Pierrick Bouvier
Cc: qemu-devel, deller, Sven Schnelle
Export range_list_from_string(), range_contains() and range_list_free()
to allow plugins to parse filter ranges and match them to avoid
reimplementing this functionality.
Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
include/qemu/qemu-plugin.h | 41 ++++++++++++++++++++++++++++++++++++
plugins/api.c | 18 ++++++++++++++++
plugins/qemu-plugins.symbols | 3 +++
3 files changed, 62 insertions(+)
diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h
index 5839feea4d..4910a63d70 100644
--- a/include/qemu/qemu-plugin.h
+++ b/include/qemu/qemu-plugin.h
@@ -765,4 +765,45 @@ typedef struct Error Error;
QEMU_PLUGIN_API
void qemu_plugin_error_print(Error *err);
+typedef GList qemu_plugin_range_list;
+
+/**
+ * qemu_plugin_ranges_from_string() - parse a filter range string
+ *
+ * @out_ranges: a pointer to a @qemu_plugin_range_list pointer
+ * @filter_spec: input string
+ * @errp: @Error string on parse failure
+ *
+ * This function parses a filter specification string and stores the
+ * parsed adress ranges found in @out. On parse failure a @Error pointer
+ * is stored in @errp. The function accepts a comma-separated list
+ * of start and end addresses or single addresses.
+ */
+QEMU_PLUGIN_API
+void qemu_plugin_range_list_from_string(qemu_plugin_range_list **out_range,
+ const char *filter_spec,
+ Error **errp);
+
+/**
+ * qemu_plugin_range_list_contains() - match a value against a list
+ * of ranges
+ *
+ * @ranges: a pointer to a @qemu_plugin_range_list
+ * @val: the value to match
+ *
+ * This function matches @val against the adress range list in @ranges.
+ * On success, true is returned, otherwise false.
+ */
+QEMU_PLUGIN_API
+bool qemu_plugin_range_list_contains(qemu_plugin_range_list *ranges,
+ uint64_t val);
+
+/**
+ * qemu_plugin_range_list_free() - free a list of ranges
+ *
+ * @ranges: a pointer to the list to be freed
+ */
+QEMU_PLUGIN_API
+void qemu_plugin_range_list_free(qemu_plugin_range_list *ranges);
+
#endif /* QEMU_QEMU_PLUGIN_H */
diff --git a/plugins/api.c b/plugins/api.c
index 8fd3a8964a..8dbd14c648 100644
--- a/plugins/api.c
+++ b/plugins/api.c
@@ -472,3 +472,21 @@ void qemu_plugin_error_print(Error *err)
error_report_err(err);
}
+void qemu_plugin_range_list_from_string(qemu_plugin_range_list **out,
+ const char *filter_spec,
+ Error **errp)
+{
+ return range_list_from_string(out, filter_spec, errp);
+}
+
+bool qemu_plugin_range_list_contains(qemu_plugin_range_list *ranges,
+ uint64_t val)
+{
+ return range_list_contains(ranges, val);
+}
+
+void qemu_plugin_range_list_free(qemu_plugin_range_list *ranges)
+{
+ return range_list_free(ranges);
+}
+
diff --git a/plugins/qemu-plugins.symbols b/plugins/qemu-plugins.symbols
index b142d11e58..472b29fc5f 100644
--- a/plugins/qemu-plugins.symbols
+++ b/plugins/qemu-plugins.symbols
@@ -21,6 +21,9 @@
qemu_plugin_num_vcpus;
qemu_plugin_outs;
qemu_plugin_path_to_binary;
+ qemu_plugin_range_list_contains;
+ qemu_plugin_range_list_free;
+ qemu_plugin_range_list_from_string;
qemu_plugin_read_register;
qemu_plugin_register_atexit_cb;
qemu_plugin_register_flush_cb;
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 11/12] plugins/execlog: use range list api
2024-03-01 17:45 [PATCH v3 00/12] plugins/execlog: add data address match and address range support Sven Schnelle
` (9 preceding siblings ...)
2024-03-01 17:46 ` [PATCH v3 10/12] plugins: add range list API Sven Schnelle
@ 2024-03-01 17:46 ` Sven Schnelle
2024-03-01 17:46 ` [PATCH v3 12/12] plugins/execlog: add data address match Sven Schnelle
11 siblings, 0 replies; 20+ messages in thread
From: Sven Schnelle @ 2024-03-01 17:46 UTC (permalink / raw)
To: Alex Bennée, Alexandre Iooss, Mahmoud Mandour,
Pierrick Bouvier
Cc: qemu-devel, deller, Sven Schnelle
Instead of doing its own implementation, use the new range
list API to parse and match address lists.
Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
contrib/plugins/execlog.c | 27 +++++++++------------------
1 file changed, 9 insertions(+), 18 deletions(-)
diff --git a/contrib/plugins/execlog.c b/contrib/plugins/execlog.c
index a1dfd59ab7..c518797893 100644
--- a/contrib/plugins/execlog.c
+++ b/contrib/plugins/execlog.c
@@ -35,7 +35,7 @@ static GArray *cpus;
static GRWLock expand_array_lock;
static GPtrArray *imatches;
-static GArray *amatches;
+static GList *amatches;
static GPtrArray *rmatches;
static bool disas_assist;
static GMutex add_reg_name_lock;
@@ -215,12 +215,8 @@ static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
}
if (skip && amatches) {
- int j;
- for (j = 0; j < amatches->len && skip; j++) {
- uint64_t v = g_array_index(amatches, uint64_t, j);
- if (v == insn_vaddr) {
- skip = false;
- }
+ if (qemu_plugin_range_list_contains(amatches, insn_vaddr)) {
+ skip = false;
}
}
@@ -398,16 +394,6 @@ static void parse_insn_match(char *match)
g_ptr_array_add(imatches, g_strdup(match));
}
-static void parse_vaddr_match(char *match)
-{
- uint64_t v = g_ascii_strtoull(match, NULL, 16);
-
- if (!amatches) {
- amatches = g_array_new(false, true, sizeof(uint64_t));
- }
- g_array_append_val(amatches, v);
-}
-
/*
* We have to wait until vCPUs are started before we can check the
* patterns find anything.
@@ -440,7 +426,12 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
if (g_strcmp0(tokens[0], "ifilter") == 0) {
parse_insn_match(tokens[1]);
} else if (g_strcmp0(tokens[0], "afilter") == 0) {
- parse_vaddr_match(tokens[1]);
+ Error *err = NULL;
+ qemu_plugin_range_list_from_string(&amatches, tokens[1], &err);
+ if (err) {
+ qemu_plugin_error_print(err);
+ return -1;
+ }
} else if (g_strcmp0(tokens[0], "reg") == 0) {
add_regpat(tokens[1]);
} else if (g_strcmp0(tokens[0], "rdisas") == 0) {
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v3 12/12] plugins/execlog: add data address match
2024-03-01 17:45 [PATCH v3 00/12] plugins/execlog: add data address match and address range support Sven Schnelle
` (10 preceding siblings ...)
2024-03-01 17:46 ` [PATCH v3 11/12] plugins/execlog: use range list api Sven Schnelle
@ 2024-03-01 17:46 ` Sven Schnelle
11 siblings, 0 replies; 20+ messages in thread
From: Sven Schnelle @ 2024-03-01 17:46 UTC (permalink / raw)
To: Alex Bennée, Alexandre Iooss, Mahmoud Mandour,
Pierrick Bouvier
Cc: qemu-devel, deller, Sven Schnelle
Add a match similar to the afilter address match, but for data
addresses. When an address is specified with '-dfilter=0x12345'
only load/stores to/from address 0x12345 are printed. All other
instructions are hidden.
Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
contrib/plugins/execlog.c | 28 +++++++++++++++++++++++-----
1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/contrib/plugins/execlog.c b/contrib/plugins/execlog.c
index c518797893..c44fd0e593 100644
--- a/contrib/plugins/execlog.c
+++ b/contrib/plugins/execlog.c
@@ -27,6 +27,8 @@ typedef struct CPU {
GString *last_exec;
/* Ptr array of Register */
GPtrArray *registers;
+ /* whether this instruction should be logged */
+ bool log;
} CPU;
QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
@@ -36,6 +38,7 @@ static GRWLock expand_array_lock;
static GPtrArray *imatches;
static GList *amatches;
+static GList *dmatches;
static GPtrArray *rmatches;
static bool disas_assist;
static GMutex add_reg_name_lock;
@@ -62,6 +65,11 @@ static void vcpu_mem(unsigned int cpu_index, qemu_plugin_meminfo_t info,
/* Find vCPU in array */
+ if (dmatches && !qemu_plugin_range_list_contains(dmatches, vaddr)) {
+ return;
+ }
+ c->log = true;
+
/* Indicate type of memory access */
if (qemu_plugin_mem_is_store(info)) {
g_string_append(s, ", store");
@@ -121,15 +129,17 @@ static void vcpu_insn_exec_with_regs(unsigned int cpu_index, void *udata)
if (cpu->registers) {
insn_check_regs(cpu);
}
-
- qemu_plugin_outs(cpu->last_exec->str);
- qemu_plugin_outs("\n");
+ if (cpu->log) {
+ qemu_plugin_outs(cpu->last_exec->str);
+ qemu_plugin_outs("\n");
+ }
}
/* Store new instruction in cache */
/* vcpu_mem will add memory access information to last_exec */
g_string_printf(cpu->last_exec, "%u, ", cpu_index);
g_string_append(cpu->last_exec, (char *)udata);
+ cpu->log = dmatches ? false : true;
}
/* Log last instruction while checking registers, ignore next */
@@ -157,7 +167,7 @@ static void vcpu_insn_exec(unsigned int cpu_index, void *udata)
CPU *cpu = get_cpu(cpu_index);
/* Print previous instruction in cache */
- if (cpu->last_exec->len) {
+ if (cpu->log && cpu->last_exec->len) {
qemu_plugin_outs(cpu->last_exec->str);
qemu_plugin_outs("\n");
}
@@ -166,6 +176,7 @@ static void vcpu_insn_exec(unsigned int cpu_index, void *udata)
/* vcpu_mem will add memory access information to last_exec */
g_string_printf(cpu->last_exec, "%u, ", cpu_index);
g_string_append(cpu->last_exec, (char *)udata);
+ cpu->log = dmatches ? false : true;
}
/**
@@ -377,7 +388,7 @@ static void plugin_exit(qemu_plugin_id_t id, void *p)
g_rw_lock_reader_lock(&expand_array_lock);
for (i = 0; i < cpus->len; i++) {
CPU *c = get_cpu(i);
- if (c->last_exec && c->last_exec->str) {
+ if (c->log && c->last_exec && c->last_exec->str) {
qemu_plugin_outs(c->last_exec->str);
qemu_plugin_outs("\n");
}
@@ -432,6 +443,13 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
qemu_plugin_error_print(err);
return -1;
}
+ } else if (g_strcmp0(tokens[0], "dfilter") == 0) {
+ Error *err = NULL;
+ qemu_plugin_range_list_from_string(&dmatches, tokens[1], &err);
+ if (err) {
+ qemu_plugin_error_print(err);
+ return -1;
+ }
} else if (g_strcmp0(tokens[0], "reg") == 0) {
add_regpat(tokens[1]);
} else if (g_strcmp0(tokens[0], "rdisas") == 0) {
--
2.43.2
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v3 10/12] plugins: add range list API
2024-03-01 17:46 ` [PATCH v3 10/12] plugins: add range list API Sven Schnelle
@ 2024-03-03 17:45 ` Bernhard Beschow
0 siblings, 0 replies; 20+ messages in thread
From: Bernhard Beschow @ 2024-03-03 17:45 UTC (permalink / raw)
To: qemu-devel, Sven Schnelle, Alex Bennée, Alexandre Iooss,
Mahmoud Mandour, Pierrick Bouvier
Cc: deller
Am 1. März 2024 17:46:07 UTC schrieb Sven Schnelle <svens@stackframe.org>:
>Export range_list_from_string(), range_contains() and range_list_free()
>to allow plugins to parse filter ranges and match them to avoid
>reimplementing this functionality.
>
>Signed-off-by: Sven Schnelle <svens@stackframe.org>
>---
> include/qemu/qemu-plugin.h | 41 ++++++++++++++++++++++++++++++++++++
> plugins/api.c | 18 ++++++++++++++++
> plugins/qemu-plugins.symbols | 3 +++
> 3 files changed, 62 insertions(+)
>
>diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h
>index 5839feea4d..4910a63d70 100644
>--- a/include/qemu/qemu-plugin.h
>+++ b/include/qemu/qemu-plugin.h
>@@ -765,4 +765,45 @@ typedef struct Error Error;
> QEMU_PLUGIN_API
> void qemu_plugin_error_print(Error *err);
>
>+typedef GList qemu_plugin_range_list;
>+
>+/**
>+ * qemu_plugin_ranges_from_string() - parse a filter range string
>+ *
>+ * @out_ranges: a pointer to a @qemu_plugin_range_list pointer
>+ * @filter_spec: input string
>+ * @errp: @Error string on parse failure
>+ *
>+ * This function parses a filter specification string and stores the
>+ * parsed adress ranges found in @out. On parse failure a @Error pointer
>+ * is stored in @errp. The function accepts a comma-separated list
>+ * of start and end addresses or single addresses.
>+ */
>+QEMU_PLUGIN_API
>+void qemu_plugin_range_list_from_string(qemu_plugin_range_list **out_range,
Nice series in general. One nitpick: When the API docs are generated I get the following error:
include/qemu/qemu-plugin.h:788: warning: Function parameter or member 'out_range' not described in 'qemu_plugin_range_list_from_string'
This is due to the parameter being documented as "out_ranges" which seems like the more appropriate name given its type. It might also be cleaner to have the same names in the source, too.
Best regards,
Bernhard
>+ const char *filter_spec,
>+ Error **errp);
>+
>+/**
>+ * qemu_plugin_range_list_contains() - match a value against a list
>+ * of ranges
>+ *
>+ * @ranges: a pointer to a @qemu_plugin_range_list
>+ * @val: the value to match
>+ *
>+ * This function matches @val against the adress range list in @ranges.
>+ * On success, true is returned, otherwise false.
>+ */
>+QEMU_PLUGIN_API
>+bool qemu_plugin_range_list_contains(qemu_plugin_range_list *ranges,
>+ uint64_t val);
>+
>+/**
>+ * qemu_plugin_range_list_free() - free a list of ranges
>+ *
>+ * @ranges: a pointer to the list to be freed
>+ */
>+QEMU_PLUGIN_API
>+void qemu_plugin_range_list_free(qemu_plugin_range_list *ranges);
>+
> #endif /* QEMU_QEMU_PLUGIN_H */
>diff --git a/plugins/api.c b/plugins/api.c
>index 8fd3a8964a..8dbd14c648 100644
>--- a/plugins/api.c
>+++ b/plugins/api.c
>@@ -472,3 +472,21 @@ void qemu_plugin_error_print(Error *err)
> error_report_err(err);
> }
>
>+void qemu_plugin_range_list_from_string(qemu_plugin_range_list **out,
>+ const char *filter_spec,
>+ Error **errp)
>+{
>+ return range_list_from_string(out, filter_spec, errp);
>+}
>+
>+bool qemu_plugin_range_list_contains(qemu_plugin_range_list *ranges,
>+ uint64_t val)
>+{
>+ return range_list_contains(ranges, val);
>+}
>+
>+void qemu_plugin_range_list_free(qemu_plugin_range_list *ranges)
>+{
>+ return range_list_free(ranges);
>+}
>+
>diff --git a/plugins/qemu-plugins.symbols b/plugins/qemu-plugins.symbols
>index b142d11e58..472b29fc5f 100644
>--- a/plugins/qemu-plugins.symbols
>+++ b/plugins/qemu-plugins.symbols
>@@ -21,6 +21,9 @@
> qemu_plugin_num_vcpus;
> qemu_plugin_outs;
> qemu_plugin_path_to_binary;
>+ qemu_plugin_range_list_contains;
>+ qemu_plugin_range_list_free;
>+ qemu_plugin_range_list_from_string;
> qemu_plugin_read_register;
> qemu_plugin_register_atexit_cb;
> qemu_plugin_register_flush_cb;
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 01/12] util/log: convert debug_regions to GList
2024-03-01 17:45 ` [PATCH v3 01/12] util/log: convert debug_regions to GList Sven Schnelle
@ 2024-03-04 10:34 ` Alex Bennée
2024-03-04 13:13 ` Sven Schnelle
2024-03-04 16:59 ` Sven Schnelle
0 siblings, 2 replies; 20+ messages in thread
From: Alex Bennée @ 2024-03-04 10:34 UTC (permalink / raw)
To: Sven Schnelle
Cc: Alexandre Iooss, Mahmoud Mandour, Pierrick Bouvier, qemu-devel,
deller
Sven Schnelle <svens@stackframe.org> writes:
> In preparation of making the parsing part of qemu_set_dfilter_ranges()
> available to other users, convert it to return a GList, so the result
> can be used with other functions taking a GList of struct Range.
Why do we need to convert it to a Glist? When I originally wrote the
dfilter code I deliberately chose GArray over GList to avoid bouncing
across cache lines during the tight loop that is checking ranges. It's
not like we can't pass GArray's to plugins as well?
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 01/12] util/log: convert debug_regions to GList
2024-03-04 10:34 ` Alex Bennée
@ 2024-03-04 13:13 ` Sven Schnelle
2024-03-04 17:00 ` Richard Henderson
2024-03-04 16:59 ` Sven Schnelle
1 sibling, 1 reply; 20+ messages in thread
From: Sven Schnelle @ 2024-03-04 13:13 UTC (permalink / raw)
To: Alex Bennée
Cc: Alexandre Iooss, Mahmoud Mandour, Pierrick Bouvier, qemu-devel,
deller
Alex Bennée <alex.bennee@linaro.org> writes:
> Sven Schnelle <svens@stackframe.org> writes:
>
>> In preparation of making the parsing part of qemu_set_dfilter_ranges()
>> available to other users, convert it to return a GList, so the result
>> can be used with other functions taking a GList of struct Range.
>
> Why do we need to convert it to a Glist? When I originally wrote the
> dfilter code I deliberately chose GArray over GList to avoid bouncing
> across cache lines during the tight loop that is checking ranges. It's
> not like we can't pass GArray's to plugins as well?
Good point. I'll change it back to a GArray in the next iteration.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 01/12] util/log: convert debug_regions to GList
2024-03-04 10:34 ` Alex Bennée
2024-03-04 13:13 ` Sven Schnelle
@ 2024-03-04 16:59 ` Sven Schnelle
2024-03-04 17:58 ` Alex Bennée
1 sibling, 1 reply; 20+ messages in thread
From: Sven Schnelle @ 2024-03-04 16:59 UTC (permalink / raw)
To: Alex Bennée
Cc: Alexandre Iooss, Mahmoud Mandour, Pierrick Bouvier, qemu-devel,
deller
Alex Bennée <alex.bennee@linaro.org> writes:
> Sven Schnelle <svens@stackframe.org> writes:
>
>> In preparation of making the parsing part of qemu_set_dfilter_ranges()
>> available to other users, convert it to return a GList, so the result
>> can be used with other functions taking a GList of struct Range.
>
> Why do we need to convert it to a Glist? When I originally wrote the
> dfilter code I deliberately chose GArray over GList to avoid bouncing
> across cache lines during the tight loop that is checking ranges. It's
> not like we can't pass GArray's to plugins as well?
Looking at the code again, i remember that the reason for choosing GList
was that the other range matching function all take GList's - having
some functions take GArray's, and some not would be odd. So i wonder
whether we should convert all of those functions to GArray? (if
possible, i haven't checked)
What do you think?
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 01/12] util/log: convert debug_regions to GList
2024-03-04 13:13 ` Sven Schnelle
@ 2024-03-04 17:00 ` Richard Henderson
0 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2024-03-04 17:00 UTC (permalink / raw)
To: Sven Schnelle, Alex Bennée
Cc: Alexandre Iooss, Mahmoud Mandour, Pierrick Bouvier, qemu-devel,
deller
On 3/4/24 03:13, Sven Schnelle wrote:
> Alex Bennée <alex.bennee@linaro.org> writes:
>
>> Sven Schnelle <svens@stackframe.org> writes:
>>
>>> In preparation of making the parsing part of qemu_set_dfilter_ranges()
>>> available to other users, convert it to return a GList, so the result
>>> can be used with other functions taking a GList of struct Range.
>>
>> Why do we need to convert it to a Glist? When I originally wrote the
>> dfilter code I deliberately chose GArray over GList to avoid bouncing
>> across cache lines during the tight loop that is checking ranges. It's
>> not like we can't pass GArray's to plugins as well?
>
> Good point. I'll change it back to a GArray in the next iteration.
How many address ranges do you expect to have?
If more than a couple, then perhaps IntervalTree would be better for a balanced binary search.
r~
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 01/12] util/log: convert debug_regions to GList
2024-03-04 16:59 ` Sven Schnelle
@ 2024-03-04 17:58 ` Alex Bennée
2024-03-04 19:12 ` Sven Schnelle
0 siblings, 1 reply; 20+ messages in thread
From: Alex Bennée @ 2024-03-04 17:58 UTC (permalink / raw)
To: Sven Schnelle
Cc: Alexandre Iooss, Mahmoud Mandour, Pierrick Bouvier, qemu-devel,
deller
Sven Schnelle <svens@stackframe.org> writes:
> Alex Bennée <alex.bennee@linaro.org> writes:
>
>> Sven Schnelle <svens@stackframe.org> writes:
>>
>>> In preparation of making the parsing part of qemu_set_dfilter_ranges()
>>> available to other users, convert it to return a GList, so the result
>>> can be used with other functions taking a GList of struct Range.
>>
>> Why do we need to convert it to a Glist? When I originally wrote the
>> dfilter code I deliberately chose GArray over GList to avoid bouncing
>> across cache lines during the tight loop that is checking ranges. It's
>> not like we can't pass GArray's to plugins as well?
>
> Looking at the code again, i remember that the reason for choosing GList
> was that the other range matching function all take GList's - having
> some functions take GArray's, and some not would be odd.
Ahh I see. There wasn't intended to be much of a relationship between
the dfilter code and the range code apart from the fact I re-used the
Range typedef to avoid duplication.
> So i wonder
> whether we should convert all of those functions to GArray? (if
> possible, i haven't checked)
I think that would depend on access patterns and flexibility. For the
dfilter there is no particular need for sorting and the principle
operation is a sequence of lookups. For the other use cases keeping a
sorted list and quick insertion might be more useful.
While its tempting to go on a wider re-factoring I would caution against
it so close to softfreeze.
> What do you think?
Lets stick to the dfilter case and worry about wider clean-ups later. As
Richard points out it might be the interval tree makes more sense for
some of these things.
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 01/12] util/log: convert debug_regions to GList
2024-03-04 17:58 ` Alex Bennée
@ 2024-03-04 19:12 ` Sven Schnelle
0 siblings, 0 replies; 20+ messages in thread
From: Sven Schnelle @ 2024-03-04 19:12 UTC (permalink / raw)
To: Alex Bennée
Cc: Alexandre Iooss, Mahmoud Mandour, Pierrick Bouvier, qemu-devel,
deller
Alex Bennée <alex.bennee@linaro.org> writes:
>> So i wonder
>> whether we should convert all of those functions to GArray? (if
>> possible, i haven't checked)
>
> I think that would depend on access patterns and flexibility. For the
> dfilter there is no particular need for sorting and the principle
> operation is a sequence of lookups. For the other use cases keeping a
> sorted list and quick insertion might be more useful.
>
> While its tempting to go on a wider re-factoring I would caution against
> it so close to softfreeze.
>
>> What do you think?
>
> Lets stick to the dfilter case and worry about wider clean-ups later. As
> Richard points out it might be the interval tree makes more sense for
> some of these things.
I think i go with the GArray variant for now. I'd guess that -dfilter is
usually only used with one or a few arguments, so using a Interval Tree
is probably not neccessary.
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2024-03-04 19:14 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-01 17:45 [PATCH v3 00/12] plugins/execlog: add data address match and address range support Sven Schnelle
2024-03-01 17:45 ` [PATCH v3 01/12] util/log: convert debug_regions to GList Sven Schnelle
2024-03-04 10:34 ` Alex Bennée
2024-03-04 13:13 ` Sven Schnelle
2024-03-04 17:00 ` Richard Henderson
2024-03-04 16:59 ` Sven Schnelle
2024-03-04 17:58 ` Alex Bennée
2024-03-04 19:12 ` Sven Schnelle
2024-03-01 17:45 ` [PATCH v3 02/12] util/log: make qemu_set_dfilter_ranges() take a GList Sven Schnelle
2024-03-01 17:46 ` [PATCH v3 03/12] util/range: move range_list_from_string() to range.c Sven Schnelle
2024-03-01 17:46 ` [PATCH v3 04/12] util/range: add range_list_free() Sven Schnelle
2024-03-01 17:46 ` [PATCH v3 05/12] util/range: use append_new_range() in range_list_from_string() Sven Schnelle
2024-03-01 17:46 ` [PATCH v3 06/12] util/range: split up range_list_from_string() Sven Schnelle
2024-03-01 17:46 ` [PATCH v3 07/12] util/range: make range_list_from_string() accept a single number Sven Schnelle
2024-03-01 17:46 ` [PATCH v3 08/12] qemu/range: add range_list_contains() function Sven Schnelle
2024-03-01 17:46 ` [PATCH v3 09/12] plugins: add API to print errors Sven Schnelle
2024-03-01 17:46 ` [PATCH v3 10/12] plugins: add range list API Sven Schnelle
2024-03-03 17:45 ` Bernhard Beschow
2024-03-01 17:46 ` [PATCH v3 11/12] plugins/execlog: use range list api Sven Schnelle
2024-03-01 17:46 ` [PATCH v3 12/12] plugins/execlog: add data address match Sven Schnelle
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).