qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] [RFC] Convert Qemu Timer List and Active Timers


From: Alex Bligh
Subject: Re: [Qemu-devel] [PATCH] [RFC] Convert Qemu Timer List and Active Timers to RCU
Date: Sat, 15 Feb 2014 22:00:56 +0000

Mike,

On 15 Feb 2014, at 20:33, Mike Day wrote:
>> 
>> 2. You have introduced rcu not only to protect active_timers, the list of
>>   active timers within one timerlist, but also to protect (I think)
>>   the list of timerlists, as evidenced by the fact you have
>>   reclaim_timer_list as well as reclaim_timer. We currently have no
>>   locking in the creation/deletion of timerlists as these only happen on init
>>   or on when an AioContext is created/destroyed (as these are the only things
>>   that create or delete TimerListGroups); both these operations are
>>   required to happen within the main thread and are protected by the
>>   BQL. Indeed currently nothing every destroys an AioContext. I suspect
>>   if there is really a need to destroy timerlists in threads other than
>>   the main thread we are going to have more issues than locking of the list 
>> of
>>   timerlists. I suggest you remove these changes and solely look at 
>> protecting
>>   the list of active timers (as opposed to the list of timerlists) by RCU.
> 
> I thought about this a lot and and I'm glad you are bringing up the
> timerlist here. As you said, I couldn't find anywhere in the code base
> that manipulates this list. But I also noticed that the timer and clock
> structures are accessed by unrelated code modules. I don't know enough
> about the timer usage to predict how timers will be used by other code
> modules so I decided to overprotect and see what you thought about it.
> 
> Removing the protection of the timerlist will vastly simplify this
> patch. Eventually, though, when we remove the BQL, I'm assuming we will
> need to protect the timerlist somehow. I'm happy now re-factoring toward
> a much simpler patch that just protects the active timer list.

I think you mean "protect the list of timerlists somehow". I agree.

I suppose RCU would ultimately be better than a mutex as it's the
archetypal read lots write almost never list. I suppose I somewhat
grudgingly see the point! If you want to do that this time round, I'd
suggest you break it into two patches.

>> 4. In timerlist_notify(), you are holding the rcu_read_lock across
>>   the callback or qemu_notify_event. Why is this necessary? EG can't you
>>   do something like:
>> 
>>    void timerlist_notify(QEMUTimerList *timer_list)
>>    {
>>         rcu_read_lock();
>>         if (atomic_rcu_read(&timer_list->notify_cb)) {
>>            QEMUTimerListNotifyCB *notify_cb = timer_list->notify_cb;
>>            void *notify_opaque = timer_list->notify_opaque;
>>            rcu_read_unlock();
>>            notify_cb(notify_opaque);
>>        } else {
>>            rcu_read_unlock();
>>            qemu_notify_event();
>>        }
>>    }
> 
> I thought a lot about this one and went back and forth a couple of
> times, so I'm glad you are looking at it. My concern is that the timer
> could be reclaimed during execution ofthe callback. And, the callback
> may be referincing the timer itself. Even if the callback takes an
> rcu_read_lock, there is a window between when the timer code leaves the
> rcu critical section and calls the notification code, and when the
> notification callback enters the rcu critical section via
> rcu_read_lock. It may be possible though unlikely that a reclaim could
> occur during this small window.

Fair enough.

> The downside, as far as I know, is that the notification callback will
> take a long time to execute. This is not good, but it won't cause an
> error by itself.

Agree.

>> 5. Similarly to the above, in qemu_clock_notify, you take the
>>   rcu_read_lock, and then do a QLIST_FOREACH_RCU. That will mean
>>   the rcu_read_lock is taken anyway in 99% of calls to timerlist_notify.
>>   This is going through the list of timerlists, and that list is in
>>   practice static (protected by the BQL). Similarly in
>>   qemu_clock_deadline_ns_all, timerlist_get_clock, etc.
> 
> My thinking here is that rcu_read_lock can be called recursively with no
> bad effect other than possibly taking up cache space. So when you have a
> function like this that is usually called as an internal function but
> occasionally called directly, take the rcu read lock in both
> functions. I think this will be removed anyway with the timerlist
> change.

It will. But I suppose it isn't a great concern.

-- 
Alex Bligh







reply via email to

[Prev in Thread] Current Thread [Next in Thread]