Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1292735 > unrolled thread
| Started by | Leo Yan <leo.yan@linaro.org> |
|---|---|
| First post | 2015-12-16 04:50 +0100 |
| Last post | 2015-12-19 07:00 +0100 |
| Articles | 5 — 2 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: [RFCv6 PATCH 03/10] sched: scheduler-driven cpu frequency selection Leo Yan <leo.yan@linaro.org> - 2015-12-16 04:50 +0100
Re: [RFCv6 PATCH 03/10] sched: scheduler-driven cpu frequency selection Steve Muckle <steve.muckle@linaro.org> - 2015-12-17 02:30 +0100
Re: [RFCv6 PATCH 03/10] sched: scheduler-driven cpu frequency selection Leo Yan <leo.yan@linaro.org> - 2015-12-17 08:20 +0100
Re: [RFCv6 PATCH 03/10] sched: scheduler-driven cpu frequency selection Steve Muckle <steve.muckle@linaro.org> - 2015-12-18 20:20 +0100
Re: [RFCv6 PATCH 03/10] sched: scheduler-driven cpu frequency selection Leo Yan <leo.yan@linaro.org> - 2015-12-19 07:00 +0100
| From | Leo Yan <leo.yan@linaro.org> |
|---|---|
| Date | 2015-12-16 04:50 +0100 |
| Subject | Re: [RFCv6 PATCH 03/10] sched: scheduler-driven cpu frequency selection |
| Message-ID | <qGbgd-4UV-5@gated-at.bofh.it> |
Hi Steve,
On Tue, Dec 08, 2015 at 10:19:24PM -0800, Steve Muckle wrote:
[...]
> +static int cpufreq_sched_thread(void *data)
> +{
> + struct sched_param param;
> + struct cpufreq_policy *policy;
> + struct gov_data *gd;
> + unsigned int new_request = 0;
> + unsigned int last_request = 0;
> + int ret;
> +
> + policy = (struct cpufreq_policy *) data;
> + gd = policy->governor_data;
> +
> + param.sched_priority = 50;
> + ret = sched_setscheduler_nocheck(gd->task, SCHED_FIFO, ¶m);
> + if (ret) {
> + pr_warn("%s: failed to set SCHED_FIFO\n", __func__);
> + do_exit(-EINVAL);
> + } else {
> + pr_debug("%s: kthread (%d) set to SCHED_FIFO\n",
> + __func__, gd->task->pid);
> + }
> +
> + do {
> + set_current_state(TASK_INTERRUPTIBLE);
> + new_request = gd->requested_freq;
> + if (new_request == last_request) {
> + schedule();
> + } else {
> + /*
> + * if the frequency thread sleeps while waiting to be
> + * unthrottled, start over to check for a newer request
> + */
> + if (finish_last_request(gd))
> + continue;
> + last_request = new_request;
> + cpufreq_sched_try_driver_target(policy, new_request);
> + }
I also think "set_current_state(TASK_INTERRUPTIBLE)" will introduce
logic error when software flow run into "else" block. The reason is
after you set state with TASK_INTERRUPTIBLE, if there have some
scheduling happen within cpufreq_sched_try_driver_target(), then the
thread will be remove from rq. But generally we suppose the thread
will be on rq and can continue run after next tick.
Juri's suggestion can fix this issue. And we can use atomic_t to
safely accessing gd->requested_freq.
[...]
Thanks,
Leo Yan
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Steve Muckle <steve.muckle@linaro.org> |
|---|---|
| Date | 2015-12-17 02:30 +0100 |
| Message-ID | <qGvyi-13b-11@gated-at.bofh.it> |
| In reply to | #1292735 |
Hi Leo, On 12/15/2015 07:48 PM, Leo Yan wrote: > I also think "set_current_state(TASK_INTERRUPTIBLE)" will introduce > logic error when software flow run into "else" block. The reason is > after you set state with TASK_INTERRUPTIBLE, if there have some > scheduling happen within cpufreq_sched_try_driver_target(), then the > thread will be remove from rq. But generally we suppose the thread > will be on rq and can continue run after next tick. > > Juri's suggestion can fix this issue. And we can use atomic_t to > safely accessing gd->requested_freq. I agree, it's incorrect. As I replied earlier I believe setting the task state back to TASK_RUNNING at the top of the else block is the easiest fix. thanks, Steve -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Leo Yan <leo.yan@linaro.org> |
|---|---|
| Date | 2015-12-17 08:20 +0100 |
| Message-ID | <qGB10-4zr-11@gated-at.bofh.it> |
| In reply to | #1293544 |
Hi Steve,
On Wed, Dec 16, 2015 at 05:24:56PM -0800, Steve Muckle wrote:
> Hi Leo,
>
> On 12/15/2015 07:48 PM, Leo Yan wrote:
> > I also think "set_current_state(TASK_INTERRUPTIBLE)" will introduce
> > logic error when software flow run into "else" block. The reason is
> > after you set state with TASK_INTERRUPTIBLE, if there have some
> > scheduling happen within cpufreq_sched_try_driver_target(), then the
> > thread will be remove from rq. But generally we suppose the thread
> > will be on rq and can continue run after next tick.
> >
> > Juri's suggestion can fix this issue. And we can use atomic_t to
> > safely accessing gd->requested_freq.
>
> I agree, it's incorrect. As I replied earlier I believe setting the task
> state back to TASK_RUNNING at the top of the else block is the easiest fix.
Could you check if below corner case will introduce logic error?
The task still will be removed from rq if timer tick is triggered
between two time's set_current_state().
set_current_state(TASK_INTERRUPTIBLE);
`-------> timer_tick and
schedule();
do_something...
set_current_state(TASK_RUNNING);
It will be safe for combination for set_current_state()/schedule()
with waken_up_process():
Thread_A: Thread_B:
set_current_state(TASK_INTERRUPTIBLE);
`-------> timer_tick and
schedule();
....
wake_up_process(Thread_A);
<---------------------/
schedule();
The first time's schedule() will remove task from rq which is caused
by timer tick and call schedule(), and the second time schdule() will
be equal yeild().
Thanks,
Leo Yan
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Steve Muckle <steve.muckle@linaro.org> |
|---|---|
| Date | 2015-12-18 20:20 +0100 |
| Message-ID | <qH8Jk-1fV-9@gated-at.bofh.it> |
| In reply to | #1293652 |
Hi Leo,
On 12/16/2015 11:17 PM, Leo Yan wrote:
> Could you check if below corner case will introduce logic error?
> The task still will be removed from rq if timer tick is triggered
> between two time's set_current_state().
>
> set_current_state(TASK_INTERRUPTIBLE);
> `-------> timer_tick and
> schedule();
> do_something...
> set_current_state(TASK_RUNNING);
>
> It will be safe for combination for set_current_state()/schedule()
> with waken_up_process():
>
> Thread_A: Thread_B:
>
> set_current_state(TASK_INTERRUPTIBLE);
> `-------> timer_tick and
> schedule();
> ....
> wake_up_process(Thread_A);
> <---------------------/
> schedule();
>
> The first time's schedule() will remove task from rq which is caused
> by timer tick and call schedule(), and the second time schdule() will
> be equal yeild().
I was initially concerned about preemption while task state =
TASK_INTERRUPTIBLE as well, but a task with state TASK_INTERRUPTIBLE is
not dequeued if it is preempted. See core.c:__schedule():
if (!preempt && prev->state) {
if (unlikely(signal_pending_state(prev->state, prev))) {
prev->state = TASK_RUNNING;
} else {
deactivate_task(rq, prev, DEQUEUE_SLEEP);
prev->on_rq = 0;
I knew this had to be the case, because this design pattern is used in
many other places in the kernel, so many things would be very broken if
this were a problem.
thanks,
Steve
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Leo Yan <leo.yan@linaro.org> |
|---|---|
| Date | 2015-12-19 07:00 +0100 |
| Message-ID | <qHiIF-7zM-1@gated-at.bofh.it> |
| In reply to | #1295103 |
Hi Steve,
On Fri, Dec 18, 2015 at 11:15:01AM -0800, Steve Muckle wrote:
> On 12/16/2015 11:17 PM, Leo Yan wrote:
> > Could you check if below corner case will introduce logic error?
> > The task still will be removed from rq if timer tick is triggered
> > between two time's set_current_state().
> >
> > set_current_state(TASK_INTERRUPTIBLE);
> > `-------> timer_tick and
> > schedule();
> > do_something...
> > set_current_state(TASK_RUNNING);
> >
> > It will be safe for combination for set_current_state()/schedule()
> > with waken_up_process():
> >
> > Thread_A: Thread_B:
> >
> > set_current_state(TASK_INTERRUPTIBLE);
> > `-------> timer_tick and
> > schedule();
> > ....
> > wake_up_process(Thread_A);
> > <---------------------/
> > schedule();
> >
> > The first time's schedule() will remove task from rq which is caused
> > by timer tick and call schedule(), and the second time schdule() will
> > be equal yeild().
>
> I was initially concerned about preemption while task state =
> TASK_INTERRUPTIBLE as well, but a task with state TASK_INTERRUPTIBLE is
> not dequeued if it is preempted. See core.c:__schedule():
>
> if (!preempt && prev->state) {
> if (unlikely(signal_pending_state(prev->state, prev))) {
> prev->state = TASK_RUNNING;
> } else {
> deactivate_task(rq, prev, DEQUEUE_SLEEP);
> prev->on_rq = 0;
>
> I knew this had to be the case, because this design pattern is used in
> many other places in the kernel, so many things would be very broken if
> this were a problem.
You are right, I went through the code again and sched tick irq will
call preempt_schedule_irq() and __schedule(true); so finally set the
parameter "preempt" = true. Sorry for noise :p
---8<---
arch/arm64/kernel/entry.S:
#ifdef CONFIG_PREEMPT
el1_preempt:
mov x24, lr
1: bl preempt_schedule_irq // irq en/disable is done inside
ldr x0, [tsk, #TI_FLAGS] // get new tasks TI_FLAGS
tbnz x0, #TIF_NEED_RESCHED, 1b // needs rescheduling?
ret x24
#endif
Thanks,
Leo Yan
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web