Hi Zhukeqian, On Fri, Mar 15, 2024 at 1:17 AM zhukeqian <zhukeqi...@huawei.com> wrote:
> Hi Salil, > > [...] > > +void cpu_address_space_destroy(CPUState *cpu, int asidx) { > + CPUAddressSpace *cpuas; > + > + assert(cpu->cpu_ases); > + assert(asidx >= 0 && asidx < cpu->num_ases); > + /* KVM cannot currently support multiple address spaces. */ > + assert(asidx == 0 || !kvm_enabled()); > + > + cpuas = &cpu->cpu_ases[asidx]; > + if (tcg_enabled()) { > + memory_listener_unregister(&cpuas->tcg_as_listener); > + } > + > + address_space_destroy(cpuas->as); > + g_free_rcu(cpuas->as, rcu); > > In address_space_destroy(), it calls call_rcu1() on cpuas->as which will > set do_address_space_destroy() as the rcu func. > And g_free_rcu() also calls call_rcu1() on cpuas->as which will overwrite > the rcu func as g_free(). > > Then I think the g_free() may be called twice in rcu thread, please verify > that. > > The source code of call_rcu1: > > void call_rcu1(struct rcu_head *node, void (*func)(struct rcu_head *node)) > { > node->func = func; > enqueue(node); > qatomic_inc(&rcu_call_count); > qemu_event_set(&rcu_call_ready_event); > } > Thanks for testing and identifying this. Let me have a look and will get back to you. Thanks Salil > > Thanks, > Keqian > > + > + if (asidx == 0) { > + /* reset the convenience alias for address space 0 */ > + cpu->as = NULL; > + } > + > + if (--cpu->cpu_ases_count == 0) { > + g_free(cpu->cpu_ases); > + cpu->cpu_ases = NULL; > + } > +} > + > AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx) { > /* Return the AddressSpace corresponding to the specified index */ > -- > 2.34.1 > >