Il 19/09/2012 11:21, Avi Kivity ha scritto:
>> > I don't know if the front-end (device) lock should come before or after
>> > the back-end (e.g. netdev) lock in the hierarchy, but that's another story.
> I would say device -> backend. It's natural if the backend is the timer
> subsystem, so extend it from there to the block and network layers. Of
> course callbacks want it to be the other way round.
Yes, that's what I wasn't sure about. In many cases I believe callbacks
can just release the backend lock. It works for timers, for example:
for(;;) {
ts = clock->active_timers;
if (!qemu_timer_expired_ns(ts, current_time)) {
break;
}
/* remove timer from the list before calling the callback */
clock->active_timers = ts->next;
ts->next = NULL;
/* run the callback (the timer list can be modified) */
- ts->cb(ts->opaque);
+ cb = ts->cb;
+ opaque = ts->opaque;
+ unlock();
+ cb(opaque);
+ lock();
}
(The hunch is that ts could be deleted exactly at the moment the
callback is unlocked. This can be solved with ref/unref on the opaque
value, as you mention below).
Paolo
> We could solve the callback problem in the same way we're using for mmio
> callbacks. When providing the callback, give the subsystem ->ref() and
> ->unref() methods. As long as a callback is pending, the subsystem
> holds a reference. Once the callback has been invoked or cancelled, the
> reference can be released.