@@ -304,16 +304,6 @@ static int parse_trace_event_arg(char *arg, struct fetch_insn *code,
304304
305305#ifdef CONFIG_PROBE_EVENTS_BTF_ARGS
306306
307- static struct btf * traceprobe_get_btf (void )
308- {
309- struct btf * btf = bpf_get_btf_vmlinux ();
310-
311- if (IS_ERR_OR_NULL (btf ))
312- return NULL ;
313-
314- return btf ;
315- }
316-
317307static u32 btf_type_int (const struct btf_type * t )
318308{
319309 return * (u32 * )(t + 1 );
@@ -371,42 +361,49 @@ static const char *type_from_btf_id(struct btf *btf, s32 id)
371361 return NULL ;
372362}
373363
374- static const struct btf_type * find_btf_func_proto (const char * funcname )
364+ static const struct btf_type * find_btf_func_proto (const char * funcname ,
365+ struct btf * * btf_p )
375366{
376- struct btf * btf = traceprobe_get_btf ();
377367 const struct btf_type * t ;
368+ struct btf * btf = NULL ;
378369 s32 id ;
379370
380- if (!btf || ! funcname )
371+ if (!funcname )
381372 return ERR_PTR (- EINVAL );
382373
383- id = btf_find_by_name_kind ( btf , funcname , BTF_KIND_FUNC );
374+ id = bpf_find_btf_id ( funcname , BTF_KIND_FUNC , & btf );
384375 if (id <= 0 )
385376 return ERR_PTR (- ENOENT );
386377
387378 /* Get BTF_KIND_FUNC type */
388379 t = btf_type_by_id (btf , id );
389380 if (!t || !btf_type_is_func (t ))
390- return ERR_PTR ( - ENOENT ) ;
381+ goto err ;
391382
392383 /* The type of BTF_KIND_FUNC is BTF_KIND_FUNC_PROTO */
393384 t = btf_type_by_id (btf , t -> type );
394385 if (!t || !btf_type_is_func_proto (t ))
395- return ERR_PTR ( - ENOENT ) ;
386+ goto err ;
396387
388+ * btf_p = btf ;
397389 return t ;
390+
391+ err :
392+ btf_put (btf );
393+ return ERR_PTR (- ENOENT );
398394}
399395
400396static const struct btf_param * find_btf_func_param (const char * funcname , s32 * nr ,
401- bool tracepoint )
397+ struct btf * * btf_p , bool tracepoint )
402398{
403399 const struct btf_param * param ;
404400 const struct btf_type * t ;
401+ struct btf * btf ;
405402
406403 if (!funcname || !nr )
407404 return ERR_PTR (- EINVAL );
408405
409- t = find_btf_func_proto (funcname );
406+ t = find_btf_func_proto (funcname , & btf );
410407 if (IS_ERR (t ))
411408 return (const struct btf_param * )t ;
412409
@@ -419,29 +416,37 @@ static const struct btf_param *find_btf_func_param(const char *funcname, s32 *nr
419416 param ++ ;
420417 }
421418
422- if (* nr > 0 )
419+ if (* nr > 0 ) {
420+ * btf_p = btf ;
423421 return param ;
424- else
425- return NULL ;
422+ }
423+
424+ btf_put (btf );
425+ return NULL ;
426+ }
427+
428+ static void clear_btf_context (struct traceprobe_parse_context * ctx )
429+ {
430+ if (ctx -> btf ) {
431+ btf_put (ctx -> btf );
432+ ctx -> btf = NULL ;
433+ ctx -> params = NULL ;
434+ ctx -> nr_params = 0 ;
435+ }
426436}
427437
428438static int parse_btf_arg (const char * varname , struct fetch_insn * code ,
429439 struct traceprobe_parse_context * ctx )
430440{
431- struct btf * btf = traceprobe_get_btf ();
432441 const struct btf_param * params ;
433442 int i ;
434443
435- if (!btf ) {
436- trace_probe_log_err (ctx -> offset , NOSUP_BTFARG );
437- return - EOPNOTSUPP ;
438- }
439-
440444 if (WARN_ON_ONCE (!ctx -> funcname ))
441445 return - EINVAL ;
442446
443447 if (!ctx -> params ) {
444- params = find_btf_func_param (ctx -> funcname , & ctx -> nr_params ,
448+ params = find_btf_func_param (ctx -> funcname ,
449+ & ctx -> nr_params , & ctx -> btf ,
445450 ctx -> flags & TPARG_FL_TPOINT );
446451 if (IS_ERR_OR_NULL (params )) {
447452 trace_probe_log_err (ctx -> offset , NO_BTF_ENTRY );
@@ -452,7 +457,7 @@ static int parse_btf_arg(const char *varname, struct fetch_insn *code,
452457 params = ctx -> params ;
453458
454459 for (i = 0 ; i < ctx -> nr_params ; i ++ ) {
455- const char * name = btf_name_by_offset (btf , params [i ].name_off );
460+ const char * name = btf_name_by_offset (ctx -> btf , params [i ].name_off );
456461
457462 if (name && !strcmp (name , varname )) {
458463 code -> op = FETCH_OP_ARG ;
@@ -470,7 +475,7 @@ static int parse_btf_arg(const char *varname, struct fetch_insn *code,
470475static const struct fetch_type * parse_btf_arg_type (int arg_idx ,
471476 struct traceprobe_parse_context * ctx )
472477{
473- struct btf * btf = traceprobe_get_btf () ;
478+ struct btf * btf = ctx -> btf ;
474479 const char * typestr = NULL ;
475480
476481 if (btf && ctx -> params ) {
@@ -485,14 +490,17 @@ static const struct fetch_type *parse_btf_arg_type(int arg_idx,
485490static const struct fetch_type * parse_btf_retval_type (
486491 struct traceprobe_parse_context * ctx )
487492{
488- struct btf * btf = traceprobe_get_btf ();
489493 const char * typestr = NULL ;
490494 const struct btf_type * t ;
495+ struct btf * btf ;
491496
492- if (btf && ctx -> funcname ) {
493- t = find_btf_func_proto (ctx -> funcname );
494- if (!IS_ERR (t ))
497+ if (ctx -> funcname ) {
498+ /* Do not use ctx->btf, because it must be used with ctx->param */
499+ t = find_btf_func_proto (ctx -> funcname , & btf );
500+ if (!IS_ERR (t )) {
495501 typestr = type_from_btf_id (btf , t -> type );
502+ btf_put (btf );
503+ }
496504 }
497505
498506 return find_fetch_type (typestr , ctx -> flags );
@@ -501,21 +509,25 @@ static const struct fetch_type *parse_btf_retval_type(
501509static bool is_btf_retval_void (const char * funcname )
502510{
503511 const struct btf_type * t ;
512+ struct btf * btf ;
513+ bool ret ;
504514
505- t = find_btf_func_proto (funcname );
515+ t = find_btf_func_proto (funcname , & btf );
506516 if (IS_ERR (t ))
507517 return false;
508518
509- return t -> type == 0 ;
519+ ret = (t -> type == 0 );
520+ btf_put (btf );
521+ return ret ;
510522}
511523#else
512- static struct btf * traceprobe_get_btf ( void )
524+ static void clear_btf_context ( struct traceprobe_parse_context * ctx )
513525{
514- return NULL ;
526+ ctx -> btf = NULL ;
515527}
516528
517529static const struct btf_param * find_btf_func_param (const char * funcname , s32 * nr ,
518- bool tracepoint )
530+ struct btf * * btf_p , bool tracepoint )
519531{
520532 return ERR_PTR (- EOPNOTSUPP );
521533}
@@ -1231,15 +1243,14 @@ static int sprint_nth_btf_arg(int idx, const char *type,
12311243 char * buf , int bufsize ,
12321244 struct traceprobe_parse_context * ctx )
12331245{
1234- struct btf * btf = traceprobe_get_btf ();
12351246 const char * name ;
12361247 int ret ;
12371248
12381249 if (idx >= ctx -> nr_params ) {
12391250 trace_probe_log_err (0 , NO_BTFARG );
12401251 return - ENOENT ;
12411252 }
1242- name = btf_name_by_offset (btf , ctx -> params [idx ].name_off );
1253+ name = btf_name_by_offset (ctx -> btf , ctx -> params [idx ].name_off );
12431254 if (!name ) {
12441255 trace_probe_log_err (0 , NO_BTF_ENTRY );
12451256 return - ENOENT ;
@@ -1271,7 +1282,7 @@ const char **traceprobe_expand_meta_args(int argc, const char *argv[],
12711282 return NULL ;
12721283 }
12731284
1274- params = find_btf_func_param (ctx -> funcname , & nr_params ,
1285+ params = find_btf_func_param (ctx -> funcname , & nr_params , & ctx -> btf ,
12751286 ctx -> flags & TPARG_FL_TPOINT );
12761287 if (IS_ERR_OR_NULL (params )) {
12771288 if (args_idx != -1 ) {
@@ -1337,6 +1348,11 @@ const char **traceprobe_expand_meta_args(int argc, const char *argv[],
13371348 return ERR_PTR (ret );
13381349}
13391350
1351+ void traceprobe_finish_parse (struct traceprobe_parse_context * ctx )
1352+ {
1353+ clear_btf_context (ctx );
1354+ }
1355+
13401356int traceprobe_update_arg (struct probe_arg * arg )
13411357{
13421358 struct fetch_insn * code = arg -> code ;
0 commit comments