From 6af2e78f07ff6e10d30f6e7ec8ae460aaed751d1 Mon Sep 17 00:00:00 2001 From: Richard Chang Date: Wed, 4 Jun 2025 06:39:04 +0000 Subject: [PATCH] ANDROID: fix ABI breakage for trace_array extensions To avoid breaking the ABI, we change trace_array_get_by_name() back to original API and introduce the new extension API trace_array_get_by_name_ext() and a wrapper struct trace_array_ext to support creating instances with specified system events. Bug: 418940629 Change-Id: I197b52af15d41b3ab56a5d94172cfa532d24ee4b Signed-off-by: Richard Chang --- drivers/scsi/qla2xxx/qla_os.c | 2 +- include/linux/trace.h | 11 +++++++-- kernel/trace/trace.c | 36 +++++++++++++++++++---------- kernel/trace/trace.h | 6 ++++- kernel/trace/trace_boot.c | 2 +- kernel/trace/trace_events.c | 5 +++- samples/ftrace/sample-trace-array.c | 3 ++- 7 files changed, 46 insertions(+), 19 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 0a3a5af67f0a..91d12198cc6c 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2883,7 +2883,7 @@ static void qla2x00_iocb_work_fn(struct work_struct *work) static void qla_trace_init(void) { - qla_trc_array = trace_array_get_by_name("qla2xxx", NULL); + qla_trc_array = trace_array_get_by_name("qla2xxx"); if (!qla_trc_array) { ql_log(ql_log_fatal, NULL, 0x0001, "Unable to create qla2xxx trace instance, instance logging will be disabled.\n"); diff --git a/include/linux/trace.h b/include/linux/trace.h index fdcd76b7be83..bb7eadcc0075 100644 --- a/include/linux/trace.h +++ b/include/linux/trace.h @@ -51,7 +51,9 @@ int trace_array_printk(struct trace_array *tr, unsigned long ip, const char *fmt, ...); int trace_array_init_printk(struct trace_array *tr); void trace_array_put(struct trace_array *tr); -struct trace_array *trace_array_get_by_name(const char *name, const char *systems); +struct trace_array *trace_array_get_by_name(const char *name); +struct trace_array *trace_array_get_by_name_ext(const char *name, + const char *systems); int trace_array_destroy(struct trace_array *tr); /* For osnoise tracer */ @@ -84,7 +86,12 @@ static inline int trace_array_init_printk(struct trace_array *tr) static inline void trace_array_put(struct trace_array *tr) { } -static inline struct trace_array *trace_array_get_by_name(const char *name, const char *systems) +static inline struct trace_array *trace_array_get_by_name(const char *name) +{ + return NULL; +} +static inline struct trace_array *trace_array_get_by_name_ext( + const char *name, const char *systems) { return NULL; } diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index eeb19f425d72..36dfdf60a172 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -9545,14 +9545,16 @@ static int trace_array_create_dir(struct trace_array *tr) static struct trace_array * trace_array_create_systems(const char *name, const char *systems) { + struct trace_array_ext *tr_ext; struct trace_array *tr; int ret; ret = -ENOMEM; - tr = kzalloc(sizeof(*tr), GFP_KERNEL); - if (!tr) + tr_ext = kzalloc(sizeof(*tr_ext), GFP_KERNEL); + if (!tr_ext) return ERR_PTR(ret); + tr = &tr_ext->trace_array; tr->name = kstrdup(name, GFP_KERNEL); if (!tr->name) goto out_free_tr; @@ -9564,8 +9566,8 @@ trace_array_create_systems(const char *name, const char *systems) goto out_free_tr; if (systems) { - tr->system_names = kstrdup_const(systems, GFP_KERNEL); - if (!tr->system_names) + tr_ext->system_names = kstrdup_const(systems, GFP_KERNEL); + if (!tr_ext->system_names) goto out_free_tr; } @@ -9612,9 +9614,9 @@ trace_array_create_systems(const char *name, const char *systems) free_trace_buffers(tr); free_cpumask_var(tr->pipe_cpumask); free_cpumask_var(tr->tracing_cpumask); - kfree_const(tr->system_names); + kfree_const(tr_ext->system_names); kfree(tr->name); - kfree(tr); + kfree(tr_ext); return ERR_PTR(ret); } @@ -9646,8 +9648,14 @@ out_unlock: return ret; } +struct trace_array *trace_array_get_by_name(const char *name) +{ + return trace_array_get_by_name_ext(name, NULL); +} +EXPORT_SYMBOL_GPL(trace_array_get_by_name); + /** - * trace_array_get_by_name - Create/Lookup a trace array, given its name. + * trace_array_get_by_name_ext - Create/Lookup a trace array, given its name. * @name: The name of the trace array to be looked up/created. * @systems: A list of systems to create event directories for (NULL for all) * @@ -9663,7 +9671,8 @@ out_unlock: * trace_array_put() is called, user space can not delete it. * */ -struct trace_array *trace_array_get_by_name(const char *name, const char *systems) +struct trace_array *trace_array_get_by_name_ext(const char *name, + const char *systems) { struct trace_array *tr; @@ -9687,11 +9696,14 @@ out_unlock: mutex_unlock(&event_mutex); return tr; } -EXPORT_SYMBOL_GPL(trace_array_get_by_name); +EXPORT_SYMBOL_GPL(trace_array_get_by_name_ext); static int __remove_instance(struct trace_array *tr) { int i; + struct trace_array_ext *tr_ext = container_of(tr, + struct trace_array_ext, + trace_array); /* Reference counter for a newly created trace array = 1. */ if (tr->ref > 1 || (tr->current_trace && tr->trace_ref)) @@ -9722,9 +9734,9 @@ static int __remove_instance(struct trace_array *tr) free_cpumask_var(tr->pipe_cpumask); free_cpumask_var(tr->tracing_cpumask); - kfree_const(tr->system_names); + kfree_const(tr_ext->system_names); kfree(tr->name); - kfree(tr); + kfree(tr_ext); return 0; } @@ -10527,7 +10539,7 @@ __init static void enable_instances(void) if (IS_ENABLED(CONFIG_TRACER_MAX_TRACE)) do_allocate_snapshot(tok); - tr = trace_array_get_by_name(tok, NULL); + tr = trace_array_get_by_name(tok); if (!tr) { pr_warn("Failed to create instance buffer %s\n", curr_str); continue; diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index eca7435c25b4..1067161269c8 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -377,7 +377,6 @@ struct trace_array { unsigned char trace_flags_index[TRACE_FLAGS_MAX_SIZE]; unsigned int flags; raw_spinlock_t start_lock; - const char *system_names; struct list_head err_log; struct dentry *dir; struct dentry *options; @@ -413,6 +412,11 @@ struct trace_array { struct trace_func_repeats __percpu *last_func_repeats; }; +struct trace_array_ext { + const char *system_names; + struct trace_array trace_array; +}; + enum { TRACE_ARRAY_FL_GLOBAL = (1 << 0) }; diff --git a/kernel/trace/trace_boot.c b/kernel/trace/trace_boot.c index dbe29b4c6a7a..7ccc7a8e155b 100644 --- a/kernel/trace/trace_boot.c +++ b/kernel/trace/trace_boot.c @@ -633,7 +633,7 @@ trace_boot_init_instances(struct xbc_node *node) if (!p || *p == '\0') continue; - tr = trace_array_get_by_name(p, NULL); + tr = trace_array_get_by_name(p); if (!tr) { pr_err("Failed to get trace instance %s\n", p); continue; diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index fbf02aa83848..3901232f413c 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -3070,8 +3070,11 @@ trace_create_new_event(struct trace_event_call *call, struct trace_pid_list *pid_list; struct trace_event_file *file; unsigned int first; + struct trace_array_ext *tr_ext = container_of(tr, + struct trace_array_ext, + trace_array); - if (!event_in_systems(call, tr->system_names)) + if (!event_in_systems(call, tr_ext->system_names)) return NULL; file = kmem_cache_alloc(file_cachep, GFP_TRACE); diff --git a/samples/ftrace/sample-trace-array.c b/samples/ftrace/sample-trace-array.c index d0ee9001c7b3..d1b2f4f9c513 100644 --- a/samples/ftrace/sample-trace-array.c +++ b/samples/ftrace/sample-trace-array.c @@ -105,7 +105,8 @@ static int __init sample_trace_array_init(void) * NOTE: This function increments the reference counter * associated with the trace array - "tr". */ - tr = trace_array_get_by_name("sample-instance", "sched,timer,kprobes"); + tr = trace_array_get_by_name_ext("sample-instance", + "sched,timer,kprobes"); if (!tr) return -1;