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.