On Wed, Aug 28, 2013 at 12:35 PM, Paolo Bonzini <
address@hidden> 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.