On Wed, Aug 28, 2013 at 12:35 PM, Paolo Bonzini <pbonz...@redhat.com> wrote: > > > @@ -828,13 +829,18 @@ static inline void *host_from_stream_offset(QEMUFile *f, > > qemu_get_buffer(f, (uint8_t *)id, len); > > id[len] = 0; > > > > - QTAILQ_FOREACH(block, &ram_list.blocks, next) { > > - if (!strncmp(id, block->idstr, sizeof(id))) > > - return memory_region_get_ram_ptr(block->mr) + offset; > > + rcu_read_lock(); > > + QLIST_FOREACH_RCU(block, &ram_list.blocks, next) { > > + if (!strncmp(id, block->idstr, sizeof(id))) { > > + ptr = memory_region_get_ram_ptr(block->mr) + offset; > > + goto unlock_out; > > + } > > } > > > > fprintf(stderr, "Can't find block %s!\n", id); > > - return NULL; > > +unlock_out: > > + rcu_read_unlock(); > > + return ptr; > > } > > > Similarly, here the critical section includes the caller, and block is > living across calls to host. Again, for now just put all of ram_load > under a huge RCU critical section. Later we can use ram_list.version to > refresh the list and make the critical sections smaller.
And: rcu_read_lock() and rcu_read_unlock() can be called recursively, so I can still leave the lock/unlock pair in host_from_stream_offset.