[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220106004656.126790-12-daniel.m.jordan@oracle.com>
Date: Wed, 5 Jan 2022 19:46:51 -0500
From: Daniel Jordan <daniel.m.jordan@...cle.com>
To: Alexander Duyck <alexanderduyck@...com>,
Alex Williamson <alex.williamson@...hat.com>,
Andrew Morton <akpm@...ux-foundation.org>,
Ben Segall <bsegall@...gle.com>,
Cornelia Huck <cohuck@...hat.com>,
Dan Williams <dan.j.williams@...el.com>,
Dave Hansen <dave.hansen@...ux.intel.com>,
Dietmar Eggemann <dietmar.eggemann@....com>,
Herbert Xu <herbert@...dor.apana.org.au>,
Ingo Molnar <mingo@...hat.com>,
Jason Gunthorpe <jgg@...dia.com>,
Johannes Weiner <hannes@...xchg.org>,
Josh Triplett <josh@...htriplett.org>,
Michal Hocko <mhocko@...e.com>, Nico Pache <npache@...hat.com>,
Pasha Tatashin <pasha.tatashin@...een.com>,
Peter Zijlstra <peterz@...radead.org>,
Steffen Klassert <steffen.klassert@...unet.com>,
Steve Sistare <steven.sistare@...cle.com>,
Tejun Heo <tj@...nel.org>,
Tim Chen <tim.c.chen@...ux.intel.com>,
Vincent Guittot <vincent.guittot@...aro.org>
Cc: linux-mm@...ck.org, kvm@...r.kernel.org,
linux-kernel@...r.kernel.org, linux-crypto@...r.kernel.org,
Daniel Jordan <daniel.m.jordan@...cle.com>
Subject: [RFC 11/16] padata: Cap helpers started to online CPUs
padata can start num_possible_cpus() helpers, but this is too many
considering that every job's main thread participates and there may
be fewer online than possible CPUs.
Limit overall concurrency, including main thread(s), to
num_online_cpus() with the padata_works_inuse counter to prevent
CPU-intensive threads flooding the system in case of concurrent jobs.
Signed-off-by: Daniel Jordan <daniel.m.jordan@...cle.com>
---
kernel/padata.c | 24 ++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/kernel/padata.c b/kernel/padata.c
index 0f4002ed1518..e27988d3e9ed 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -50,6 +50,7 @@ struct padata_work {
static DEFINE_SPINLOCK(padata_works_lock);
static struct padata_work *padata_works;
+static unsigned int padata_works_inuse;
static LIST_HEAD(padata_free_works);
struct padata_mt_job_state {
@@ -98,11 +99,16 @@ static struct padata_work *padata_work_alloc(void)
lockdep_assert_held(&padata_works_lock);
- if (list_empty(&padata_free_works))
- return NULL; /* No more work items allowed to be queued. */
+ /* Are more work items allowed to be queued? */
+ if (padata_works_inuse >= num_online_cpus())
+ return NULL;
+
+ if (WARN_ON_ONCE(list_empty(&padata_free_works)))
+ return NULL;
pw = list_first_entry(&padata_free_works, struct padata_work, pw_list);
list_del(&pw->pw_list);
+ ++padata_works_inuse;
return pw;
}
@@ -111,7 +117,11 @@ static int padata_work_alloc_mt(int nworks, struct list_head *head)
int i;
spin_lock(&padata_works_lock);
- /* Start at 1 because the current task participates in the job. */
+ /*
+ * Increment inuse and start iterating at 1 to account for the main
+ * thread participating in the job with its stack-allocated work.
+ */
+ ++padata_works_inuse;
for (i = 1; i < nworks; ++i) {
struct padata_work *pw = padata_work_alloc();
@@ -128,20 +138,22 @@ static void padata_work_free(struct padata_work *pw)
{
lockdep_assert_held(&padata_works_lock);
list_add(&pw->pw_list, &padata_free_works);
+ WARN_ON_ONCE(!padata_works_inuse);
+ --padata_works_inuse;
}
static void padata_works_free(struct list_head *works)
{
struct padata_work *cur, *next;
- if (list_empty(works))
- return;
-
spin_lock(&padata_works_lock);
list_for_each_entry_safe(cur, next, works, pw_list) {
list_del(&cur->pw_list);
padata_work_free(cur);
}
+ /* To account for the main thread finishing its part of the job. */
+ WARN_ON_ONCE(!padata_works_inuse);
+ --padata_works_inuse;
spin_unlock(&padata_works_lock);
}
--
2.34.1
Powered by blists - more mailing lists