Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp6360491imu; Mon, 21 Jan 2019 07:36:25 -0800 (PST) X-Google-Smtp-Source: ALg8bN5Z5VHokWJhSxsETp7zoyDZU6CkSFazoebXr/DoJbDZMwLMdFr+LoR1nO6ewTexZfRZG9Pu X-Received: by 2002:a62:5910:: with SMTP id n16mr29808342pfb.128.1548084985819; Mon, 21 Jan 2019 07:36:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548084985; cv=none; d=google.com; s=arc-20160816; b=AIFyKbuJ6hL7YmZZsgfMbZA3efKqgoXRVcTHT5M0fXovk+yMAgOAulz+GC3+T9nLci KgX+FqbTfTKFDOP/WxN9a4B9c/Ev4pirI5EpJLSD3jWNasxBV+aNollnVZq7vrZDN81u mG1Il59HVT7NmpDHg/pQ2k+/dVsDV6yRXieQqfervzeWb5cq9L5Uj/nHmzOMBRnihm+a AgM46af+3Y8UbxABOr22oESnHoaOpFwSFoTGU52JlqEDimG9kZKUgjXjya5VDaG+HXvv 1QZ1ZDaRwLNhZNG8MR9L1LXwE4ERDMb5j567FbsjQOnFSigxzfNvQR/b88DPAWqbsM4H k76w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=hC8tGq4roFSJ9OuhHl/+64mJOh41vMAu/aLMcavPFBs=; b=KDR95FwaLN7VUk1CC9q5F13KxURQyRINq5y/VjIxfeIlhxZQuWPKMEftT4lRmfeSt0 3R6KqnDjqbed2VJRG3WHUscCBI/B3R1qI0emIlz8qWHSlFihi9E3qMyiEfBbKs8SePKc t7BMlULwQSa2kG7tFdKajIccih6aEHxvSsLwqcRGboHjtmeacdXSIAyNmuCYQFrTJ4pn pAoYifRSZKY7+PypaDTkokxvJ7sxxrwPwCsbwdoc6tqHdC3LXMYjcIkRWBv69DiFSaTT CziQcjnNXOS586UyWNG1iUXf4zwqSmpx10/xv+42TOTf7ZofKbTxKl1WmMNyjenUX7ZJ BIyw== 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 d38si13070452pla.207.2019.01.21.07.36.10; Mon, 21 Jan 2019 07:36:25 -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 S1730373AbfAUPej (ORCPT + 99 others); Mon, 21 Jan 2019 10:34:39 -0500 Received: from foss.arm.com ([217.140.101.70]:36556 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730313AbfAUPei (ORCPT ); Mon, 21 Jan 2019 10:34:38 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 08AB8165C; Mon, 21 Jan 2019 07:34:38 -0800 (PST) Received: from e110439-lin (e110439-lin.cambridge.arm.com [10.1.194.43]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 154C93F7BE; Mon, 21 Jan 2019 07:34:34 -0800 (PST) Date: Mon, 21 Jan 2019 15:34:32 +0000 From: Patrick Bellasi To: Peter Zijlstra Cc: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, linux-api@vger.kernel.org, Ingo Molnar , Tejun Heo , "Rafael J . Wysocki" , Vincent Guittot , Viresh Kumar , Paul Turner , Quentin Perret , Dietmar Eggemann , Morten Rasmussen , Juri Lelli , Todd Kjos , Joel Fernandes , Steve Muckle , Suren Baghdasaryan Subject: Re: [PATCH v6 03/16] sched/core: uclamp: Map TASK's clamp values into CPU's clamp buckets Message-ID: <20190121153432.vlhgxvd2otvu24st@e110439-lin> References: <20190115101513.2822-1-patrick.bellasi@arm.com> <20190115101513.2822-4-patrick.bellasi@arm.com> <20190121150507.GJ27931@hirez.programming.kicks-ass.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20190121150507.GJ27931@hirez.programming.kicks-ass.net> User-Agent: NeoMutt/20180716 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 21-Jan 16:05, Peter Zijlstra wrote: > On Tue, Jan 15, 2019 at 10:15:00AM +0000, Patrick Bellasi wrote: > > +static inline unsigned int uclamp_bucket_value(unsigned int clamp_value) > > +{ > > +#define UCLAMP_BUCKET_DELTA (SCHED_CAPACITY_SCALE / CONFIG_UCLAMP_BUCKETS_COUNT) > > +#define UCLAMP_BUCKET_UPPER (UCLAMP_BUCKET_DELTA * CONFIG_UCLAMP_BUCKETS_COUNT) > > + > > + if (clamp_value >= UCLAMP_BUCKET_UPPER) > > + return SCHED_CAPACITY_SCALE; > > + > > + return UCLAMP_BUCKET_DELTA * (clamp_value / UCLAMP_BUCKET_DELTA); > > +} > > > +static void uclamp_bucket_inc(struct uclamp_se *uc_se, unsigned int clamp_id, > > + unsigned int clamp_value) > > +{ > > + union uclamp_map *uc_maps = &uclamp_maps[clamp_id][0]; > > + unsigned int prev_bucket_id = uc_se->bucket_id; > > + union uclamp_map uc_map_old, uc_map_new; > > + unsigned int free_bucket_id; > > + unsigned int bucket_value; > > + unsigned int bucket_id; > > + > > + bucket_value = uclamp_bucket_value(clamp_value); > > Aahh!! > > So why don't you do: > > bucket_id = clamp_value / UCLAMP_BUCKET_DELTA; > bucket_value = bucket_id * UCLAMP_BUCKET_DELTA; The mapping done here is meant to keep at the beginning of the cache line all and only the buckets we use. Let say we have configured the system to track 20 buckets, to have a 5% clamping resolution, but then we use only two values at run-time, e.g. 13% and 87%. With the mapping done here the per-CPU variables will have to consider only 2 buckets: bucket_#00: clamp value: 10% (mapped) bucket_#01: clamp value: 85% (mapped) bucket_#02: (free) ... bucket_#20: (free) While without the mapping we will have: bucket_#00: (free) bucket_#01: clamp value: 10 (mapped) bucket_#02: (free) ... big hole crossing a cache line .... bucket_#16: (free) bucket_#17: clamp value: 85 (mapped) bucket_#18: (free) ... bucket_#20: (free) Addressing is simple without mapping but we can have performance issues in the hot-path, since sometimes we need to scan all the buckets to figure out the new max. The mapping done here is meant to keep all the used slots at the very beginning of a cache line to speed up that max computation when required. > > > + do { > > + /* Find the bucket_id of an already mapped clamp bucket... */ > > + free_bucket_id = UCLAMP_BUCKETS; > > + for (bucket_id = 0; bucket_id < UCLAMP_BUCKETS; ++bucket_id) { > > + uc_map_old.data = atomic_long_read(&uc_maps[bucket_id].adata); > > + if (free_bucket_id == UCLAMP_BUCKETS && !uc_map_old.se_count) > > + free_bucket_id = bucket_id; > > + if (uc_map_old.value == bucket_value) > > + break; > > + } > > + > > + /* ... or allocate a new clamp bucket */ > > + if (bucket_id >= UCLAMP_BUCKETS) { > > + /* > > + * A valid clamp bucket must always be available. > > + * If we cannot find one: refcounting is broken and we > > + * warn once. The sched_entity will be tracked in the > > + * fast-path using its previous clamp bucket, or not > > + * tracked at all if not yet mapped (i.e. it's new). > > + */ > > + if (unlikely(free_bucket_id == UCLAMP_BUCKETS)) { > > + SCHED_WARN_ON(free_bucket_id == UCLAMP_BUCKETS); > > + return; > > + } > > + bucket_id = free_bucket_id; > > + uc_map_old.data = atomic_long_read(&uc_maps[bucket_id].adata); > > + } > > And then skip all this? > > + > > + uc_map_new.se_count = uc_map_old.se_count + 1; > > + uc_map_new.value = bucket_value; > > + > > + } while (!atomic_long_try_cmpxchg(&uc_maps[bucket_id].adata, > > + &uc_map_old.data, uc_map_new.data)); > > + > > + uc_se->value = clamp_value; > > + uc_se->bucket_id = bucket_id; > > + > > + if (uc_se->mapped) > > + uclamp_bucket_dec(clamp_id, prev_bucket_id); > > + > > + /* > > + * Task's sched_entity are refcounted in the fast-path only when they > > + * have got a valid clamp_bucket assigned. > > + */ > > + uc_se->mapped = true; > > +} -- #include Patrick Bellasi