From patchwork Mon Apr 20 08:22:47 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xunlei Pang X-Patchwork-Id: 47333 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wg0-f70.google.com (mail-wg0-f70.google.com [74.125.82.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 9CF0620553 for ; Mon, 20 Apr 2015 08:25:22 +0000 (UTC) Received: by wghm4 with SMTP id m4sf36167688wgh.2 for ; Mon, 20 Apr 2015 01:25:21 -0700 (PDT) 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=fD1TYx/UIuV+tRCnTdyiK1nnzV6rce2hy8gghf9nIN8=; b=DddGlXwNuPLl1VMZD9oqGn2TR/qJnQ8+8fwbLspuhHEEs6CH+C1wmLCEi3PYUvfOhg fCkJTExXclUHi7dtLlOGtbEvHHYC8FY9SdsOopHzSLTH1pgtXMdsBBeUVzdklnnRqWKI Jbrq6O9a82X8qVrFfNsvphwfgU2BrBO6U/5gY9JHqv+TPR051ZFbHROvglzWzFUmZtxm mGygyHCmY0Vzg6UjlTp3PxuLg6UrywY9PBcB2FF4NPMFXj/f9tJXLVSejyaRHzYkPa+6 dmyxYhOhxNoaK55sV80EiJLEvNE6WoTJGogSBl0P627vwsO5sDv01sNLun0pylMLwqKT 4ftg== X-Gm-Message-State: ALoCoQl6i8JnHD3XX6RuVExROaoNjJB568yRTSmzdJmasomWKbsM0dL/flafohIeg6i7Eqf0SS/Z X-Received: by 10.180.73.137 with SMTP id l9mr5573033wiv.5.1429518321934; Mon, 20 Apr 2015 01:25:21 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.37.194 with SMTP id a2ls721113lak.88.gmail; Mon, 20 Apr 2015 01:25:21 -0700 (PDT) X-Received: by 10.152.1.227 with SMTP id 3mr1424189lap.61.1429518321739; Mon, 20 Apr 2015 01:25:21 -0700 (PDT) Received: from mail-lb0-x22b.google.com (mail-lb0-x22b.google.com. [2a00:1450:4010:c04::22b]) by mx.google.com with ESMTPS id k18si14485407lbh.10.2015.04.20.01.25.21 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 20 Apr 2015 01:25:21 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2a00:1450:4010:c04::22b as permitted sender) client-ip=2a00:1450:4010:c04::22b; Received: by lbbqq2 with SMTP id qq2so124543291lbb.3 for ; Mon, 20 Apr 2015 01:25:21 -0700 (PDT) X-Received: by 10.112.29.36 with SMTP id g4mr14979908lbh.56.1429518321595; Mon, 20 Apr 2015 01:25:21 -0700 (PDT) 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.67.65 with SMTP id l1csp1297117lbt; Mon, 20 Apr 2015 01:25:20 -0700 (PDT) X-Received: by 10.70.90.162 with SMTP id bx2mr26004805pdb.60.1429518319648; Mon, 20 Apr 2015 01:25:19 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id hs9si27234284pdb.189.2015.04.20.01.25.18; Mon, 20 Apr 2015 01:25:19 -0700 (PDT) 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 S1754692AbbDTIZN (ORCPT + 26 others); Mon, 20 Apr 2015 04:25:13 -0400 Received: from m50-110.126.com ([123.125.50.110]:40364 "EHLO m50-110.126.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754655AbbDTIZG (ORCPT ); Mon, 20 Apr 2015 04:25:06 -0400 Received: from localhost.localdomain (unknown [210.21.223.3]) by smtp4 (Coremail) with SMTP id jdKowAD3__uLtzRVzV2uAQ--.4394S3; Mon, 20 Apr 2015 16:23:50 +0800 (CST) From: Xunlei Pang To: linux-kernel@vger.kernel.org Cc: Peter Zijlstra , Steven Rostedt , Juri Lelli , Xunlei Pang Subject: [PATCH v6 2/3] sched/rt: Fix wrong SMP scheduler behavior for equal prio cases Date: Mon, 20 Apr 2015 16:22:47 +0800 Message-Id: <1429518168-7965-2-git-send-email-xlpang@126.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1429518168-7965-1-git-send-email-xlpang@126.com> References: <1429518168-7965-1-git-send-email-xlpang@126.com> X-CM-TRANSID: jdKowAD3__uLtzRVzV2uAQ--.4394S3 X-Coremail-Antispam: 1Uf129KBjvJXoWxGFWrZr4kur48Gw4xXF13Jwb_yoWrJw48pa 48Jw1jyw4kJa9Fgrn3Xr48Zr43Gw1vq3y5JF93K3y5KanYqFy0qFnYvry3tFWrKr1vga17 tF4ktrsxGr1UZF7anT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07jlPfPUUUUU= X-Originating-IP: [210.21.223.3] X-CM-SenderInfo: p0ost0bj6rjloofrz/1tbiJxbhv01sBUvfIAAAs- Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Original-Sender: xlpang@126.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2a00:1450:4010:c04::22b as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org; dkim=neutral (body hash did not verify) header.i=@; dmarc=fail (p=NONE dis=NONE) header.from=126.com 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: , From: Xunlei Pang Currently, SMP RT scheduler has some trouble in dealing with equal prio cases. For example, in check_preempt_equal_prio(): When RT1(current task) gets preempted by RT2, if there is a migratable RT3 with same prio, RT3 will be pushed away instead of RT1 afterwards, because RT1 will be enqueued to the tail of the pushable list when going through succeeding put_prev_task_rt() triggered by resched. This broke FIFO. Furthermore, this is also problematic for normal preempted cases if there're some rt tasks queued with the same prio as current. Because current will be put behind these tasks in the pushable queue. So, if a task is running and gets preempted by a higher priority task (or even with same priority for migrating), this patch ensures that it is put ahead of any existing task with the same priority in the pushable queue. Suggested-by: Steven Rostedt Signed-off-by: Xunlei Pang --- v5->v6: Add wrapped enqueue_pushable_task_preempted() and enqueue_pushable_task() for __enqueue_pushable_task() to avoid the "bool head" parameter everywhere. kernel/sched/rt.c | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 575da76..8679eff 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -359,17 +359,32 @@ static inline void set_post_schedule(struct rq *rq) rq->post_schedule = has_pushable_tasks(rq); } -static void enqueue_pushable_task(struct rq *rq, struct task_struct *p) +static void +__enqueue_pushable_task(struct rq *rq, struct task_struct *p, bool head) { plist_del(&p->pushable_tasks, &rq->rt.pushable_tasks); plist_node_init(&p->pushable_tasks, p->prio); - plist_add(&p->pushable_tasks, &rq->rt.pushable_tasks); + if (head) + plist_add_head(&p->pushable_tasks, &rq->rt.pushable_tasks); + else + plist_add_tail(&p->pushable_tasks, &rq->rt.pushable_tasks); /* Update the highest prio pushable task */ if (p->prio < rq->rt.highest_prio.next) rq->rt.highest_prio.next = p->prio; } +static inline +void enqueue_pushable_task_preempted(struct rq *rq, struct task_struct *p) +{ + __enqueue_pushable_task(rq, p, true); +} + +static inline void enqueue_pushable_task(struct rq *rq, struct task_struct *p) +{ + __enqueue_pushable_task(rq, p, false); +} + static void dequeue_pushable_task(struct rq *rq, struct task_struct *p) { plist_del(&p->pushable_tasks, &rq->rt.pushable_tasks); @@ -385,6 +400,11 @@ static void dequeue_pushable_task(struct rq *rq, struct task_struct *p) #else +static inline +void enqueue_pushable_task_preempted(struct rq *rq, struct task_struct *p) +{ +} + static inline void enqueue_pushable_task(struct rq *rq, struct task_struct *p) { } @@ -1506,8 +1526,21 @@ static void put_prev_task_rt(struct rq *rq, struct task_struct *p) * The previous task needs to be made eligible for pushing * if it is still active */ - if (on_rt_rq(&p->rt) && p->nr_cpus_allowed > 1) - enqueue_pushable_task(rq, p); + if (on_rt_rq(&p->rt) && p->nr_cpus_allowed > 1) { + /* + * put_prev_task_rt() is called by many functions, + * pick_next_task_rt() is the only one may have + * PREEMPT_ACTIVE set. So if detecting p(current + * task) is preempted in such case, we should + * enqueue it to the front of the pushable plist, + * as there may be multiple tasks with the same + * priority as p. + */ + if (preempt_count() & PREEMPT_ACTIVE) + enqueue_pushable_task_preempted(rq, p); + else + enqueue_pushable_task(rq, p); + } } #ifdef CONFIG_SMP