@@ -416,6 +416,9 @@ static void free_trace_fprobe(struct trace_fprobe *tf)
416
416
}
417
417
}
418
418
419
+ /* Since alloc_trace_fprobe() can return error, check the pointer is ERR too. */
420
+ DEFINE_FREE (free_trace_fprobe , struct trace_fprobe * , if (!IS_ERR_OR_NULL (_T )) free_trace_fprobe (_T ))
421
+
419
422
/*
420
423
* Allocate new trace_probe and initialize it (including fprobe).
421
424
*/
@@ -426,7 +429,7 @@ static struct trace_fprobe *alloc_trace_fprobe(const char *group,
426
429
struct module * mod ,
427
430
int nargs , bool is_return )
428
431
{
429
- struct trace_fprobe * tf ;
432
+ struct trace_fprobe * tf __free ( free_trace_fprobe ) = NULL ;
430
433
int ret = - ENOMEM ;
431
434
432
435
tf = kzalloc (struct_size (tf , tp .args , nargs ), GFP_KERNEL );
@@ -435,7 +438,7 @@ static struct trace_fprobe *alloc_trace_fprobe(const char *group,
435
438
436
439
tf -> symbol = kstrdup (symbol , GFP_KERNEL );
437
440
if (!tf -> symbol )
438
- goto error ;
441
+ return ERR_PTR ( - ENOMEM ) ;
439
442
440
443
if (is_return )
441
444
tf -> fp .exit_handler = fexit_dispatcher ;
@@ -447,13 +450,10 @@ static struct trace_fprobe *alloc_trace_fprobe(const char *group,
447
450
448
451
ret = trace_probe_init (& tf -> tp , event , group , false, nargs );
449
452
if (ret < 0 )
450
- goto error ;
453
+ return ERR_PTR ( ret ) ;
451
454
452
455
dyn_event_init (& tf -> devent , & trace_fprobe_ops );
453
- return tf ;
454
- error :
455
- free_trace_fprobe (tf );
456
- return ERR_PTR (ret );
456
+ return_ptr (tf );
457
457
}
458
458
459
459
static struct trace_fprobe * find_trace_fprobe (const char * event ,
@@ -880,14 +880,12 @@ static int register_trace_fprobe(struct trace_fprobe *tf)
880
880
struct trace_fprobe * old_tf ;
881
881
int ret ;
882
882
883
- mutex_lock (& event_mutex );
883
+ guard ( mutex ) (& event_mutex );
884
884
885
885
old_tf = find_trace_fprobe (trace_probe_name (& tf -> tp ),
886
886
trace_probe_group_name (& tf -> tp ));
887
- if (old_tf ) {
888
- ret = append_trace_fprobe (tf , old_tf );
889
- goto end ;
890
- }
887
+ if (old_tf )
888
+ return append_trace_fprobe (tf , old_tf );
891
889
892
890
/* Register new event */
893
891
ret = register_fprobe_event (tf );
@@ -897,7 +895,7 @@ static int register_trace_fprobe(struct trace_fprobe *tf)
897
895
trace_probe_log_err (0 , EVENT_EXIST );
898
896
} else
899
897
pr_warn ("Failed to register probe event(%d)\n" , ret );
900
- goto end ;
898
+ return ret ;
901
899
}
902
900
903
901
/* Register fprobe */
@@ -907,8 +905,6 @@ static int register_trace_fprobe(struct trace_fprobe *tf)
907
905
else
908
906
dyn_event_add (& tf -> devent , trace_probe_event_call (& tf -> tp ));
909
907
910
- end :
911
- mutex_unlock (& event_mutex );
912
908
return ret ;
913
909
}
914
910
@@ -1069,7 +1065,10 @@ static int parse_symbol_and_return(int argc, const char *argv[],
1069
1065
return 0 ;
1070
1066
}
1071
1067
1072
- static int __trace_fprobe_create (int argc , const char * argv [])
1068
+ DEFINE_FREE (module_put , struct module * , if (_T ) module_put (_T ))
1069
+
1070
+ static int trace_fprobe_create_internal (int argc , const char * argv [],
1071
+ struct traceprobe_parse_context * ctx )
1073
1072
{
1074
1073
/*
1075
1074
* Argument syntax:
@@ -1095,23 +1094,20 @@ static int __trace_fprobe_create(int argc, const char *argv[])
1095
1094
* Type of args:
1096
1095
* FETCHARG:TYPE : use TYPE instead of unsigned long.
1097
1096
*/
1098
- struct trace_fprobe * tf = NULL ;
1097
+ struct trace_fprobe * tf __free ( free_trace_fprobe ) = NULL ;
1099
1098
int i , new_argc = 0 , ret = 0 ;
1100
1099
bool is_return = false;
1101
- char * symbol = NULL ;
1100
+ char * symbol __free ( kfree ) = NULL ;
1102
1101
const char * event = NULL , * group = FPROBE_EVENT_SYSTEM ;
1103
- const char * * new_argv = NULL ;
1102
+ const char * * new_argv __free ( kfree ) = NULL ;
1104
1103
char buf [MAX_EVENT_NAME_LEN ];
1105
1104
char gbuf [MAX_EVENT_NAME_LEN ];
1106
1105
char sbuf [KSYM_NAME_LEN ];
1107
1106
char abuf [MAX_BTF_ARGS_LEN ];
1108
- char * dbuf = NULL ;
1107
+ char * dbuf __free ( kfree ) = NULL ;
1109
1108
bool is_tracepoint = false;
1110
- struct module * tp_mod = NULL ;
1109
+ struct module * tp_mod __free ( module_put ) = NULL ;
1111
1110
struct tracepoint * tpoint = NULL ;
1112
- struct traceprobe_parse_context ctx = {
1113
- .flags = TPARG_FL_KERNEL | TPARG_FL_FPROBE ,
1114
- };
1115
1111
1116
1112
if ((argv [0 ][0 ] != 'f' && argv [0 ][0 ] != 't' ) || argc < 2 )
1117
1113
return - ECANCELED ;
@@ -1121,13 +1117,11 @@ static int __trace_fprobe_create(int argc, const char *argv[])
1121
1117
group = TRACEPOINT_EVENT_SYSTEM ;
1122
1118
}
1123
1119
1124
- trace_probe_log_init ("trace_fprobe" , argc , argv );
1125
-
1126
1120
if (argv [0 ][1 ] != '\0' ) {
1127
1121
if (argv [0 ][1 ] != ':' ) {
1128
1122
trace_probe_log_set_index (0 );
1129
1123
trace_probe_log_err (1 , BAD_MAXACT );
1130
- goto parse_error ;
1124
+ return - EINVAL ;
1131
1125
}
1132
1126
event = & argv [0 ][2 ];
1133
1127
}
@@ -1137,14 +1131,14 @@ static int __trace_fprobe_create(int argc, const char *argv[])
1137
1131
/* a symbol(or tracepoint) must be specified */
1138
1132
ret = parse_symbol_and_return (argc , argv , & symbol , & is_return , is_tracepoint );
1139
1133
if (ret < 0 )
1140
- goto parse_error ;
1134
+ return - EINVAL ;
1141
1135
1142
1136
trace_probe_log_set_index (0 );
1143
1137
if (event ) {
1144
1138
ret = traceprobe_parse_event_name (& event , & group , gbuf ,
1145
1139
event - argv [0 ]);
1146
1140
if (ret )
1147
- goto parse_error ;
1141
+ return - EINVAL ;
1148
1142
}
1149
1143
1150
1144
if (!event ) {
@@ -1160,49 +1154,44 @@ static int __trace_fprobe_create(int argc, const char *argv[])
1160
1154
}
1161
1155
1162
1156
if (is_return )
1163
- ctx . flags |= TPARG_FL_RETURN ;
1157
+ ctx -> flags |= TPARG_FL_RETURN ;
1164
1158
else
1165
- ctx . flags |= TPARG_FL_FENTRY ;
1159
+ ctx -> flags |= TPARG_FL_FENTRY ;
1166
1160
1167
1161
if (is_tracepoint ) {
1168
- ctx . flags |= TPARG_FL_TPOINT ;
1162
+ ctx -> flags |= TPARG_FL_TPOINT ;
1169
1163
tpoint = find_tracepoint (symbol , & tp_mod );
1170
1164
if (tpoint ) {
1171
- ctx . funcname = kallsyms_lookup (
1165
+ ctx -> funcname = kallsyms_lookup (
1172
1166
(unsigned long )tpoint -> probestub ,
1173
1167
NULL , NULL , NULL , sbuf );
1174
1168
} else if (IS_ENABLED (CONFIG_MODULES )) {
1175
1169
/* This *may* be loaded afterwards */
1176
1170
tpoint = TRACEPOINT_STUB ;
1177
- ctx . funcname = symbol ;
1171
+ ctx -> funcname = symbol ;
1178
1172
} else {
1179
1173
trace_probe_log_set_index (1 );
1180
1174
trace_probe_log_err (0 , NO_TRACEPOINT );
1181
- goto parse_error ;
1175
+ return - EINVAL ;
1182
1176
}
1183
1177
} else
1184
- ctx . funcname = symbol ;
1178
+ ctx -> funcname = symbol ;
1185
1179
1186
1180
argc -= 2 ; argv += 2 ;
1187
1181
new_argv = traceprobe_expand_meta_args (argc , argv , & new_argc ,
1188
- abuf , MAX_BTF_ARGS_LEN , & ctx );
1189
- if (IS_ERR (new_argv )) {
1190
- ret = PTR_ERR (new_argv );
1191
- new_argv = NULL ;
1192
- goto out ;
1193
- }
1182
+ abuf , MAX_BTF_ARGS_LEN , ctx );
1183
+ if (IS_ERR (new_argv ))
1184
+ return PTR_ERR (new_argv );
1194
1185
if (new_argv ) {
1195
1186
argc = new_argc ;
1196
1187
argv = new_argv ;
1197
1188
}
1198
- if (argc > MAX_TRACE_ARGS ) {
1199
- ret = - E2BIG ;
1200
- goto out ;
1201
- }
1189
+ if (argc > MAX_TRACE_ARGS )
1190
+ return - E2BIG ;
1202
1191
1203
1192
ret = traceprobe_expand_dentry_args (argc , argv , & dbuf );
1204
1193
if (ret )
1205
- goto out ;
1194
+ return ret ;
1206
1195
1207
1196
/* setup a probe */
1208
1197
tf = alloc_trace_fprobe (group , event , symbol , tpoint , tp_mod ,
@@ -1211,16 +1200,16 @@ static int __trace_fprobe_create(int argc, const char *argv[])
1211
1200
ret = PTR_ERR (tf );
1212
1201
/* This must return -ENOMEM, else there is a bug */
1213
1202
WARN_ON_ONCE (ret != - ENOMEM );
1214
- goto out ; /* We know tf is not allocated */
1203
+ return ret ;
1215
1204
}
1216
1205
1217
1206
/* parse arguments */
1218
1207
for (i = 0 ; i < argc ; i ++ ) {
1219
1208
trace_probe_log_set_index (i + 2 );
1220
- ctx . offset = 0 ;
1221
- ret = traceprobe_parse_probe_arg (& tf -> tp , i , argv [i ], & ctx );
1209
+ ctx -> offset = 0 ;
1210
+ ret = traceprobe_parse_probe_arg (& tf -> tp , i , argv [i ], ctx );
1222
1211
if (ret )
1223
- goto error ; /* This can be -ENOMEM */
1212
+ return ret ; /* This can be -ENOMEM */
1224
1213
}
1225
1214
1226
1215
if (is_return && tf -> tp .entry_arg ) {
@@ -1231,7 +1220,7 @@ static int __trace_fprobe_create(int argc, const char *argv[])
1231
1220
ret = traceprobe_set_print_fmt (& tf -> tp ,
1232
1221
is_return ? PROBE_PRINT_RETURN : PROBE_PRINT_NORMAL );
1233
1222
if (ret < 0 )
1234
- goto error ;
1223
+ return ret ;
1235
1224
1236
1225
ret = register_trace_fprobe (tf );
1237
1226
if (ret ) {
@@ -1242,29 +1231,32 @@ static int __trace_fprobe_create(int argc, const char *argv[])
1242
1231
trace_probe_log_err (0 , BAD_PROBE_ADDR );
1243
1232
else if (ret != - ENOMEM && ret != - EEXIST )
1244
1233
trace_probe_log_err (0 , FAIL_REG_PROBE );
1245
- goto error ;
1234
+ return - EINVAL ;
1246
1235
}
1247
1236
1248
- out :
1249
- if (tp_mod )
1250
- module_put (tp_mod );
1237
+ /* 'tf' is successfully registered. To avoid freeing, assign NULL. */
1238
+ tf = NULL ;
1239
+
1240
+ return 0 ;
1241
+ }
1242
+
1243
+ static int trace_fprobe_create_cb (int argc , const char * argv [])
1244
+ {
1245
+ struct traceprobe_parse_context ctx = {
1246
+ .flags = TPARG_FL_KERNEL | TPARG_FL_FPROBE ,
1247
+ };
1248
+ int ret ;
1249
+
1250
+ trace_probe_log_init ("trace_fprobe" , argc , argv );
1251
+ ret = trace_fprobe_create_internal (argc , argv , & ctx );
1251
1252
traceprobe_finish_parse (& ctx );
1252
1253
trace_probe_log_clear ();
1253
- kfree (new_argv );
1254
- kfree (symbol );
1255
- kfree (dbuf );
1256
1254
return ret ;
1257
-
1258
- parse_error :
1259
- ret = - EINVAL ;
1260
- error :
1261
- free_trace_fprobe (tf );
1262
- goto out ;
1263
1255
}
1264
1256
1265
1257
static int trace_fprobe_create (const char * raw_command )
1266
1258
{
1267
- return trace_probe_create (raw_command , __trace_fprobe_create );
1259
+ return trace_probe_create (raw_command , trace_fprobe_create_cb );
1268
1260
}
1269
1261
1270
1262
static int trace_fprobe_release (struct dyn_event * ev )
0 commit comments