@@ -7892,13 +7892,6 @@ bpf_object__load_progs(struct bpf_object *obj, int log_level)
78927892 size_t i ;
78937893 int err ;
78947894
7895- for (i = 0 ; i < obj -> nr_programs ; i ++ ) {
7896- prog = & obj -> programs [i ];
7897- err = bpf_object__sanitize_prog (obj , prog );
7898- if (err )
7899- return err ;
7900- }
7901-
79027895 for (i = 0 ; i < obj -> nr_programs ; i ++ ) {
79037896 prog = & obj -> programs [i ];
79047897 if (prog_is_subprog (obj , prog ))
@@ -7924,6 +7917,21 @@ bpf_object__load_progs(struct bpf_object *obj, int log_level)
79247917 return 0 ;
79257918}
79267919
7920+ static int bpf_object_prepare_progs (struct bpf_object * obj )
7921+ {
7922+ struct bpf_program * prog ;
7923+ size_t i ;
7924+ int err ;
7925+
7926+ for (i = 0 ; i < obj -> nr_programs ; i ++ ) {
7927+ prog = & obj -> programs [i ];
7928+ err = bpf_object__sanitize_prog (obj , prog );
7929+ if (err )
7930+ return err ;
7931+ }
7932+ return 0 ;
7933+ }
7934+
79277935static const struct bpf_sec_def * find_sec_def (const char * sec_name );
79287936
79297937static int bpf_object_init_progs (struct bpf_object * obj , const struct bpf_object_open_opts * opts )
@@ -8540,9 +8548,72 @@ static int bpf_object_prepare_struct_ops(struct bpf_object *obj)
85408548 return 0 ;
85418549}
85428550
8551+ static void bpf_object_unpin (struct bpf_object * obj )
8552+ {
8553+ int i ;
8554+
8555+ /* unpin any maps that were auto-pinned during load */
8556+ for (i = 0 ; i < obj -> nr_maps ; i ++ )
8557+ if (obj -> maps [i ].pinned && !obj -> maps [i ].reused )
8558+ bpf_map__unpin (& obj -> maps [i ], NULL );
8559+ }
8560+
8561+ static void bpf_object_post_load_cleanup (struct bpf_object * obj )
8562+ {
8563+ int i ;
8564+
8565+ /* clean up fd_array */
8566+ zfree (& obj -> fd_array );
8567+
8568+ /* clean up module BTFs */
8569+ for (i = 0 ; i < obj -> btf_module_cnt ; i ++ ) {
8570+ close (obj -> btf_modules [i ].fd );
8571+ btf__free (obj -> btf_modules [i ].btf );
8572+ free (obj -> btf_modules [i ].name );
8573+ }
8574+ obj -> btf_module_cnt = 0 ;
8575+ zfree (& obj -> btf_modules );
8576+
8577+ /* clean up vmlinux BTF */
8578+ btf__free (obj -> btf_vmlinux );
8579+ obj -> btf_vmlinux = NULL ;
8580+ }
8581+
8582+ static int bpf_object_prepare (struct bpf_object * obj , const char * target_btf_path )
8583+ {
8584+ int err ;
8585+
8586+ if (obj -> state >= OBJ_PREPARED ) {
8587+ pr_warn ("object '%s': prepare loading can't be attempted twice\n" , obj -> name );
8588+ return - EINVAL ;
8589+ }
8590+
8591+ err = bpf_object_prepare_token (obj );
8592+ err = err ? : bpf_object__probe_loading (obj );
8593+ err = err ? : bpf_object__load_vmlinux_btf (obj , false);
8594+ err = err ? : bpf_object__resolve_externs (obj , obj -> kconfig );
8595+ err = err ? : bpf_object__sanitize_maps (obj );
8596+ err = err ? : bpf_object__init_kern_struct_ops_maps (obj );
8597+ err = err ? : bpf_object_adjust_struct_ops_autoload (obj );
8598+ err = err ? : bpf_object__relocate (obj , obj -> btf_custom_path ? : target_btf_path );
8599+ err = err ? : bpf_object__sanitize_and_load_btf (obj );
8600+ err = err ? : bpf_object__create_maps (obj );
8601+ err = err ? : bpf_object_prepare_progs (obj );
8602+
8603+ if (err ) {
8604+ bpf_object_unpin (obj );
8605+ bpf_object_unload (obj );
8606+ obj -> state = OBJ_LOADED ;
8607+ return err ;
8608+ }
8609+
8610+ obj -> state = OBJ_PREPARED ;
8611+ return 0 ;
8612+ }
8613+
85438614static int bpf_object_load (struct bpf_object * obj , int extra_log_level , const char * target_btf_path )
85448615{
8545- int err , i ;
8616+ int err ;
85468617
85478618 if (!obj )
85488619 return libbpf_err (- EINVAL );
@@ -8562,17 +8633,12 @@ static int bpf_object_load(struct bpf_object *obj, int extra_log_level, const ch
85628633 return libbpf_err (- LIBBPF_ERRNO__ENDIAN );
85638634 }
85648635
8565- err = bpf_object_prepare_token (obj );
8566- err = err ? : bpf_object__probe_loading (obj );
8567- err = err ? : bpf_object__load_vmlinux_btf (obj , false);
8568- err = err ? : bpf_object__resolve_externs (obj , obj -> kconfig );
8569- err = err ? : bpf_object__sanitize_maps (obj );
8570- err = err ? : bpf_object__init_kern_struct_ops_maps (obj );
8571- err = err ? : bpf_object_adjust_struct_ops_autoload (obj );
8572- err = err ? : bpf_object__relocate (obj , obj -> btf_custom_path ? : target_btf_path );
8573- err = err ? : bpf_object__sanitize_and_load_btf (obj );
8574- err = err ? : bpf_object__create_maps (obj );
8575- err = err ? : bpf_object__load_progs (obj , extra_log_level );
8636+ if (obj -> state < OBJ_PREPARED ) {
8637+ err = bpf_object_prepare (obj , target_btf_path );
8638+ if (err )
8639+ return libbpf_err (err );
8640+ }
8641+ err = bpf_object__load_progs (obj , extra_log_level );
85768642 err = err ? : bpf_object_init_prog_arrays (obj );
85778643 err = err ? : bpf_object_prepare_struct_ops (obj );
85788644
@@ -8584,35 +8650,22 @@ static int bpf_object_load(struct bpf_object *obj, int extra_log_level, const ch
85848650 err = bpf_gen__finish (obj -> gen_loader , obj -> nr_programs , obj -> nr_maps );
85858651 }
85868652
8587- /* clean up fd_array */
8588- zfree ( & obj -> fd_array );
8653+ bpf_object_post_load_cleanup ( obj );
8654+ obj -> state = OBJ_LOADED ; /* doesn't matter if successfully or not */
85898655
8590- /* clean up module BTFs */
8591- for ( i = 0 ; i < obj -> btf_module_cnt ; i ++ ) {
8592- close (obj -> btf_modules [ i ]. fd );
8593- btf__free ( obj -> btf_modules [ i ]. btf );
8594- free ( obj -> btf_modules [ i ]. name );
8656+ if ( err ) {
8657+ bpf_object_unpin ( obj );
8658+ bpf_object_unload (obj );
8659+ pr_warn ( "failed to load object '%s'\n" , obj -> path );
8660+ return libbpf_err ( err );
85958661 }
8596- free (obj -> btf_modules );
8597-
8598- /* clean up vmlinux BTF */
8599- btf__free (obj -> btf_vmlinux );
8600- obj -> btf_vmlinux = NULL ;
8601-
8602- obj -> state = OBJ_LOADED ; /* doesn't matter if successfully or not */
8603- if (err )
8604- goto out ;
86058662
86068663 return 0 ;
8607- out :
8608- /* unpin any maps that were auto-pinned during load */
8609- for (i = 0 ; i < obj -> nr_maps ; i ++ )
8610- if (obj -> maps [i ].pinned && !obj -> maps [i ].reused )
8611- bpf_map__unpin (& obj -> maps [i ], NULL );
8664+ }
86128665
8613- bpf_object_unload ( obj );
8614- pr_warn ( "failed to load object '%s'\n" , obj -> path );
8615- return libbpf_err (err );
8666+ int bpf_object__prepare ( struct bpf_object * obj )
8667+ {
8668+ return libbpf_err (bpf_object_prepare ( obj , NULL ) );
86168669}
86178670
86188671int bpf_object__load (struct bpf_object * obj )
@@ -9060,6 +9113,13 @@ void bpf_object__close(struct bpf_object *obj)
90609113 if (IS_ERR_OR_NULL (obj ))
90619114 return ;
90629115
9116+ /*
9117+ * if user called bpf_object__prepare() without ever getting to
9118+ * bpf_object__load(), we need to clean up stuff that is normally
9119+ * cleaned up at the end of loading step
9120+ */
9121+ bpf_object_post_load_cleanup (obj );
9122+
90639123 usdt_manager_free (obj -> usdt_man );
90649124 obj -> usdt_man = NULL ;
90659125
0 commit comments