diff --git a/backends/xnnpack/runtime/XNNWeightsCache.cpp b/backends/xnnpack/runtime/XNNWeightsCache.cpp index 09cfe3641b5..c91c387a206 100644 --- a/backends/xnnpack/runtime/XNNWeightsCache.cpp +++ b/backends/xnnpack/runtime/XNNWeightsCache.cpp @@ -141,16 +141,19 @@ Error XNNWeightsCache::initialize_for_runtime( return Error::Ok; } - // Already loaded earlier this session; just reopen the write fd that - // save_packed_index() closed. Subsequent reserve_space can extend the - // file for any entries not in the saved trailer. - if (cache_loaded_) { + // Entries already in memory (from a prior load_packed_cache or a prior + // fresh-write session). Just reopen the write fd that save_packed_index + // closed; subsequent reserve_space can extend the file. Using metadata + // emptiness (not a separate flag) as the gate avoids a latent bug + // where fresh-write→save→re-init re-enters load_packed_cache and + // double-mmaps the same file. + if (!name_to_packed_data_metadata_.empty()) { packed_file_fd_ = open_locked(packed_cache_path_, O_RDWR); return Error::Ok; } - // First init for this path: try to load the saved trailer; on success - // open a write fd for any new entries. If load fails, fall through to + // No in-memory entries: try to load the saved trailer; on success open + // a write fd for any new entries. If load fails, fall through to // fresh-write below. if (load_packed_cache()) { ET_LOG( @@ -280,7 +283,6 @@ void XNNWeightsCache::full_unload() { packed_data_ptrs_.clear(); ptr_to_file_offset_.clear(); file_ptr_to_region_index_.clear(); - cache_loaded_ = false; if (packed_file_fd_ >= 0) { close(packed_file_fd_); packed_file_fd_ = -1; @@ -714,7 +716,6 @@ bool XNNWeightsCache::load_packed_cache() { name_to_packed_data_metadata_[name] = meta; } - cache_loaded_ = true; packed_file_used_ = index_start; // In-memory state matches the on-disk trailer; the next save would be // a no-op. Initialize watermark so save_packed_index short-circuits. diff --git a/backends/xnnpack/runtime/XNNWeightsCache.h b/backends/xnnpack/runtime/XNNWeightsCache.h index 851b452441f..54ca73c5467 100644 --- a/backends/xnnpack/runtime/XNNWeightsCache.h +++ b/backends/xnnpack/runtime/XNNWeightsCache.h @@ -39,10 +39,8 @@ struct PackedDataMeta { bool in_current_runtime{}; // True if this entry's bytes are persisted in the on-disk cache file // (either originally loaded via load_packed_cache, or freshly packed - // and then save_packed_index-ed). Used by delete_packed_data to - // detect when all persistent entries are gone, at which point - // cache_loaded_ is auto-invalidated so the next init re-enters - // load_packed_cache and reuses the saved file instead of re-packing. + // and then save_packed_index-ed). delete_packed_data preserves these + // entries so the next init reuses the saved file instead of re-packing. bool from_load{false}; // Per-ukernel seed from xnn_weights_cache_look_up_key.seed. XNNPACK // guarantees this is consistent across runs of the same ukernel; when @@ -195,10 +193,6 @@ class XNNWeightsCache { std::string packed_cache_path_; int packed_file_fd_{-1}; size_t packed_file_used_{0}; - // True once load_packed_cache() has populated metadata from a saved - // index, OR once a fresh-write session has been persisted to disk via - // save_packed_index() (so subsequent inits can load from it). - bool cache_loaded_{false}; // Tracks file offset of each file-backed allocation. Used by // save_packed_index() to serialize (name → offset, size) index. std::unordered_map ptr_to_file_offset_;