From nobody Fri Jun 12 15:46:55 2026 Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3E685389453 for ; Wed, 13 May 2026 22:17:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778710650; cv=none; b=tbboxip1Ed35GA+jmqsDH31U55RtafGKD6Q4hAcjjvVjiW4DYuqhthLa/3W1gTtRewhaL3Oe7nS4K9f+mms52kmUti12Mjqq7PFySxvRnVNpCQI/FQZrzIzE8qHkOqctN8eBNH3xov/PwDj+9Zjd+MpodV4ELpvrIPJsVbfskA4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778710650; c=relaxed/simple; bh=1CnwvZTogWqZAhy/VkQH/NFsLSpDk11lwLmlhfnuhRY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qN194mceZLS/Z6B7v4op8KjovuSctsE5pxUWVbhhcU4ewGUG3FcDWP3NtUbcLsVCSmo18nnsn6CAsuXz2PiXLaTVgfT7doqntKDP//trM0S+wLIJwBAwGJsPJUkpWuP2gTcDM8Gwkws17irV3UxrudBmoceqG6NUJBBFlLcBO1c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=hackers.camp; spf=pass smtp.mailfrom=gmail.com; arc=none smtp.client-ip=209.85.128.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=hackers.camp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-48e7b0208ebso1726655e9.3 for ; Wed, 13 May 2026 15:17:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778710648; x=1779315448; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=xr0kdEEJCMxvOXZIAvbWuOWKwyYcIL/GxzX7Rgi9GeM=; b=Q7z5csd0Iw3QEu3vzvImbc0LjqoIaH2dYVxwom/EUIjXur/7AkOUeX578U2d5OaTJH IjBMiJxaXqLqN0iGZIXZ1sYfWuR1NChDjOT+X3ltf5Q3OEBwBzjg9iVOuqP5Xd8GzCEy G4ZXwngVZyPCtX5Qetm8hqMYWK+n3d4DuRrQEu2tpglh6g7DN4W8bF94iv5QmyZxFcw6 hO8dWkvBS8Rwb5i7UC1ce2UQKIm4i63xaB99a3rdPWj89xgAJeMbcRuJeNSmsEJg7Pb2 s7sYVR5EqN+8vxGOu6yIjNB4l55MxWRKxKe7Dd1MY3w0dTScz2nwwpA0XVM6cUwGWt68 4VfQ== X-Gm-Message-State: AOJu0YwrJCTuLU+e7IWdwIVJSaRh6bwL/Fe3pYXyXnzHYSh7xK+yQQmD KKfOSJ66wu4f3+949JUoVzFIvnmqwCd99hIu+OhYqpDSXSxJJrXL/azQ88sZyuj0wfA= X-Gm-Gg: Acq92OH6L0rKrXjFoFR+iFLlfgb5xv9P9DjP1A9KSySYvOjXtU8/UO0X7KSkv15ncVk IYFeVkMCLbukw14Z3+ti4jTk/LSzY/ck8LBjLtbcXdiskayo8knx90VXdpEtpQ/imLhYgj123sL jjWChRacNVF+aZP2xjvdTTQtJBf0O2dZL0gKPe82TmZce/J7+GOHWS2m83v6Cp2WvtGydK537xa dyiLs2kBgZHEZjmXr9agSkGSefYr7rcWj7O77tA9zmHpgLUBgDeMSLligAeWEP6aXxAjkkyGwHG Yj5YhAN69cDDBYyyPjPjOw61aqlMwUl93mVukU5bJ0zO5SU3EIHjHAKM7ICLUTEsUNHgOv4Fv8k WrqLlE8CL9etpXoTrb/cJezvKOg2v98mCmDX8zWaq087zAP1eKsenMtEjGdspCMIHyFLpbnogxJ qLKCT0QhUcPkWpAxDfBuh3CUpQbYb2USyGeErkE7rh5eoKh04xlO0Fp4LfvZ1ez3CoDE4SN6wWp g== X-Received: by 2002:a05:600c:6305:b0:48a:5546:619e with SMTP id 5b1f17b1804b1-48fc9a2eb9amr42590795e9.4.1778710647344; Wed, 13 May 2026 15:17:27 -0700 (PDT) Received: from spartian.home ([2a01:cb1c:868:fa00:915c:e3c1:676e:553e]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48fdb26a7aasm3878445e9.3.2026.05.13.15.17.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 May 2026 15:17:26 -0700 (PDT) From: Aurelien DESBRIERES To: tglx@kernel.org Cc: linux-kernel@vger.kernel.org Subject: [PATCH 1/1] lib/reed_solomon: document rs_control concurrency contract Date: Thu, 14 May 2026 00:17:24 +0200 Message-ID: <10d4000e212db297ee7b7658bb7125cc8ca56997.1778710307.git.aurelien@hackers.camp> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: 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 Content-Type: text/plain; charset="utf-8" struct rs_control carries internal scratch buffers (lambda, syn, b, t, omega, root, reg, loc) in its flexible @buffers array. The scratch is used by decode_rs.c and encode_rs.c during each call, so two concurrent callers operating on the same rs_control corrupt each other's intermediate state and may report spurious uncorrectable errors on otherwise valid codewords. This is consistent with the original Phil Karn KA9Q implementation from 2002 that the library is derived from. No existing in-tree user appears to decode concurrently against a shared rs_control, which is why the contract has stayed implicit. A recent out-of-tree user (a Reed-Solomon protected filesystem) hit the issue under parallel read load: 8 parallel sha256sum runs across a read-only mount produced 150-240 wrong hashes per run and ~160 RS uncorrectable entries per batch, while sequential reads of the same image returned correct bytes byte-for-byte across hundreds of iterations. Allocating one rs_control per CPU (alloc_percpu + for_each_possible_cpu init_rs, with get_cpu_ptr / put_cpu_ptr around encode_rs8 / decode_rs8) eliminated the failures and yielded better wallclock than sequential thanks to real parallelism. Extend the kdoc of struct rs_control to state explicitly that an instance is not safe to share across concurrent encode_rs*() / decode_rs*() calls, and that callers needing concurrent codec use must allocate one rs_control per concurrent caller. Document the bounded extra cost so the trade-off is obvious. No code change, no ABI change. Purely makes the existing contract discoverable without reading decode_rs.c to notice the rsc->buffers indexing. Signed-off-by: Aurelien DESBRIERES --- include/linux/rslib.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/linux/rslib.h b/include/linux/rslib.h index a2848f6907e3..94cfee6d7bdc 100644 --- a/include/linux/rslib.h +++ b/include/linux/rslib.h @@ -50,6 +50,20 @@ struct rs_codec { * struct rs_control - rs control structure per instance * @codec: The codec used for this instance * @buffers: Internal scratch buffers used in calls to decode_rs() + * + * Locking and concurrency: a single struct rs_control instance is NOT + * safe to share across concurrent calls to encode_rs*() or decode_rs*(). + * The codec routines use @buffers as scratch space during encoding and + * decoding (see lib/reed_solomon/decode_rs.c and encode_rs.c), so two + * threads operating on the same rs_control will corrupt each other's + * intermediate state and may report spurious uncorrectable errors on + * otherwise valid codewords. Callers that need concurrent encode/decode + * must allocate one rs_control per concurrent caller (for example one + * per CPU, or one per worker thread). The underlying rs_codec returned + * by codec_init() is reference-counted and reused across rs_control + * instances allocated with matching parameters, so the additional cost + * is bounded to sizeof(struct rs_control) + nroots*8*sizeof(uint16_t) + * per extra instance. */ struct rs_control { struct rs_codec *codec; --=20 2.53.0