Received: by 2002:a05:7412:31a9:b0:e2:908c:2ebd with SMTP id et41csp2905912rdb; Tue, 12 Sep 2023 16:30:17 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHuZeBchg2Pqts306mGZ228i7ty/22AhdpmMIUcq44SxTQ8NOfb0oKKE02qJYXDuTQyFfkO X-Received: by 2002:a05:6871:70a:b0:1d5:53c0:c1fe with SMTP id f10-20020a056871070a00b001d553c0c1femr1178357oap.3.1694561417594; Tue, 12 Sep 2023 16:30:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1694561417; cv=none; d=google.com; s=arc-20160816; b=sQjFJf2Qbs28g1RllgGcN9i2m8QUH5sTfgnK4BfqB7YmqoLrwIc9I4H7WNT7vT3yKj AETGGvBGJtP+in0l0l9Sa5xoPVb8j5j2wx1VmSfxWU6XkuC7h5CmPP/O1t1tcANBUjw1 O61siqCoYJMgjzhQSSia8PUSojwZU3Ge56zvRbNzizxGAU7sFWFCmgKLxdZFy2eesB6R o9vxy4IdgxuBu7DepfB47pTl6chNfUS5HXZs7w60Of7yNhnGVVVbzNBCvy5xRb9cVpnQ kGjcTCbtOgdnbuBg5KqfC2e1bc6d30q6sEY6U5T2z81zE5FAU08I6dhHzz/QXAvtfLLQ Gw3w== 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 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Return-Path: Received: from snail.vger.email (snail.vger.email. [2620:137:e000::3:7]) by mx.google.com with ESMTPS id d20-20020a656214000000b0057403c26ea0si8442606pgv.391.2023.09.12.16.30.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Sep 2023 16:30:17 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) client-ip=2620:137:e000::3:7; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 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 46DBE8311BCA; Mon, 11 Sep 2023 23:13:23 -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 S229703AbjILGNU (ORCPT + 99 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 Content-Transfer-Encoding: 7BIT Content-Type: text/plain; charset=US-ASCII 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:23 -0700 (PDT) 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 --- 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 = { -- 2.34.1