|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4] xen: sched: convert RTDS from time to event driven model
On 2/3/2016 7:39 AM, Dario Faggioli wrote: On Tue, 2016-02-02 at 13:09 -0500, Tianyang Chen wrote:On 2/2/2016 10:08 AM, Dario Faggioli wrote:On Sun, 2016-01-31 at 23:32 -0500, Tianyang Chen wrote:+ struct rt_private *prv = rt_priv(ops); + struct list_head *replq = rt_replq(ops); + struct list_head *iter; + + ASSERT( spin_is_locked(&prv->lock) ); +Is this really useful? Considering where this is called, I don't think it is.This basically comes from __q_insert().I see. Well it's still not necessary, IMO, so don't add it. At some point, we may want to remove it from __runq_insert() too. The bottom line is: prv->lock is, currently, the runqueue lock (it's the lock for everything! :-D). It is pretty obvious that you need the runq lock to manipulate the runqueue. It is not the runqueue that you are manipulating here, it is the replenishment queue, but as a matter of fact, prv->lock serializes that too. So, if anything, it would be more useful to add a comment somewhere, noting (reinforcing, I should probably say) the point that also this new queue for replenishment is being serialized by prv->lock, than an assert like this one. Sure I have been searching for the definitions of vcpu_schedule_lock_irq() and pcpu_schedule_lock_irq(). Do you know where they are defined? I did some name search in the entire xen directory but still nothing.They are auto-generated. Look in xen/include/xen/sched-if.h. Yeah it makes sense to put some comments in rt_init to remind readers that the timer will be taken care of later in alloc_pdata().
Yeah I agree with this situation. But I meant to say when a vcpu is waking up while it's still on a queue. See below. And also, repl_handler removes vcpus that are not runnable and if they are not added back here, where should we start tracking them? This goes back to if it's necessary to remove a un-runnable vcpu.I also don't get what you mean by "tracking" (here and in other places). So "tracking" basically means adding a vcpu to the replenishment queue. "Stop tracking" means removing a vcpu from the replenishment queue. Anyway, what I meant when I said that what to do in the "delayed add" case depends on other things is, for instance, this: the vcpu is waking up right now, but it is going to be inserted in the runqueue later. When (as per "where in the code", "in what function") do you want to program the timer, here in rt_vcpu_wake(), or changing __replq_insert(), as said somewhere else, or in rt_context_saved(), where the vcpu is actually added to the runq? This kind of things... All this being said, taking a bit of a step back, and considering, not only the replenishment event and/or timer (re)programming issue, but also the deadline that needs updating, I think you actually need to find a way to check for both, in this patch. For the this situation, a vcpu is waking up on a pcpu. It could be taken off from the replq inside the timer handler at the end. So, if we decide to not replenish any sleeping/un-runnable vcpus any further, we should probably add it back to replq here right? For this situation, a vcpu could be going through the following phases: on runq --> sleep --> (for a long time) --> wake upWhen it wakes up, it could stay in the front of the runq because cur_deadline hasn't been updated. It will, inherently have some high priority-ness (because of EDF) and be picked over other vcpus right? Do we want to update it's deadline and budget here and re-insert it accordingly? For here, consider this scenario:on pcpu (originally on replq) --> sleep --> context_saved() but still asleep --> wake() Timer handler isn't triggered before it awakes. Then this vcpu will be added to replq again while it's already there. I'm not 100% positive if this situation is possible though. But judging from rt_context_saved(), it checks if a vcpu is runnable before adding back to the runq. I agree with this. Since replenishment happens above already, it can be inserted back to runq correctly in rt_context_saved(). So just to wrap up my thoughts for budget replenishment inside of wake(), a vcpu can be in different states(on pcpu, on queue etc.) when it wakes up. 1)wake up on a pcpu:Do nothing as it may have some remaining budget and we just ignore it's cur_deadline when it wakes up. I can't find a corresponding pattern in DS but this can be treated like a server being pushed back because of the nap. 2)wake up on a queue:Update the deadline(refill budget) of it and re-insert it into runq for the reason stated above. 3)wake up in the middle of context switching:Update the deadline(refill budget) of it so it can be re-inserted into runq in rt_context_saved(). 4)wake up on nowhere ( sleep on pcpu--> context_saved() --> wake()): Replenish it and re-insert it back to runq. 5)other? I can't think of any for now.As for replenishment queue manipulation, we should always try and add it back to replq because we don't know if the timer handler has taken it off or not. The timer handler and wake() is coupled in a sense that they both manipulate replq.
So, the burn_budget() is still there right? I'm not sure what you are referring to as budget enforcement. Correct me if I'm wrong, budget enforcement means that each vcpu uses its assigned/remaining budget. Is there any specific situation I'm missing? So, do you mind if we take a step back again, and analyze the situation. When the timer fires, and this handler is executed and a replenishment event taken off the replenishment queue, the following situations are possible: 1) the replenishment is for a running vcpu 2) the replenishment is for a runnable vcpu in the runq 3) the replenishment is for a runnable vcpu in the depletedq 4) the replenishment is for a sleeping vcpu So, 4) is never going to happen, right?, as we're stopping the timer when a vcpu blocks. If we go for this, let's put an ASSERT() and a comment as a guard for that. If we do the optimization in this very patch. If we leave it for another patch, we need to handle this case, I guess. In all 1), 2) and 3) cases, we need to remove the replenishment event from the replenishment queue, so just (in the code) do it upfront. I don't think we need to take them of the replenishment queue? See the last couple paragraphs. What other actions need to happen in each case, 1), 2) and 3)? Can you summarize then in here, so we can decide how to handle each situation? Here we go. 1) the replenishment is for a running vcpuReplenish the vcpu. Keep it on the replenishment queue. Tickle it as it may have a later deadline. 2) the replenishment is for a runnable vcpu in the runqReplenish the vcpu. Keep it on the replenishment queue. (re-)insert it into runq. Tickle it. 3) the replenishment is for a runnable vcpu in the depletedq Same as 2) 4) the replenishment is for a sleeping vcpuTake it off from the replenishment queue and don't do replenishment. As a matter of fact, this patch does the replenishment first and then take it off. I'd say that, in both case 2) and case 3), the vcpu needs to be taken out of the queue where they are, and (re-)inserted in the runqueue, and then we need to tickle... Is that correct? correct^. I'd also say that, in case 1), we also need to tickle because the deadline may now be have become bigger than some other vcpu that is in the runqueue? correct. I missed this case^. Also, under what conditions we need, as soon as replenishment for vcpu X happened, to queue another replenishment for the same vcpu, at its next deadline? Always, I would say (unless the vcpu is sleeping, because of the optimization you introduced)? So this is kinda confusing. If in case 1) 2) and 3) they are never taken off from the replenishment queue, a series of replenishment events are automatically updated after the replenishment. There is no need, as least one less reason, to keep track of when to queue the next vcpus for replenishment. The side effect of this is that all vcpus could be going to sleep right after the timer was programmed at the end of the handler. If they don't wake up before the timer fires next time, the handler is called to replenish nobody. If that's the case, timer will not be programmed again in the handler. Wake() kicks in and programs it instead. And the downside of this is that we always need to check if an awaking vcpu is on replq or not. It not add it back(hence the notion of starting to track it's replenishment events again). When adding back, check if there is a need to reprogram the timer. I really like the idea of replenishment queue compared to running queue in that the places that we need to manipulate the queue are only in wake() and repl_handler(). Thanks, Tianyang _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |