From nobody Sat Feb 7 15:16:14 2026 Received: from out-178.mta1.migadu.com (out-178.mta1.migadu.com [95.215.58.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BD5A532ED2C for ; Wed, 28 Jan 2026 10:51:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769597500; cv=none; b=bxA4WVQqcmEB70KPrzo0ict0Tb0icPKiUxcGBFBv6DuiIb1dX8737XHhJef771p/VJl8P6zg7yCEpC4CffTtjaVewxSUshKhHVsTfJ06pjFYJXI4sA20jPayUNW8CIiUlsvDlbcBDKR6PrDZkBi95j1Pr8Q93b/8lLsWs9Co6Bk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769597500; c=relaxed/simple; bh=qB342u1Fa9iKIjRjBEPInMZcJOV3JU+F1+1AOruqAcQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=KBrAbYVUaE846uDIDXejbxJXyZVsHJ3d87uew82U03iSTzQrWWpzt1Vydi7wfcrnyxZASVCRJOMK2IwY17kUJkHiefuYQzSMwdDGqZEws2f9wbhLPiwA6u599gN5sGS4+9MvQvH12hsyV3ydRuMAqAZjCM8N5LtXPTXMDXfC8N0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=EQyrwGk7; arc=none smtp.client-ip=95.215.58.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="EQyrwGk7" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1769597486; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=eehzFHmt5LTmSet9iPSrcV4IAuJCuW4jScy1n4w7+Bw=; b=EQyrwGk76j+TbzoJbGNrCimYa4uUVGcxLcTV8Y0MyqF1qmhju+7yAapX+NgIyPzXoD2P9j IJ2nECpjEC3I9RHqyx7fDiqY3jfwlmzzHDozJJt4LZYBzy5QjEEZ02Sj1hkTgj2jxGQuH0 hvOkAf9zH3XpvHWHzqR9QhXqPDXIl4M= From: sunliming@linux.dev To: song@kernel.org, yukuai@fnnas.com Cc: linux-raid@vger.kernel.org, linux-kernel@vger.kernel.org, sunliming Subject: [PATCH 2/3] lib/raid6: Optimizing the raid6_select_algo time through asynchronous processing Date: Wed, 28 Jan 2026 18:49:22 +0800 Message-Id: <20260128104923.338443-3-sunliming@linux.dev> In-Reply-To: <20260128104923.338443-1-sunliming@linux.dev> References: <20260128104923.338443-1-sunliming@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: sunliming Optimizing the raid6_select_algo time. In raid6_select_algo(), an raid6 gen algorithm is first selected quickly through synchronous processing, while the time-consuming process of selecting the optimal algorithm via benchmark= ing is handled asynchronously. This approach speeds up the overall startup time and ultimately ensures the selection of an optimal algorithm. Signed-off-by: sunliming --- lib/raid6/algos.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/lib/raid6/algos.c b/lib/raid6/algos.c index ac6a77b0ae1d..c92168d59df2 100644 --- a/lib/raid6/algos.c +++ b/lib/raid6/algos.c @@ -12,6 +12,7 @@ */ =20 #include +#include #ifndef __KERNEL__ #include #include @@ -168,7 +169,7 @@ static inline const struct raid6_calls *raid6_choose_ge= n_fast(void) =20 if (best) { raid6_call =3D *best; - pr_info("raid6: skipped pq benchmark and selected %s\n", + pr_info("raid6: fast selected %s, async benchmark pending\n", best->name); } else { pr_err("raid6: No valid algorithm found even for fast selection!\n"); @@ -177,7 +178,7 @@ static inline const struct raid6_calls *raid6_choose_ge= n_fast(void) return best; } =20 -static inline const struct raid6_calls *raid6_gen_benchmark( +static inline void raid6_gen_benchmark( void *(*const dptrs)[RAID6_TEST_DISKS], const int disks) { unsigned long perf, bestgenperf, j0, j1; @@ -214,12 +215,11 @@ static inline const struct raid6_calls *raid6_gen_ben= chmark( } =20 if (!best) { - pr_err("raid6: Yikes! No algorithm found!\n"); - goto out; + pr_err("raid6: async benchmark failed to find any algorithm\n"); + return; } =20 raid6_call =3D *best; - pr_info("raid6: using algorithm %s gen() %ld MB/s\n", best->name, (bestgenperf * HZ * (disks - 2)) >> @@ -244,14 +244,11 @@ static inline const struct raid6_calls *raid6_gen_ben= chmark( (perf * HZ * (disks - 2)) >> (20 - PAGE_SHIFT + RAID6_TIME_JIFFIES_LG2 + 1)); } - -out: - return best; } =20 /* Try to pick the best algorithm */ /* This code uses the gfmul table as convenient data set to abuse */ -static int raid6_choose_gen_benmark(const struct raid6_calls **gen_best) +static int raid6_choose_gen_benmark(void) { const int disks =3D RAID6_TEST_DISKS; char *disk_ptr, *p; @@ -278,32 +275,39 @@ static int raid6_choose_gen_benmark(const struct raid= 6_calls **gen_best) if ((disks - 2) * PAGE_SIZE % 65536) memcpy(p, raid6_gfmul, (disks - 2) * PAGE_SIZE % 65536); =20 - *gen_best =3D raid6_gen_benchmark(&dptrs, disks); + raid6_gen_benchmark(&dptrs, disks); =20 free_pages((unsigned long)disk_ptr, RAID6_TEST_DISKS_ORDER); =20 return 0; } =20 +static struct work_struct raid6_benchmark_work __initdata; + +static __init void benchmark_work_func(struct work_struct *work) +{ + raid6_choose_gen_benmark(); +} + int __init raid6_select_algo(void) { - int ret; const struct raid6_calls *gen_best =3D NULL; const struct raid6_recov_calls *rec_best =3D NULL; =20 - /* select raid gen_syndrome functions */ - if (!IS_ENABLED(CONFIG_RAID6_PQ_BENCHMARK)) - gen_best =3D raid6_choose_gen_fast(); - else { - ret =3D raid6_choose_gen_benmark(&gen_best); - if (ret < 0) - return ret; - } + /* phase 1: synchronous fast selection generation algorithm */ + gen_best =3D raid6_choose_gen_fast(); =20 /* select raid recover functions */ rec_best =3D raid6_choose_recov(); =20 - return gen_best && rec_best ? 0 : -EINVAL; + if (!gen_best || !rec_best) + return -EINVAL; + + /* phase 2: asynchronous performance benchmarking */ + INIT_WORK(&raid6_benchmark_work, benchmark_work_func); + schedule_work(&raid6_benchmark_work); + + return 0; } =20 static void raid6_exit(void) --=20 2.25.1