Re: A question about cpu_idle()

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

 



On Wed, Oct 21, 2009 at 12:47 PM, Gregory Haskins <ghaskins@xxxxxxxxxx> wrote:
>>>> On 10/20/2009 at 11:07 PM, in message
> <a0e7fce50910202007l587d2cfcu91b455ff0486110b@xxxxxxxxxxxxxx>, yi li
> <liyi.dev@xxxxxxxxx> wrote:
>> Hi RT users,
>>
>> While reading patch-2.6.31.4-rt14, there is a patch for cpu_idle()
>> which I cannot understand.
>>
>> Could anyone kindly enough to tell me what is patch used for?
>
> Hi Yi,
>
> I believe that logic is ensuring that the task is put to sleep instead of simply being preempted.  The difference is that a preemption leaves the task on the RQ, whereas calling schedule() may or may not leave the caller on the RQ, depending on the status of current->state.  The local_irq_disable+__preempt_enable_no_resched dance is a way of legally calling schedule() while effectively preventing preemption (since interrupts-off also disables preemption).  The difference is that its legal to call __schedule() with interrupts off, but you can't with preempt_disable().
>
> Long story short, the enable_no_resched() + schedule() pattern is only ever used when you want to make sure the task fully sleeps.  However without this patch to disable interrupts, the original code appears racy and thus probably had issues achieving its intended goal.
>
> HTH,
> -Greg
>

Thanks Greg for the kind reply.

But due to my limited knowledge on PREEMPT_RT, I still not fully understand.

Given schedule() is defined as:

asmlinkage void __sched schedule(void)
{
need_resched:
	local_irq_disable();
	__schedule();
	local_irq_enable();

	if (need_resched())
		goto need_resched;
}

Comparing bellow two code sequences:

1)
preempt_enable_no_resched();
schedule();
preempt_disable();


2)
local_irq_disable();
__preempt_enable_no_resched();
__schedule();
preempt_disable();
local_irq_enable();

It seems to me, the main difference is to change the order of
"preempt_enable_no_sched() / local_irq_disable()":
i.e, from:

"preempt_enable_no_sched();
/* Yi: will some race condition happens here? */
 local_irq_disable();
__schedule();"

to:

"local_irq_disable(); /* Yi: disables irq effectively disables preemption?  */
preempt_enable_no_sched();
__schedule();"

Regards,
-Yi

>>
>>
>> diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
>> index ebefb54..c8d0ece 100644
>> --- a/arch/x86/kernel/process_64.c
>> +++ b/arch/x86/kernel/process_64.c
>> @@ -152,9 +152,11 @@ void cpu_idle(void)
>>                 }
>>
>>                 tick_nohz_restart_sched_tick();
>> -               preempt_enable_no_resched();
>> -               schedule();
>> +               local_irq_disable();
>> +               __preempt_enable_no_resched();
>> +               __schedule();
>>                 preempt_disable();
>> +               local_irq_enable();
>>         }
>>  }
>>
>> Regards,
>> -Yi
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [RT Stable]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]

  Powered by Linux