From patchwork Thu Nov 6 07:52:02 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "pang.xunlei" X-Patchwork-Id: 40253 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f199.google.com (mail-wi0-f199.google.com [209.85.212.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 1D4E9240B2 for ; Thu, 6 Nov 2014 07:53:10 +0000 (UTC) Received: by mail-wi0-f199.google.com with SMTP id r20sf296663wiv.10 for ; Wed, 05 Nov 2014 23:53:09 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=D3feNeVwC2J041S4/ap2QVX8/rVgSwA0BtlYfgQaqM4=; b=PQwj1xNB36ACqog8AP+jLQEU8JVhSUXfi0sci4+64KxrKV5HL8FPpTkaiCKNY0CYIL 8IY3bMwNVLc/eJWAetGKkkhzffBjXeTMJUqPj1G8EmLMGb3/oTLvcqYxgiwpILF3A4L0 yBEmgkwGdME7PoPkcTXsOYnpu6JhN4O2iuYtJIHvTJFdVBgWAYmwjJccYE4ss+m2V2w/ R7Yq/c+ltTU/eFUlJqEwwxksUB3O4tUVLO0ZsMzgpl0nVGOzHdIlZx2T3lcbE4zFDPq/ Lkq82fdf+JsTaiyueKJmCRZ6WmXFcguK61RtHKwe0gA7R4DSQjlkXptNZTBnHacQ88Iy QFaQ== X-Gm-Message-State: ALoCoQmh/eyyn/cuLeE9+ysMBom8+l0bryuZl/iJ7tMixyRUI/aAiG4/pchDig8X9O11T9WqFLYN X-Received: by 10.112.154.194 with SMTP id vq2mr249972lbb.10.1415260388987; Wed, 05 Nov 2014 23:53:08 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.9.137 with SMTP id z9ls48540laa.50.gmail; Wed, 05 Nov 2014 23:53:08 -0800 (PST) X-Received: by 10.112.180.198 with SMTP id dq6mr3004033lbc.56.1415260388482; Wed, 05 Nov 2014 23:53:08 -0800 (PST) Received: from mail-lb0-f174.google.com (mail-lb0-f174.google.com. [209.85.217.174]) by mx.google.com with ESMTPS id o6si7042427laj.25.2014.11.05.23.53.08 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 05 Nov 2014 23:53:08 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.174 as permitted sender) client-ip=209.85.217.174; Received: by mail-lb0-f174.google.com with SMTP id p9so434689lbv.33 for ; Wed, 05 Nov 2014 23:53:08 -0800 (PST) X-Received: by 10.112.77.74 with SMTP id q10mr3018066lbw.66.1415260388298; Wed, 05 Nov 2014 23:53:08 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.184.201 with SMTP id ew9csp8574lbc; Wed, 5 Nov 2014 23:53:07 -0800 (PST) X-Received: by 10.68.204.233 with SMTP id lb9mr2641058pbc.25.1415260386414; Wed, 05 Nov 2014 23:53:06 -0800 (PST) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id sz3si5111556pab.188.2014.11.05.23.53.05 for ; Wed, 05 Nov 2014 23:53:06 -0800 (PST) Received-SPF: none (google.com: linux-kernel-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751555AbaKFHw7 (ORCPT + 25 others); Thu, 6 Nov 2014 02:52:59 -0500 Received: from mail-pa0-f48.google.com ([209.85.220.48]:64152 "EHLO mail-pa0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751263AbaKFHw4 (ORCPT ); Thu, 6 Nov 2014 02:52:56 -0500 Received: by mail-pa0-f48.google.com with SMTP id ey11so757649pad.7 for ; Wed, 05 Nov 2014 23:52:56 -0800 (PST) X-Received: by 10.69.27.33 with SMTP id jd1mr2750779pbd.90.1415260376288; Wed, 05 Nov 2014 23:52:56 -0800 (PST) Received: from wangdeqiang.com ([210.21.223.3]) by mx.google.com with ESMTPSA id yc4sm5168431pab.27.2014.11.05.23.52.52 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 05 Nov 2014 23:52:55 -0800 (PST) From: "pang.xunlei" To: linux-kernel@vger.kernel.org Cc: Peter Zijlstra , Steven Rostedt , Juri Lelli , "pang.xunlei" Subject: [PATCH v4 2/7] sched/rt: Deal with cpupri.pri_to_cpu[CPUPRI_IDLE] for idle cases Date: Thu, 6 Nov 2014 15:52:02 +0800 Message-Id: <1415260327-30465-2-git-send-email-pang.xunlei@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1415260327-30465-1-git-send-email-pang.xunlei@linaro.org> References: <1415260327-30465-1-git-send-email-pang.xunlei@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: pang.xunlei@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.174 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , When a runqueue runs out of RT tasks, it may have non-RT tasks or none tasks(idle). Currently, RT balance treats the two cases equally and manipulates cpupri.pri_to_cpu[CPUPRI_NORMAL] only which may cause problems. For instance, 4 cpus system, non-RT task1 is running on cpu0, RT task2 is running on cpu3, cpu1/cpu2 both are idle. Then RT task3 (usually CPU-intensive) is waken up or created on cpu3, it will be placed to cpu0 (see find_lowest_rq()) causing task1 starving until cfs load balance places task1 to another cpu, or even worse if task1 is bound on cpu0. So, it would be reasonable to put task3 to cpu1 or cpu2 which is idle(even though doing this may break the energy-saving idle state). This patch tackles the problem by operating pri_to_cpu[CPUPRI_IDLE] of cpupri according to the stages of idle task, so that when pushing RT tasks through find_lowest_rq(), it will try to find one idle cpu as the goal. Signed-off-by: pang.xunlei --- kernel/sched/idle_task.c | 3 +++ kernel/sched/rt.c | 21 +++++++++++++++++++++ kernel/sched/sched.h | 6 ++++++ 3 files changed, 30 insertions(+) diff --git a/kernel/sched/idle_task.c b/kernel/sched/idle_task.c index 67ad4e7..e053347 100644 --- a/kernel/sched/idle_task.c +++ b/kernel/sched/idle_task.c @@ -26,6 +26,8 @@ static void check_preempt_curr_idle(struct rq *rq, struct task_struct *p, int fl static struct task_struct * pick_next_task_idle(struct rq *rq, struct task_struct *prev) { + idle_enter_rt(rq); + put_prev_task(rq, prev); schedstat_inc(rq, sched_goidle); @@ -47,6 +49,7 @@ dequeue_task_idle(struct rq *rq, struct task_struct *p, int flags) static void put_prev_task_idle(struct rq *rq, struct task_struct *prev) { + idle_exit_rt(rq); idle_exit_fair(rq); rq_last_tick_reset(rq); } diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index d024e6c..da6922e 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -992,6 +992,27 @@ enqueue_top_rt_rq(struct rt_rq *rt_rq) #if defined CONFIG_SMP +/* Set CPUPRI_IDLE bitmap for this cpu when entering idle. */ +void idle_enter_rt(struct rq *this_rq) +{ + struct cpupri *cp = &this_rq->rd->cpupri; + int currpri = cp->cpu_to_pri[this_rq->cpu]; + + BUG_ON(currpri != CPUPRI_NORMAL); + cpupri_set(cp, this_rq->cpu, MAX_PRIO); +} + +/* Set CPUPRI_NORMAL bitmap for this cpu when exiting from idle. */ +void idle_exit_rt(struct rq *this_rq) +{ + struct cpupri *cp = &this_rq->rd->cpupri; + int currpri = cp->cpu_to_pri[this_rq->cpu]; + + /* RT tasks may be queued before, this judgement is needed. */ + if (currpri == CPUPRI_IDLE) + cpupri_set(cp, this_rq->cpu, MAX_RT_PRIO); +} + static void inc_rt_prio_smp(struct rt_rq *rt_rq, int prio, int prev_prio) { diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 24156c84..cc603fa 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1162,11 +1162,17 @@ extern void update_group_capacity(struct sched_domain *sd, int cpu); extern void trigger_load_balance(struct rq *rq); +extern void idle_enter_rt(struct rq *this_rq); +extern void idle_exit_rt(struct rq *this_rq); + extern void idle_enter_fair(struct rq *this_rq); extern void idle_exit_fair(struct rq *this_rq); #else +static inline void idle_enter_rt(struct rq *rq) { } +static inline void idle_exit_rt(struct rq *rq) { } + static inline void idle_enter_fair(struct rq *rq) { } static inline void idle_exit_fair(struct rq *rq) { }