public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	patches@lists.linux.dev, Yun Hsiang <hsiang023167@gmail.com>,
	Qais Yousef <qais.yousef@arm.com>,
	"Peter Zijlstra (Intel)" <peterz@infradead.org>,
	"Qais Yousef (Google)" <qyousef@layalina.io>
Subject: [PATCH 5.15 45/73] sched/uclamp: Fix fits_capacity() check in feec()
Date: Mon, 24 Apr 2023 15:16:59 +0200	[thread overview]
Message-ID: <20230424131130.655453142@linuxfoundation.org> (raw)
In-Reply-To: <20230424131129.040707961@linuxfoundation.org>

From: Qais Yousef <qais.yousef@arm.com>

commit 244226035a1f9b2b6c326e55ae5188fab4f428cb upstream.

As reported by Yun Hsiang [1], if a task has its uclamp_min >= 0.8 * 1024,
it'll always pick the previous CPU because fits_capacity() will always
return false in this case.

The new util_fits_cpu() logic should handle this correctly for us beside
more corner cases where similar failures could occur, like when using
UCLAMP_MAX.

We open code uclamp_rq_util_with() except for the clamp() part,
util_fits_cpu() needs the 'raw' values to be passed to it.

Also introduce uclamp_rq_{set, get}() shorthand accessors to get uclamp
value for the rq. Makes the code more readable and ensures the right
rules (use READ_ONCE/WRITE_ONCE) are respected transparently.

[1] https://lists.linaro.org/pipermail/eas-dev/2020-July/001488.html

Fixes: 1d42509e475c ("sched/fair: Make EAS wakeup placement consider uclamp restrictions")
Reported-by: Yun Hsiang <hsiang023167@gmail.com>
Signed-off-by: Qais Yousef <qais.yousef@arm.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20220804143609.515789-4-qais.yousef@arm.com
(cherry picked from commit 244226035a1f9b2b6c326e55ae5188fab4f428cb)
[Conflict in kernel/sched/fair.c mainly due to new automatic variables
being added on master vs 5.15]
Signed-off-by: Qais Yousef (Google) <qyousef@layalina.io>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/sched/core.c  |   10 +++++-----
 kernel/sched/fair.c  |   26 ++++++++++++++++++++++++--
 kernel/sched/sched.h |   42 +++++++++++++++++++++++++++++++++++++++---
 3 files changed, 68 insertions(+), 10 deletions(-)

--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -1335,7 +1335,7 @@ static inline void uclamp_idle_reset(str
 	if (!(rq->uclamp_flags & UCLAMP_FLAG_IDLE))
 		return;
 
-	WRITE_ONCE(rq->uclamp[clamp_id].value, clamp_value);
+	uclamp_rq_set(rq, clamp_id, clamp_value);
 }
 
 static inline
@@ -1513,8 +1513,8 @@ static inline void uclamp_rq_inc_id(stru
 	if (bucket->tasks == 1 || uc_se->value > bucket->value)
 		bucket->value = uc_se->value;
 
-	if (uc_se->value > READ_ONCE(uc_rq->value))
-		WRITE_ONCE(uc_rq->value, uc_se->value);
+	if (uc_se->value > uclamp_rq_get(rq, clamp_id))
+		uclamp_rq_set(rq, clamp_id, uc_se->value);
 }
 
 /*
@@ -1580,7 +1580,7 @@ static inline void uclamp_rq_dec_id(stru
 	if (likely(bucket->tasks))
 		return;
 
-	rq_clamp = READ_ONCE(uc_rq->value);
+	rq_clamp = uclamp_rq_get(rq, clamp_id);
 	/*
 	 * Defensive programming: this should never happen. If it happens,
 	 * e.g. due to future modification, warn and fixup the expected value.
@@ -1588,7 +1588,7 @@ static inline void uclamp_rq_dec_id(stru
 	SCHED_WARN_ON(bucket->value > rq_clamp);
 	if (bucket->value >= rq_clamp) {
 		bkt_clamp = uclamp_rq_max_value(rq, clamp_id, uc_se->value);
-		WRITE_ONCE(uc_rq->value, bkt_clamp);
+		uclamp_rq_set(rq, clamp_id, bkt_clamp);
 	}
 }
 
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -6985,6 +6985,8 @@ compute_energy(struct task_struct *p, in
 static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
 {
 	unsigned long prev_delta = ULONG_MAX, best_delta = ULONG_MAX;
+	unsigned long p_util_min = uclamp_is_used() ? uclamp_eff_value(p, UCLAMP_MIN) : 0;
+	unsigned long p_util_max = uclamp_is_used() ? uclamp_eff_value(p, UCLAMP_MAX) : 1024;
 	struct root_domain *rd = cpu_rq(smp_processor_id())->rd;
 	int cpu, best_energy_cpu = prev_cpu, target = -1;
 	unsigned long cpu_cap, util, base_energy = 0;
@@ -7014,6 +7016,8 @@ static int find_energy_efficient_cpu(str
 
 	for (; pd; pd = pd->next) {
 		unsigned long cur_delta, spare_cap, max_spare_cap = 0;
+		unsigned long rq_util_min, rq_util_max;
+		unsigned long util_min, util_max;
 		bool compute_prev_delta = false;
 		unsigned long base_energy_pd;
 		int max_spare_cap_cpu = -1;
@@ -7034,8 +7038,26 @@ static int find_energy_efficient_cpu(str
 			 * much capacity we can get out of the CPU; this is
 			 * aligned with sched_cpu_util().
 			 */
-			util = uclamp_rq_util_with(cpu_rq(cpu), util, p);
-			if (!fits_capacity(util, cpu_cap))
+			if (uclamp_is_used()) {
+				if (uclamp_rq_is_idle(cpu_rq(cpu))) {
+					util_min = p_util_min;
+					util_max = p_util_max;
+				} else {
+					/*
+					 * Open code uclamp_rq_util_with() except for
+					 * the clamp() part. Ie: apply max aggregation
+					 * only. util_fits_cpu() logic requires to
+					 * operate on non clamped util but must use the
+					 * max-aggregated uclamp_{min, max}.
+					 */
+					rq_util_min = uclamp_rq_get(cpu_rq(cpu), UCLAMP_MIN);
+					rq_util_max = uclamp_rq_get(cpu_rq(cpu), UCLAMP_MAX);
+
+					util_min = max(rq_util_min, p_util_min);
+					util_max = max(rq_util_max, p_util_max);
+				}
+			}
+			if (!util_fits_cpu(util, util_min, util_max, cpu))
 				continue;
 
 			if (cpu == prev_cpu) {
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -2855,6 +2855,23 @@ static inline void cpufreq_update_util(s
 #ifdef CONFIG_UCLAMP_TASK
 unsigned long uclamp_eff_value(struct task_struct *p, enum uclamp_id clamp_id);
 
+static inline unsigned long uclamp_rq_get(struct rq *rq,
+					  enum uclamp_id clamp_id)
+{
+	return READ_ONCE(rq->uclamp[clamp_id].value);
+}
+
+static inline void uclamp_rq_set(struct rq *rq, enum uclamp_id clamp_id,
+				 unsigned int value)
+{
+	WRITE_ONCE(rq->uclamp[clamp_id].value, value);
+}
+
+static inline bool uclamp_rq_is_idle(struct rq *rq)
+{
+	return rq->uclamp_flags & UCLAMP_FLAG_IDLE;
+}
+
 /**
  * uclamp_rq_util_with - clamp @util with @rq and @p effective uclamp values.
  * @rq:		The rq to clamp against. Must not be NULL.
@@ -2890,12 +2907,12 @@ unsigned long uclamp_rq_util_with(struct
 		 * Ignore last runnable task's max clamp, as this task will
 		 * reset it. Similarly, no need to read the rq's min clamp.
 		 */
-		if (rq->uclamp_flags & UCLAMP_FLAG_IDLE)
+		if (uclamp_rq_is_idle(rq))
 			goto out;
 	}
 
-	min_util = max_t(unsigned long, min_util, READ_ONCE(rq->uclamp[UCLAMP_MIN].value));
-	max_util = max_t(unsigned long, max_util, READ_ONCE(rq->uclamp[UCLAMP_MAX].value));
+	min_util = max_t(unsigned long, min_util, uclamp_rq_get(rq, UCLAMP_MIN));
+	max_util = max_t(unsigned long, max_util, uclamp_rq_get(rq, UCLAMP_MAX));
 out:
 	/*
 	 * Since CPU's {min,max}_util clamps are MAX aggregated considering
@@ -2941,6 +2958,25 @@ static inline bool uclamp_is_used(void)
 {
 	return false;
 }
+
+static inline unsigned long uclamp_rq_get(struct rq *rq,
+					  enum uclamp_id clamp_id)
+{
+	if (clamp_id == UCLAMP_MIN)
+		return 0;
+
+	return SCHED_CAPACITY_SCALE;
+}
+
+static inline void uclamp_rq_set(struct rq *rq, enum uclamp_id clamp_id,
+				 unsigned int value)
+{
+}
+
+static inline bool uclamp_rq_is_idle(struct rq *rq)
+{
+	return false;
+}
 #endif /* CONFIG_UCLAMP_TASK */
 
 #ifdef arch_scale_freq_capacity



  parent reply	other threads:[~2023-04-24 13:23 UTC|newest]

Thread overview: 82+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-24 13:16 [PATCH 5.15 00/73] 5.15.109-rc1 review Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 01/73] ARM: dts: rockchip: fix a typo error for rk3288 spdif node Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 02/73] arm64: dts: qcom: ipq8074-hk01: enable QMP device, not the PHY node Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 03/73] arm64: dts: meson-g12-common: specify full DMC range Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 04/73] arm64: dts: imx8mm-evk: correct pmic clock source Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 05/73] netfilter: br_netfilter: fix recent physdev match breakage Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 06/73] regulator: fan53555: Explicitly include bits header Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 07/73] regulator: fan53555: Fix wrong TCS_SLEW_MASK Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 08/73] net: sched: sch_qfq: prevent slab-out-of-bounds in qfq_activate_agg Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 09/73] virtio_net: bugfix overflow inside xdp_linearize_page() Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 10/73] sfc: Split STATE_READY in to STATE_NET_DOWN and STATE_NET_UP Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 11/73] sfc: Fix use-after-free due to selftest_work Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 12/73] netfilter: nf_tables: fix ifdef to also consider nf_tables=m Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 13/73] i40e: fix accessing vsi->active_filters without holding lock Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 14/73] i40e: fix i40e_setup_misc_vector() error handling Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 15/73] netfilter: nf_tables: validate catch-all set elements Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 16/73] netfilter: nf_tables: tighten netlink attribute requirements for catch-all elements Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 17/73] bnxt_en: Do not initialize PTP on older P3/P4 chips Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 18/73] mlxfw: fix null-ptr-deref in mlxfw_mfa2_tlv_next() Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 19/73] bonding: Fix memory leak when changing bond type to Ethernet Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 20/73] net: rpl: fix rpl header size calculation Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 21/73] mlxsw: pci: Fix possible crash during initialization Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 22/73] spi: spi-rockchip: Fix missing unwind goto in rockchip_sfc_probe() Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 23/73] bpf: Fix incorrect verifier pruning due to missing register precision taints Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 24/73] e1000e: Disable TSO on i219-LM card to increase speed Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 25/73] f2fs: Fix f2fs_truncate_partial_nodes ftrace event Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 26/73] Input: i8042 - add quirk for Fujitsu Lifebook A574/H Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 27/73] platform/x86 (gigabyte-wmi): Add support for A320M-S2H V2 Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 28/73] selftests: sigaltstack: fix -Wuninitialized Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 29/73] scsi: megaraid_sas: Fix fw_crash_buffer_show() Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 30/73] scsi: core: Improve scsi_vpd_inquiry() checks Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 31/73] net: dsa: b53: mmap: add phy ops Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 32/73] s390/ptrace: fix PTRACE_GET_LAST_BREAK error handling Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 33/73] nvme-tcp: fix a possible UAF when failing to allocate an io queue Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 34/73] xen/netback: use same error messages for same errors Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 35/73] platform/x86: gigabyte-wmi: add support for X570S AORUS ELITE Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 36/73] rtmutex: Add acquire semantics for rtmutex lock acquisition slow path Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 37/73] iio: light: tsl2772: fix reading proximity-diodes from device tree Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 38/73] nilfs2: initialize unused bytes in segment summary blocks Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 39/73] memstick: fix memory leak if card device is never registered Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 40/73] kernel/sys.c: fix and improve control flow in __sys_setres[ug]id() Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 41/73] mmc: sdhci_am654: Set HIGH_SPEED_ENA for SDR12 and SDR25 Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 42/73] drm/i915: Fix fast wake AUX sync len Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 43/73] mm/khugepaged: check again on anon uffd-wp during isolation Greg Kroah-Hartman
2023-04-24 13:16 ` [PATCH 5.15 44/73] mm: page_alloc: skip regions with hugetlbfs pages when allocating 1G pages Greg Kroah-Hartman
2023-04-24 13:16 ` Greg Kroah-Hartman [this message]
2023-04-24 13:17 ` [PATCH 5.15 46/73] sched/uclamp: Make cpu_overutilized() use util_fits_cpu() Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 47/73] sched/uclamp: Cater for uclamp in find_energy_efficient_cpu()s early exit condition Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 48/73] sched/fair: Detect capacity inversion Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 49/73] sched/fair: Consider capacity inversion in util_fits_cpu() Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 50/73] sched/uclamp: Fix a uninitialized variable warnings Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 51/73] sched/fair: Fixes for capacity inversion detection Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 52/73] MIPS: Define RUNTIME_DISCARD_EXIT in LD script Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 53/73] [PATCH v2 stable-5.10.y stable-5.15.y] docs: futex: Fix kernel-doc references after code split-up preparation Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 54/73] purgatory: fix disabling debug info Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 55/73] fuse: fix attr version comparison in fuse_read_update_size() Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 56/73] fuse: always revalidate rename target dentry Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 57/73] fuse: fix deadlock between atomic O_TRUNC and page invalidation Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 58/73] udp: Call inet6_destroy_sock() in setsockopt(IPV6_ADDRFORM) Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 59/73] tcp/udp: Call inet6_destroy_sock() in IPv6 sk->sk_destruct() Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 60/73] inet6: Remove inet6_destroy_sock() in sk->sk_prot->destroy() Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 61/73] dccp: Call inet6_destroy_sock() via sk->sk_destruct() Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 62/73] sctp: " Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 63/73] pwm: meson: Explicitly set .polarity in .get_state() Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 64/73] pwm: iqs620a: " Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 65/73] pwm: hibvt: " Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 66/73] counter: 104-quad-8: Fix race condition between FLAG and CNTR reads Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 67/73] iio: adc: at91-sama5d2_adc: fix an error code in at91_adc_allocate_trigger() Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 68/73] mm/page_alloc: fix potential deadlock on zonelist_update_seq seqlock Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 69/73] ASoC: fsl_asrc_dma: fix potential null-ptr-deref Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 70/73] ASN.1: Fix check for strdup() success Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 71/73] soc: sifive: l2_cache: fix missing iounmap() in error path in sifive_l2_init() Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 72/73] soc: sifive: l2_cache: fix missing free_irq() " Greg Kroah-Hartman
2023-04-24 13:17 ` [PATCH 5.15 73/73] soc: sifive: l2_cache: fix missing of_node_put() " Greg Kroah-Hartman
2023-04-25  1:14 ` [PATCH 5.15 00/73] 5.15.109-rc1 review Guenter Roeck
2023-04-25  2:42 ` Bagas Sanjaya
2023-04-25 13:37 ` Chris Paterson
2023-04-25 13:41 ` Naresh Kamboju
2023-04-25 14:01 ` Harshit Mogalapalli
2023-04-25 20:30 ` Florian Fainelli
2023-04-25 21:03 ` Ron Economos
2023-04-26  0:24 ` Shuah Khan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230424131130.655453142@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=hsiang023167@gmail.com \
    --cc=patches@lists.linux.dev \
    --cc=peterz@infradead.org \
    --cc=qais.yousef@arm.com \
    --cc=qyousef@layalina.io \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox