Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp448522ybl; Wed, 29 Jan 2020 03:34:11 -0800 (PST) X-Google-Smtp-Source: APXvYqwHT98+f8BjCZCZK5Wt+aiC7sY5+KDLtQxF8mq9U+k1Ru/HL4UaqI0SV++waDTtThB8bNtP X-Received: by 2002:a9d:ec1:: with SMTP id 59mr19472427otj.141.1580297651134; Wed, 29 Jan 2020 03:34:11 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1580297651; cv=none; d=google.com; s=arc-20160816; b=XA/vl+IJdpt/R2wMBn3iXaJ4K0cCNSJJiukdchLMjoGq0Jy1GqQqEOusU9h5ghpMV9 RsMuQ/z2KUJVVXqPuHodTZchwjeEs6VXWKFUz2P7mE88m2cvH+2H7b2R/D/GnSfVuw6J XkaxaFY2gUMx6peBmeKCYb4aeP0zCSThjdyu15RSMe3SHogAgSt+t0S0ZZ683MzG38Ed qQk1bOAlhVeBqidUBNtKgcmRMkeGDrx/9fvIV8vutxxcOipQEYItm8XCGBnWva/fTfb9 o5ftoKCHDjF5KVa2aa/er4g8ZxhBU5f8gEks38DIN/TuGa/kcXBzQ/f+BCeOyCu9dKUG EU/g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :robot-unsubscribe:robot-id:message-id:mime-version:references :in-reply-to:cc:subject:to:reply-to:from:date; bh=1dunPml/G4ULk113HafOgauZfcIiHT+tCOYvwtlaBvA=; b=ZIdPeRbggqiBQ9xq61nlSChsrgJe0QgBo+o4GIiPQVZrezk+RRcC4LVRWrrjYZsZUD uZkrynpE2QZiArJV7aZw7lB5+4iD193WAZ0Lw9PPd56Fimyg2O5QzD8W56+Keld45w9I Fyckqu7wj80vSi5kJg1GJIozZpenJaqA0+w0Yyv7jIShOMEDJoP5pPB1WadmlTr+/sfC uLa+IFypTTbEyJLHKALc2b0KsIT7Bi7BBfsg2J/75L4BmyKoQle/l0vD3dD1yJB1H9Y1 av+ZFml1y1iKb8VTsLvggMCTWYa357nwT4PUZC0OSj+cr1DTa1YU9CTcB6Gt67sa3FLA cFiQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x197si859862oix.174.2020.01.29.03.33.57; Wed, 29 Jan 2020 03:34:11 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726358AbgA2LdC (ORCPT + 99 others); Wed, 29 Jan 2020 06:33:02 -0500 Received: from Galois.linutronix.de ([193.142.43.55]:51027 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726140AbgA2LdC (ORCPT ); Wed, 29 Jan 2020 06:33:02 -0500 Received: from [5.158.153.53] (helo=tip-bot2.lab.linutronix.de) by Galois.linutronix.de with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1iwlab-0007kQ-2E; Wed, 29 Jan 2020 12:32:57 +0100 Received: from [127.0.1.1] (localhost [IPv6:::1]) by tip-bot2.lab.linutronix.de (Postfix) with ESMTP id B57291C0095; Wed, 29 Jan 2020 12:32:56 +0100 (CET) Date: Wed, 29 Jan 2020 11:32:56 -0000 From: "tip-bot2 for Konstantin Khlebnikov" Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: sched/core] sched/rt: Optimize checking group RT scheduler constraints Cc: Konstantin Khlebnikov , "Peter Zijlstra (Intel)" , Ingo Molnar , x86 , LKML In-Reply-To: <157996383820.4651.11292439232549211693.stgit@buzz> References: <157996383820.4651.11292439232549211693.stgit@buzz> MIME-Version: 1.0 Message-ID: <158029757654.396.14560704856092377008.tip-bot2@tip-bot2> X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Linutronix-Spam-Score: 1.5 X-Linutronix-Spam-Level: + X-Linutronix-Spam-Status: No , 1.5 points, 5.0 required, ALL_TRUSTED=-1,SHORTCIRCUIT=-0.0001,URIBL_DBL_ABUSE_MALW=2.5 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The following commit has been merged into the sched/core branch of tip: Commit-ID: b4fb015eeff7f3e5518a7dbe8061169a3e2f2bc7 Gitweb: https://git.kernel.org/tip/b4fb015eeff7f3e5518a7dbe8061169a3e2f2bc7 Author: Konstantin Khlebnikov AuthorDate: Sat, 25 Jan 2020 17:50:38 +03:00 Committer: Ingo Molnar CommitterDate: Tue, 28 Jan 2020 21:37:09 +01:00 sched/rt: Optimize checking group RT scheduler constraints Group RT scheduler contains protection against setting zero runtime for cgroup with RT tasks. Right now function tg_set_rt_bandwidth() iterates over all CPU cgroups and calls tg_has_rt_tasks() for any cgroup which runtime is zero (not only for changed one). Default RT runtime is zero, thus tg_has_rt_tasks() will is called for almost at CPU cgroups. This protection already is slightly racy: runtime limit could be changed between cpu_cgroup_can_attach() and cpu_cgroup_attach() because changing cgroup attribute does not lock cgroup_mutex while attach does not lock rt_constraints_mutex. Changing task scheduler class also races with changing rt runtime: check in __sched_setscheduler() isn't protected. Function tg_has_rt_tasks() iterates over all threads in the system. This gives NR_CGROUPS * NR_TASKS operations under single tasklist_lock locked for read tg_set_rt_bandwidth(). Any concurrent attempt of locking tasklist_lock for write (for example fork) will stuck with disabled irqs. This patch makes two optimizations: 1) Remove locking tasklist_lock and iterate only tasks in cgroup 2) Call tg_has_rt_tasks() iff rt runtime changes from non-zero to zero All changed code is under CONFIG_RT_GROUP_SCHED. Testcase: # mkdir /sys/fs/cgroup/cpu/test{1..10000} # echo 0 | tee /sys/fs/cgroup/cpu/test*/cpu.rt_runtime_us At the same time without patch fork time will be >100ms: # perf trace -e clone --duration 100 stress-ng --fork 1 Also remote ping will show timings >100ms caused by irq latency. Signed-off-by: Konstantin Khlebnikov Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Ingo Molnar Link: https://lkml.kernel.org/r/157996383820.4651.11292439232549211693.stgit@buzz --- kernel/sched/rt.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 4043abe..55a4a50 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -2449,10 +2449,11 @@ const struct sched_class rt_sched_class = { */ static DEFINE_MUTEX(rt_constraints_mutex); -/* Must be called with tasklist_lock held */ static inline int tg_has_rt_tasks(struct task_group *tg) { - struct task_struct *g, *p; + struct task_struct *task; + struct css_task_iter it; + int ret = 0; /* * Autogroups do not have RT tasks; see autogroup_create(). @@ -2460,12 +2461,12 @@ static inline int tg_has_rt_tasks(struct task_group *tg) if (task_group_is_autogroup(tg)) return 0; - for_each_process_thread(g, p) { - if (rt_task(p) && task_group(p) == tg) - return 1; - } + css_task_iter_start(&tg->css, 0, &it); + while (!ret && (task = css_task_iter_next(&it))) + ret |= rt_task(task); + css_task_iter_end(&it); - return 0; + return ret; } struct rt_schedulable_data { @@ -2496,9 +2497,10 @@ static int tg_rt_schedulable(struct task_group *tg, void *data) return -EINVAL; /* - * Ensure we don't starve existing RT tasks. + * Ensure we don't starve existing RT tasks if runtime turns zero. */ - if (rt_bandwidth_enabled() && !runtime && tg_has_rt_tasks(tg)) + if (rt_bandwidth_enabled() && !runtime && + tg->rt_bandwidth.rt_runtime && tg_has_rt_tasks(tg)) return -EBUSY; total = to_ratio(period, runtime); @@ -2564,7 +2566,6 @@ static int tg_set_rt_bandwidth(struct task_group *tg, return -EINVAL; mutex_lock(&rt_constraints_mutex); - read_lock(&tasklist_lock); err = __rt_schedulable(tg, rt_period, rt_runtime); if (err) goto unlock; @@ -2582,7 +2583,6 @@ static int tg_set_rt_bandwidth(struct task_group *tg, } raw_spin_unlock_irq(&tg->rt_bandwidth.rt_runtime_lock); unlock: - read_unlock(&tasklist_lock); mutex_unlock(&rt_constraints_mutex); return err; @@ -2641,9 +2641,7 @@ static int sched_rt_global_constraints(void) int ret = 0; mutex_lock(&rt_constraints_mutex); - read_lock(&tasklist_lock); ret = __rt_schedulable(NULL, 0, 0); - read_unlock(&tasklist_lock); mutex_unlock(&rt_constraints_mutex); return ret;