From patchwork Tue Sep 12 06:10:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liao Chang X-Patchwork-Id: 138481 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:9ecd:0:b0:3f2:4152:657d with SMTP id t13csp742198vqx; Tue, 12 Sep 2023 16:30:27 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHen6GMV9amRhGxIgG5mNJbxYlDanGcsBrN+T4BIqqHMnvgYkkbHil9KkLmzGV4IF663DP7 X-Received: by 2002:a05:6870:8290:b0:1ba:2a58:b15e with SMTP id q16-20020a056870829000b001ba2a58b15emr1080831oae.2.1694561426971; Tue, 12 Sep 2023 16:30:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1694561426; cv=none; d=google.com; s=arc-20160816; b=Cs4OOlG2BwXhXpoZO/Fu+aswIVvwPbbhU7VRwisnrrUmYVr3l2vX0aqlhxz8RYFucJ hjvtJg2tM+nhEtzBvAz7QG0uiyk9Ch2p45/wGY1bM7AYhZvXbHGtkq+xIn71qW6PU9to pX557L+86D8pIzl/BDnhLLiL0dBQ6uOvf8AAex5MYzWvOr7yMBWuI16wiCCofBw7WjWO 5LJbNaJ7NAJ6bKztZFOAz1vJ+ByHORFzk2yK3LeoFNi8z45yTK4a7sZ8IvmlYk4vKv63 uDcUXn/HL8kNuNdj34mooV/nwsARRW4Co/l6FXk5AVbThUXWUGqR7v4oBU/AK3nYBUE+ 0Vhg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=nVcWHsHdFfnC1o5myI4DYAv+ZtuCdut82A2GVn2W42A=; fh=0vaYOzzn3Z5SQEjgoqvxffIotvjIeDSv5QGTvx6cK/U=; b=pChB1hBiT0Vm7l1nXl38G3hcBt0o1Sn6MLHv1PpZ7ZWt7JTuT9+fVqUqr/5dPMufz2 LFv3Yt9h85YHVO7lgCUneIUtIawgYB/oDSuo0WMBq1z4GeSMpsyKBlkwKulsoBlJF98f 7LTL9lwByhNwcdTSPndcy/YLsxN3pOZD4EO2N+MLD1KsVA6pq/6xVzbEgUrpz95MaHoJ AJtIMob75/KEEXnP2X8KK5cAmebzjb9n/ahQWpOh2Co/qTzJVLkqSSwt1dVSBy/2Ax2J HrBbedV1UV1uHKu+sc4oC+hxkIYFHAS4FL8o4reAyG0aygrnw757kVAKDL73hw6iaEAN 2UHg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Received: from snail.vger.email (snail.vger.email. [23.128.96.37]) by mx.google.com with ESMTPS id 19-20020a631753000000b00573f93787e4si8464078pgx.103.2023.09.12.16.30.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Sep 2023 16:30:26 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) client-ip=23.128.96.37; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 16BCA83185D2; Mon, 11 Sep 2023 23:13:26 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.8 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229704AbjILGNU (ORCPT + 39 others); Tue, 12 Sep 2023 02:13:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43718 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229567AbjILGNU (ORCPT ); Tue, 12 Sep 2023 02:13:20 -0400 Received: from szxga03-in.huawei.com (szxga03-in.huawei.com [45.249.212.189]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 049B7AF; Mon, 11 Sep 2023 23:13:16 -0700 (PDT) Received: from kwepemd200002.china.huawei.com (unknown [172.30.72.53]) by szxga03-in.huawei.com (SkyGuard) with ESMTP id 4RlCpz5k45zMlHw; Tue, 12 Sep 2023 14:09:47 +0800 (CST) Received: from huawei.com (10.67.174.28) by kwepemd200002.china.huawei.com (7.221.188.186) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.1258.23; Tue, 12 Sep 2023 14:13:13 +0800 From: Liao Chang To: , CC: , Subject: [PATCH 1/2] cpufreq: userspace: Use fine-grained mutex in userspace governor Date: Tue, 12 Sep 2023 06:10:56 +0000 Message-ID: <20230912061057.2516963-1-liaochang1@huawei.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-Originating-IP: [10.67.174.28] X-ClientProxiedBy: dggems702-chm.china.huawei.com (10.3.19.179) To kwepemd200002.china.huawei.com (7.221.188.186) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Mon, 11 Sep 2023 23:13:26 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1776876442432280246 X-GMAIL-MSGID: 1776876442432280246 The userspace governor currently uses a big global mutex to avoid the race condition on the governor_data field of cpufreq_policy structure. This leads to a low concurrency if multiple userspace applications are trying to set the speed of different policies at the same time. This patch introduces a per-policy mutex to allow the updating of different policies to be performed concurrently, improving overall concurrency. Signed-off-by: Liao Chang Acked-by: Viresh Kumar --- drivers/cpufreq/cpufreq_userspace.c | 69 +++++++++++++++++------------ 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c index 50a4d7846580..442e31060d62 100644 --- a/drivers/cpufreq/cpufreq_userspace.c +++ b/drivers/cpufreq/cpufreq_userspace.c @@ -16,7 +16,11 @@ #include static DEFINE_PER_CPU(unsigned int, cpu_is_managed); -static DEFINE_MUTEX(userspace_mutex); + +struct userspace_policy { + unsigned int setspeed; + struct mutex mutex; +}; /** * cpufreq_set - set the CPU frequency @@ -28,19 +32,19 @@ static DEFINE_MUTEX(userspace_mutex); static int cpufreq_set(struct cpufreq_policy *policy, unsigned int freq) { int ret = -EINVAL; - unsigned int *setspeed = policy->governor_data; + struct userspace_policy *userspace = policy->governor_data; pr_debug("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq); - mutex_lock(&userspace_mutex); + mutex_lock(&userspace->mutex); if (!per_cpu(cpu_is_managed, policy->cpu)) goto err; - *setspeed = freq; + userspace->setspeed = freq; ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L); err: - mutex_unlock(&userspace_mutex); + mutex_unlock(&userspace->mutex); return ret; } @@ -51,67 +55,74 @@ static ssize_t show_speed(struct cpufreq_policy *policy, char *buf) static int cpufreq_userspace_policy_init(struct cpufreq_policy *policy) { - unsigned int *setspeed; + struct userspace_policy *userspace; - setspeed = kzalloc(sizeof(*setspeed), GFP_KERNEL); - if (!setspeed) + userspace = kzalloc(sizeof(*userspace), GFP_KERNEL); + if (!userspace) return -ENOMEM; - policy->governor_data = setspeed; + mutex_init(&userspace->mutex); + + policy->governor_data = userspace; return 0; } +/* + * Any routine that writes to the policy struct will hold the "rwsem" of + * policy struct that means it is free to free "governor_data" here. + */ static void cpufreq_userspace_policy_exit(struct cpufreq_policy *policy) { - mutex_lock(&userspace_mutex); kfree(policy->governor_data); policy->governor_data = NULL; - mutex_unlock(&userspace_mutex); } static int cpufreq_userspace_policy_start(struct cpufreq_policy *policy) { - unsigned int *setspeed = policy->governor_data; + struct userspace_policy *userspace = policy->governor_data; BUG_ON(!policy->cur); pr_debug("started managing cpu %u\n", policy->cpu); - mutex_lock(&userspace_mutex); + mutex_lock(&userspace->mutex); per_cpu(cpu_is_managed, policy->cpu) = 1; - *setspeed = policy->cur; - mutex_unlock(&userspace_mutex); + userspace->setspeed = policy->cur; + mutex_unlock(&userspace->mutex); return 0; } static void cpufreq_userspace_policy_stop(struct cpufreq_policy *policy) { - unsigned int *setspeed = policy->governor_data; + struct userspace_policy *userspace = policy->governor_data; pr_debug("managing cpu %u stopped\n", policy->cpu); - mutex_lock(&userspace_mutex); + mutex_lock(&userspace->mutex); per_cpu(cpu_is_managed, policy->cpu) = 0; - *setspeed = 0; - mutex_unlock(&userspace_mutex); + userspace->setspeed = 0; + mutex_unlock(&userspace->mutex); } static void cpufreq_userspace_policy_limits(struct cpufreq_policy *policy) { - unsigned int *setspeed = policy->governor_data; + struct userspace_policy *userspace = policy->governor_data; - mutex_lock(&userspace_mutex); + mutex_lock(&userspace->mutex); pr_debug("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n", - policy->cpu, policy->min, policy->max, policy->cur, *setspeed); - - if (policy->max < *setspeed) - __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H); - else if (policy->min > *setspeed) - __cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L); + policy->cpu, policy->min, policy->max, policy->cur, userspace->setspeed); + + if (policy->max < userspace->setspeed) + __cpufreq_driver_target(policy, policy->max, + CPUFREQ_RELATION_H); + else if (policy->min > userspace->setspeed) + __cpufreq_driver_target(policy, policy->min, + CPUFREQ_RELATION_L); else - __cpufreq_driver_target(policy, *setspeed, CPUFREQ_RELATION_L); + __cpufreq_driver_target(policy, userspace->setspeed, + CPUFREQ_RELATION_L); - mutex_unlock(&userspace_mutex); + mutex_unlock(&userspace->mutex); } static struct cpufreq_governor cpufreq_gov_userspace = {