Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp813776pxv; Thu, 15 Jul 2021 16:58:04 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxoY5cTWNJgh7J088Z4j6ugxHdDPbjWVm62f5Z+9ivsDFoQ5xX/GFM2XnuC5BU6yM8lyYTs X-Received: by 2002:a92:7c10:: with SMTP id x16mr4394496ilc.192.1626393484497; Thu, 15 Jul 2021 16:58:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626393484; cv=none; d=google.com; s=arc-20160816; b=nHZbQJ8itSZYo7td6HxLMWwYOP3VJI2ov1U0o25FReWhXGjdS6DBod++iTD5Kji4rA +LZ4vDyniu554cjH1f+aAfbIN/40DdQs1rcsvJdI2zpVOvy7ESoqiUBWHx7W+Ab758F8 9eZs8T6djUaYd6YmunWu13VMGRoxkWoj4VPLL3eMfUd1BzOik32iZopzkrU4cO03hvxj 2FmESZPgCid4Zem+mNJDujlhH0KStxOaARJYCcLqC/pqjyzWxRyGmYtxWKAOv8ShgP49 z+938fAC5FAuLVKQ2MOHQCcsPlBKQSIv8o3q4cw5GtJQuUJnlS0HFK3ObePWai49qLwG Dx5A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version; bh=37Ab3kpTrPgzmm618oRObyRk2nJWR4HT2Rg5TXVHbr4=; b=tMKPsWICDRIRyrjZeUqv6k72l9v1huzSWiMQJTWIJslTpp2jJrw9owCZiAAPR/do7a qoWLjIWKCOVsaKs95pqB8VxCm1YatU4c2fbuB+cGNnloqR7dgvhVS/NH9MXFItlDZWZe HV76fPRXi1Z+tvjNVjzRK7TQfawmFVM2F3oexTkp2bBPsPSsGEEgK6gT+pIOSEezsSn9 4mhE7CpICBigFddok8Y7IeO7wenQBu+DPv4jozSN/DxYTxaQt5eo5V7D3q/+GFTXh7OW hD51ozyIPJrHizbOl6J4rDBhEeNyZ+LIYD7D12EQbwemiasS+ngqb44FemJR/oE3VOiC 2rkQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id w5si8940470ilh.139.2021.07.15.16.57.45; Thu, 15 Jul 2021 16:58:04 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231131AbhGOX70 (ORCPT + 99 others); Thu, 15 Jul 2021 19:59:26 -0400 Received: from mail-lf1-f43.google.com ([209.85.167.43]:34406 "EHLO mail-lf1-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231724AbhGOX7W (ORCPT ); Thu, 15 Jul 2021 19:59:22 -0400 Received: by mail-lf1-f43.google.com with SMTP id f30so12997134lfj.1; Thu, 15 Jul 2021 16:56:28 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=37Ab3kpTrPgzmm618oRObyRk2nJWR4HT2Rg5TXVHbr4=; b=EOiuZvioNYu4kzK74PBwSm+P3UOFLKi0N/8j3ep8HMbLa2NI+HbpzDXfPpZzdNCaCx vQpqMZ7W53EKdu3kVRbZPyneqVDXMS2W/O8+WpOglVtE3/dTyzVhTR98z3aq0s5sU20n 2fra7ICdyt+vzd1yPH29GuKv/OJgOPhQW4+6txXKDEN06Zi0e/4oSDJi+vNivuRwPnlm ca+95x3klKUbizoro5CYRU2DUby4dQzHhkj9DVqKbi/Mx5w9YaQOL1vIXVrbISIKDn3R D5V2iXXI2tjoKFJ7GwQKBKa+TfAGmk8BhePu+fILezYGkVjiFVM54U9r+9doOe7ivAZ9 PRcA== X-Gm-Message-State: AOAM533H6gHk8jIlYcmsDV9vykGztS/PK3c/dipLsozjjYeKeVWWnz1c S4fEyCH4PfRDzuLx0cct4hC9x4ztkojKLa9mnzw= X-Received: by 2002:a19:8c0f:: with SMTP id o15mr5387368lfd.509.1626393381332; Thu, 15 Jul 2021 16:56:21 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Namhyung Kim Date: Thu, 15 Jul 2021 16:56:10 -0700 Message-ID: Subject: Re: [RFC PATCH 04/10] perf workqueue: add threadpool execute and wait functions To: Riccardo Mancini Cc: Arnaldo Carvalho de Melo , Ian Rogers , Peter Zijlstra , Ingo Molnar , Mark Rutland , Jiri Olsa , linux-kernel , linux-perf-users Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Jul 13, 2021 at 5:11 AM Riccardo Mancini wrote: > > This patch adds: > - execute_in_threadpool: assigns a task to the threads to execute > asynchronously. > - wait_threadpool: waits for the task to complete on all threads. > Furthermore, testing for these new functions is added. > > This patch completes the threadpool. > > Signed-off-by: Riccardo Mancini > --- > tools/perf/tests/workqueue.c | 86 ++++++++++++++++++++- > tools/perf/util/workqueue/threadpool.c | 103 +++++++++++++++++++++++++ > tools/perf/util/workqueue/threadpool.h | 5 ++ > 3 files changed, 193 insertions(+), 1 deletion(-) > > diff --git a/tools/perf/tests/workqueue.c b/tools/perf/tests/workqueue.c > index be377e9897bab4e9..3c64db8203556847 100644 > --- a/tools/perf/tests/workqueue.c > +++ b/tools/perf/tests/workqueue.c > @@ -1,13 +1,59 @@ > // SPDX-License-Identifier: GPL-2.0 > +#include > #include > +#include > #include "tests.h" > #include "util/debug.h" > #include "util/workqueue/threadpool.h" > > +#define DUMMY_FACTOR 100000 > +#define N_DUMMY_WORK_SIZES 7 > + > struct threadpool_test_args_t { > int pool_size; > }; > > +struct test_task { > + struct task_struct task; > + int n_threads; > + int *array; > +}; > + > +/** > + * dummy_work - calculates DUMMY_FACTOR * (idx % N_DUMMY_WORK_SIZES) inefficiently > + * > + * This function uses modulus to create work items of different sizes. > + */ > +static void dummy_work(int idx) > +{ > + int prod = 0; I'm not sure but having 'volatile' would prevent some kind of possible compiler optimizations.. > + int k = idx % N_DUMMY_WORK_SIZES; > + int i, j; > + > + for (i = 0; i < DUMMY_FACTOR; i++) > + for (j = 0; j < k; j++) > + prod ++; > + > + pr_debug3("dummy: %d * %d = %d\n", DUMMY_FACTOR, k, prod); > +} > + > +static void test_task_fn1(int tidx, struct task_struct *task) > +{ > + struct test_task *mtask = container_of(task, struct test_task, task); > + > + dummy_work(tidx); > + mtask->array[tidx] = tidx+1; > +} > + > +static void test_task_fn2(int tidx, struct task_struct *task) > +{ > + struct test_task *mtask = container_of(task, struct test_task, task); > + > + dummy_work(tidx); > + mtask->array[tidx] = tidx*2; > +} > + > + > static int __threadpool__prepare(struct threadpool_struct **pool, int pool_size) > { > int ret; > @@ -38,21 +84,59 @@ static int __threadpool__teardown(struct threadpool_struct *pool) > return 0; > } > > +static int __threadpool__exec_wait(struct threadpool_struct *pool, > + struct task_struct *task) > +{ > + int ret; > + > + ret = execute_in_threadpool(pool, task); > + TEST_ASSERT_VAL("threadpool execute failure", ret == 0); > + TEST_ASSERT_VAL("threadpool is not executing", threadpool_is_busy(pool)); > + > + ret = wait_threadpool(pool); > + TEST_ASSERT_VAL("threadpool wait failure", ret == 0); > + TEST_ASSERT_VAL("waited threadpool is not ready", threadpool_is_ready(pool)); > + > + return 0; > +} > > static int __test__threadpool(void *_args) > { > struct threadpool_test_args_t *args = _args; > struct threadpool_struct *pool; > - int ret; > + int ret, i; > + struct test_task task; > + > + task.task.fn = test_task_fn1; > + task.n_threads = args->pool_size; > + task.array = calloc(args->pool_size, sizeof(*task.array)); Need to check the return value. > > ret = __threadpool__prepare(&pool, args->pool_size); > if (ret) > return ret; > > + ret = __threadpool__exec_wait(pool, &task.task); > + if (ret) > + return ret; > + > + for (i = 0; i < args->pool_size; i++) > + TEST_ASSERT_VAL("failed array check (1)", task.array[i] == i+1); > + > + task.task.fn = test_task_fn2; > + > + ret = __threadpool__exec_wait(pool, &task.task); > + if (ret) > + return ret; > + > + for (i = 0; i < args->pool_size; i++) > + TEST_ASSERT_VAL("failed array check (2)", task.array[i] == 2*i); > + > ret = __threadpool__teardown(pool); > if (ret) > return ret; > > + free(task.array); All previous returns will leak it. Thanks, Namhyung