Re: BFS 420: fix ttwu stat

From: Hillf Danton
Date: Fri May 18 2012 - 09:54:11 EST


On Fri, May 18, 2012 at 9:20 PM, Hillf Danton <dhillf@xxxxxxxxx> wrote:
> Due to monolithic runqueue used by BFS, the ttwu stat is bogus as we could not
> tell/predict on which CPU a woken task will run after it is activated. And we
> have to delay updating ttwu stat until the stage when task is taken off run
> queue. To achieve that, a field, wakeup_cpu, is added in the task struct, and is
> inited to be invalid CPU number for each new task.
>
> When updating ttwu stat, now it is simply to mark the delayed operation; and
> when taking task off runqueue, the stat is updated.
>
>
> --- a/include/linux/sched.h   Fri May 18 20:51:06 2012
> +++ b/include/linux/sched.h   Fri May 18 20:32:20 2012
> @@ -1255,6 +1255,11 @@ struct task_struct {
> Â Â Â Âstruct list_head run_list;
> Â Â Â Âu64 last_ran;
> Â Â Â Âu64 sched_time; /* sched_clock time spent running */
> +#ifdef CONFIG_SCHEDSTATS
> +#ifdef CONFIG_SMP
> + Â Â Â int wakeup_cpu; //for ttwu stat
> +#endif
> +#endif
> Â#ifdef CONFIG_SMP
> Â Â Â Âbool sticky; /* Soft affined flag */
> Â#endif
> --- a/kernel/sched/bfs.c    ÂMon May 14 20:50:38 2012
> +++ b/kernel/sched/bfs.c    ÂFri May 18 20:46:22 2012
> @@ -1145,6 +1145,30 @@ static inline void unstick_task(struct r
> Â*/
> Âstatic inline void take_task(int cpu, struct task_struct *p)
> Â{
> +#ifdef CONFIG_SCHEDSTATS
> +#ifdef CONFIG_SMP
> + Â Â Â if (p->wakeup_cpu == -1)
> + Â Â Â Â Â Â Â goto skip;
> +
> + Â Â Â if (cpu == p->wakeup_cpu) {
> + Â Â Â Â Â Â Â schedstat_inc(cpu_rq(cpu), ttwu_local);
> + Â Â Â }
> + Â Â Â else if (cpu_online(p->wakeup_cpu)) {
> + Â Â Â Â Â Â Â struct sched_domain *sd;
> +
> + Â Â Â Â Â Â Â rcu_read_lock();
> + Â Â Â Â Â Â Â for_each_domain(p->wakeup_cpu, sd) {
> + Â Â Â Â Â Â Â Â Â Â Â if (cpumask_test_cpu(cpu, sched_domain_span(sd))) {
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â schedstat_inc(sd, ttwu_wake_remote);
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â break;
> + Â Â Â Â Â Â Â Â Â Â Â }
> + Â Â Â Â Â Â Â }
> + Â Â Â Â Â Â Â rcu_read_unlock();
> + Â Â Â }
> + Â Â Â p->wakeup_cpu = -1;
> +skip:
> +#endif
> +#endif
> Â Â Â Âset_task_cpu(p, cpu);
> Â Â Â Âdequeue_task(p);
> Â Â Â Âclear_sticky(p);
> @@ -1485,30 +1509,13 @@ static void try_preempt(struct task_stru
> Â}
> Â#endif /* CONFIG_SMP */
>
> -static void
> -ttwu_stat(struct task_struct *p, int cpu, int wake_flags)
> +static void ttwu_stat(struct task_struct *p, int cpu, int wake_flags)
> Â{
> Â#ifdef CONFIG_SCHEDSTATS
> Â Â Â Âstruct rq *rq = this_rq();
>
> Â#ifdef CONFIG_SMP
> - Â Â Â int this_cpu = smp_processor_id();
> -
> - Â Â Â if (cpu == this_cpu)
> - Â Â Â Â Â Â Â schedstat_inc(rq, ttwu_local);
> - Â Â Â else {
> - Â Â Â Â Â Â Â struct sched_domain *sd;
> -
> - Â Â Â Â Â Â Â rcu_read_lock();
> - Â Â Â Â Â Â Â for_each_domain(this_cpu, sd) {
> - Â Â Â Â Â Â Â Â Â Â Â if (cpumask_test_cpu(cpu, sched_domain_span(sd))) {
> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â schedstat_inc(sd, ttwu_wake_remote);
> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â break;
> - Â Â Â Â Â Â Â Â Â Â Â }
> - Â Â Â Â Â Â Â }
> - Â Â Â Â Â Â Â rcu_read_unlock();
> - Â Â Â }
> -
> + Â Â Â p->wakeup_cpu = smp_processor_id();
> Â#endif /* CONFIG_SMP */
>
> Â Â Â Âschedstat_inc(rq, ttwu_count);
> @@ -1717,6 +1724,12 @@ void sched_fork(struct task_struct *p)
> Â#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
> Â Â Â Âif (unlikely(sched_info_on()))
> Â Â Â Â Â Â Â Âmemset(&p->sched_info, 0, sizeof(p->sched_info));
> +#endif
> +
> +#ifdef CONFIG_SCHEDSTATS
> +#ifdef CONFIG_SMP
> + Â Â Â p->wakeup_cpu = -1;
> +#endif
> Â#endif
>
> Â Â Â Âp->on_cpu = false;
> --
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/