Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp2331338imm; Fri, 7 Sep 2018 14:48:55 -0700 (PDT) X-Google-Smtp-Source: ANB0VdaTw8nDraeVV4bJ7ZlHJEhxgKGtbUiHKoaNub2a2WKKLS0s8bqkmWpna1JfZ2Qg4VM9AejL X-Received: by 2002:aa7:8118:: with SMTP id b24-v6mr10792531pfi.78.1536356935306; Fri, 07 Sep 2018 14:48:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1536356935; cv=none; d=google.com; s=arc-20160816; b=nlxtgZQIcCvOK11k+6GYST0Ecyte7UpbGNWQ7GG0Itesi+sJiyqpcCI7bt54Tl7zj6 Qxbj06wgl/61yNoaaZ5cFafBs7B1+TDIpv1uXYNMHPuHnawtWUb5vaw/BDVRMwAlE/J0 aTByuOSi5k1vtrewxa2OFaTJugRyJU21wAvjvW1kV6iTg3rwaUuz6J/Fx/iX3tTXWUds uCE2BzZM9BtBcMVjR1GiMAJVloFeNyfN9HPwdfDdDeEdJUIlKw5zeaqmK5Bq59bCV52r Cv0rdtXAwI0uWcSD8SevZnA5ZWxJxBfj8K0HAfg6jLyldsmQDJym6uwRlB/6Gr/ZDgBj UCRg== 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:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=gMB4V5wK/BxzmjXx2WZsy0dy3j5BDmMkOAQFP/S9lho=; b=dr5XzfVvuUDPU6jM/AaoOv3zCOE8NgRXrUCJt4vT/DsreKZYwVraJ2aNJLa2QLSRqh Q1GhBqAnFx9o1V2xR1Zk/8P4HmZ3XPGzKbwMb+rskPEciWtyY0x5wy5/VsFLsMRZ8ZvF Pg/+jtZQ2NBAMFU7bOM+jdY66564MFE2Xmzdy787HtRJuZcNPs5oXl2HLmk5FxKpBB96 GLBK7Wj/HS2mn+6RKYS5cUmwZCGRMO8ap4MpAuzVzvbJgilXSHonBSCAcvooKWt0gF5d yhElBi7LWVP2CTV71o9xREXa9YHpFxlcdWRNb5AWuJ4RwKkDoottTrUYGORp6Dim9nCF X+NA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amazon.de header.s=amazon201209 header.b=XRmR5Z1N; 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; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=amazon.de Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k3-v6si9174061pld.6.2018.09.07.14.48.40; Fri, 07 Sep 2018 14:48:55 -0700 (PDT) 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; dkim=pass header.i=@amazon.de header.s=amazon201209 header.b=XRmR5Z1N; 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; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=amazon.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731016AbeIHC3h (ORCPT + 99 others); Fri, 7 Sep 2018 22:29:37 -0400 Received: from smtp-fw-9101.amazon.com ([207.171.184.25]:32267 "EHLO smtp-fw-9101.amazon.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728423AbeIHC3g (ORCPT ); Fri, 7 Sep 2018 22:29:36 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.de; i=@amazon.de; q=dns/txt; s=amazon201209; t=1536356799; x=1567892799; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=gMB4V5wK/BxzmjXx2WZsy0dy3j5BDmMkOAQFP/S9lho=; b=XRmR5Z1N9Uz3OVQwmlIpfgkKN2JfEy2lFChMdSzvl/VVXM7ZxWO7O+ja OiOmj3iA8juA54XNPVnotPhR9XyGvN2r+eb+l0mr0Shi9EoDeswLuoUQG nAvfixGXYit4s5EXXu8ujEORNfQXoY0e0GkNNwpYuvpcIRTsFvvje3XRm I=; X-IronPort-AV: E=Sophos;i="5.53,343,1531785600"; d="scan'208";a="757370735" Received: from sea3-co-svc-lb6-vlan3.sea.amazon.com (HELO email-inbound-relay-1d-74cf8b49.us-east-1.amazon.com) ([10.47.22.38]) by smtp-border-fw-out-9101.sea19.amazon.com with ESMTP/TLS/DHE-RSA-AES256-SHA; 07 Sep 2018 21:44:03 +0000 Received: from u7588a65da6b65f.ant.amazon.com (iad7-ws-svc-lb50-vlan2.amazon.com [10.0.93.210]) by email-inbound-relay-1d-74cf8b49.us-east-1.amazon.com (8.14.7/8.14.7) with ESMTP id w87Lgbcf052690 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 7 Sep 2018 21:42:39 GMT Received: from u7588a65da6b65f.ant.amazon.com (localhost [127.0.0.1]) by u7588a65da6b65f.ant.amazon.com (8.15.2/8.15.2/Debian-3) with ESMTPS id w87LgZKt027645 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 7 Sep 2018 23:42:35 +0200 Received: (from jschoenh@localhost) by u7588a65da6b65f.ant.amazon.com (8.15.2/8.15.2/Submit) id w87LgYNd027640; Fri, 7 Sep 2018 23:42:34 +0200 From: =?UTF-8?q?Jan=20H=2E=20Sch=C3=B6nherr?= To: Ingo Molnar , Peter Zijlstra Cc: =?UTF-8?q?Jan=20H=2E=20Sch=C3=B6nherr?= , linux-kernel@vger.kernel.org Subject: [RFC 42/60] cosched: Introduce locking for (mostly) enqueuing and dequeuing Date: Fri, 7 Sep 2018 23:40:29 +0200 Message-Id: <20180907214047.26914-43-jschoenh@amazon.de> X-Mailer: git-send-email 2.9.3.1.gcba166c.dirty In-Reply-To: <20180907214047.26914-1-jschoenh@amazon.de> References: <20180907214047.26914-1-jschoenh@amazon.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org With hierarchical runqueues and locks at each level, it is often necessary to get locks at different level. Introduce the second of two locking strategies, which is suitable for progressing upwards through the hierarchy with minimal impact on lock contention. During enqueuing and dequeuing, a scheduling entity is recursively added or removed from the runqueue hierarchy. This is an upwards only progression through the hierarchy, which does not care about which CPU is responsible for a certain part of the hierarchy. Hence, it is not necessary to hold on to a lock of a lower hierarchy level once we moved on to a higher one. Introduce rq_chain_init(), rq_chain_lock(), and rq_chain_unlock(), which implement lock chaining, where the previous lock is only released after we acquired the next one, so that concurrent operations cannot overtake each other. The functions can be used even when parts have already been locked via rq_lock_owned(), as for example dequeueing might happen during task selection if a runqueue is throttled. Signed-off-by: Jan H. Schönherr --- kernel/sched/cosched.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/sched/sched.h | 14 +++++++++++++ 2 files changed, 67 insertions(+) diff --git a/kernel/sched/cosched.c b/kernel/sched/cosched.c index df62ee6d0520..f2d51079b3db 100644 --- a/kernel/sched/cosched.c +++ b/kernel/sched/cosched.c @@ -608,3 +608,56 @@ void rq_unlock_owned(struct rq *rq, struct rq_owner_flags *orf) rq_unlock(rq, &rq->sdrq_data.rf); } } + +void rq_chain_init(struct rq_chain *rc, struct rq *rq) +{ + bool parent_locked = rq->sdrq_data.parent_locked; + + WARN_ON_ONCE(!irqs_disabled()); + lockdep_assert_held(&rq->lock); + + rq = parent_rq(rq); + while (parent_locked) { + lockdep_assert_held(&rq->lock); + parent_locked = rq->sdrq_data.parent_locked; + rq = parent_rq(rq); + } + + rc->next = rq; + rc->curr = NULL; +} + +void rq_chain_unlock(struct rq_chain *rc) +{ + if (rc->curr) + rq_unlock(rc->curr, &rc->rf); +} + +void rq_chain_lock(struct rq_chain *rc, struct sched_entity *se) +{ + struct cfs_rq *cfs_rq = se->cfs_rq; + struct rq *rq = cfs_rq->rq; + + if (!is_sd_se(se) || rc->curr == rq) { + lockdep_assert_held(&rq->lock); + return; + } + + if (rq == rc->next) { + struct rq_flags rf = rc->rf; + + /* Get the new lock (and release previous lock afterwards) */ + rq_lock(rq, &rc->rf); + + if (rc->curr) { + lockdep_assert_held(&rc->curr->lock); + rq_unlock(rc->curr, &rf); + } + + rc->curr = rq; + rc->next = parent_rq(rq); + + /* FIXME: Only update clock, when necessary */ + update_rq_clock(rq); + } +} diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 7dba8fdc48c7..48939c8e539d 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -513,6 +513,14 @@ struct rq_owner_flags { #endif }; +struct rq_chain { +#ifdef CONFIG_COSCHEDULING + struct rq *next; + struct rq *curr; + struct rq_flags rf; +#endif +}; + #ifdef CONFIG_COSCHEDULING struct sdrq_data { /* @@ -1206,6 +1214,9 @@ void cosched_online_group(struct task_group *tg); void cosched_offline_group(struct task_group *tg); struct rq *rq_lock_owned(struct rq *rq, struct rq_owner_flags *orf); void rq_unlock_owned(struct rq *rq, struct rq_owner_flags *orf); +void rq_chain_init(struct rq_chain *rc, struct rq *rq); +void rq_chain_unlock(struct rq_chain *rc); +void rq_chain_lock(struct rq_chain *rc, struct sched_entity *se); #else /* !CONFIG_COSCHEDULING */ static inline void cosched_init_bottom(void) { } static inline void cosched_init_topology(void) { } @@ -1217,6 +1228,9 @@ static inline void cosched_online_group(struct task_group *tg) { } static inline void cosched_offline_group(struct task_group *tg) { } static inline struct rq *rq_lock_owned(struct rq *rq, struct rq_owner_flags *orf) { return rq; } static inline void rq_unlock_owned(struct rq *rq, struct rq_owner_flags *orf) { } +static inline void rq_chain_init(struct rq_chain *rc, struct rq *rq) { } +static inline void rq_chain_unlock(struct rq_chain *rc) { } +static inline void rq_chain_lock(struct rq_chain *rc, struct sched_entity *se) { } #endif /* !CONFIG_COSCHEDULING */ #ifdef CONFIG_SCHED_SMT -- 2.9.3.1.gcba166c.dirty