From nobody Sun Feb 8 16:12:01 2026 Received: from mail-wm1-f46.google.com (mail-wm1-f46.google.com [209.85.128.46]) (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 5E8E128FFFB for ; Thu, 13 Nov 2025 16:42:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763052152; cv=none; b=SRFDaH8z1xVyFYlUiZaheBTkVUnw9KlL1Ye9qSA6n/OagD+OBe5FMCzWKJZrROhV9QGuldTK/IJIZcrW2niPjTIQFfuqaqAkszGscpp0SMQZBpI+KG2Qms+1O8N+AKAnQVe9r9mDgjO6M9Kmq8/EJ+SAYXKFuGwrur66kEvXNdU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763052152; c=relaxed/simple; bh=4o/RxC43YnVQqRXczuDbSl9ni1pMUIIJIyrl4BDWu78=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mYnZ4Wpq4hBg+rO7pTjrMXRj6xUI9EvsQ+iPL6QBf9HwztPfkrGTvFrhCKnK63WW+84Z12X/R8fYl/gL9smiqtSNFYljpayCrj2QQzdnOxBE6yWJ0mhSZx6hPP6LVrXDTV/26IS4uP5/9jjfVjDs3dpPDnKVLoBfys2lejMYoaw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=JRiCSTLs; arc=none smtp.client-ip=209.85.128.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="JRiCSTLs" Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-477782a42a8so577965e9.0 for ; Thu, 13 Nov 2025 08:42:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1763052149; x=1763656949; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=aMzRJ5pI2+TptVcafty876sJe4B1nGFvJf6ldhJSevs=; b=JRiCSTLsLq28r+pB2vnZiToDICfanVm+vpzw2y9VtDTkw0a1x2ouIiF1U3YPwLl8bc RcttOI5hl5JJwYKhs9KPrRb2nLYzULRgwnSm0w7SwD7JXwiJSsIolEVhuHZVdJliqRgG 2sxYsxejpCA8gvrp1X3rDgwLKxrCeaz6xxH7yIUXaJU53yYNX3QoUmrV6f9QNITGqRXb PZIg8r+T4DckyiV0wtKauMdEhxwo3QscSS0WzYfSJl6TCwtPek6+cw+kCwB/z0h9sCr9 7hovGPRVty4ic9mnQJjP3v/0o0FY7mcAL4KEsSz/xFUDzFVcDaFvm3qYdLrYpESdfcNP NNdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763052149; x=1763656949; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=aMzRJ5pI2+TptVcafty876sJe4B1nGFvJf6ldhJSevs=; b=Jevfjr8nRQE7eBuuddQNbckykG9cVvzqMGPQ28nMe/7Zs+ZMLbrHw5UFIJxZWxQt2h NK1vp2idkfEVkIG409Zt2RsyuEuOSBKjKnk3vQM4RstPMGX5PaF/NY6nGIlvmtYS1T58 uc2Zsxb8Un2eOiNphawL1NBoyf4HcSesLTxM4pPRUW+KPNCy7NSLKOhOnbnuB0HNspwV fmK9PKKpsgEfIkfcvS8xvH7HZEf1EgkfVw2H7NPn3O1+RjATgfufMAxr4QFvdjk+3sY0 U9riWEWk6av5uNlxADt7DT/cGIcswYJt60WvcqMYJnRH2zmjcv5udw8msRyzx+idDmrm 1pQQ== X-Forwarded-Encrypted: i=1; AJvYcCU4ei4eebK90HsYdsyXd9wNLuCquekYBxlBeRLGsPg5olUhtj/gu+eVn7MaLVqESn/C1o4blP0xWxWajp4=@vger.kernel.org X-Gm-Message-State: AOJu0Yyv5TCfqWcsxQlG2e4jCSnekexLT43xUfE6PCilFi/yE9NyI/I0 Nr62x/+r0FFPBLULgV+xA7+PVDdZlnUxfS91Nu7BAuP4lNGmBXb3Qgx8 X-Gm-Gg: ASbGncvqLSbn1MM2TznUj8w/0o2yTcDuzMMpEESw8OTkoreXAfPqnVqfo+yTCu6g/eE rW+GZTsp6mnfyjeQOU/oUXJc60yDRaf3fkB3ZHeJ02nxX5wZz/b1HEconGqWjYEQ66q1A7HTNyO jlCDPL1Btar3i0ZtiIg3lOFd92fKrR/gyn1oMSyhpCDWm8zQEcQBsg5va3D/7a79n4qr1XtYvGu XlHWPvg+GAYMaJ/AvlFpEL1MmP108E60m5nhJdsKuLofxt6HKjSND1bktG3KleQ/CdkqNuxnH5t ccSS3nRYpRpwa3m4PdOUHw5RiVG+QC3cfLYE+DfRSKktpiXi3awBNAGtGwHVDI1enndbxL5J5w8 zAnfZyjr6r14AsCTgtKo7qDpgkDK2cKZGWzy0Eufw1R/MA5oGOsnpQFvopAzLXB/2U0uPV7MgX7 3U4o2zg8XL4vAqWLQ= X-Google-Smtp-Source: AGHT+IGRCKn1s1l7XPuZ3WmfDrwdmb84hd7wM1N88NvGU0e/XOAv+o6GyT+T3hJdUvhK0yT5AjMEAg== X-Received: by 2002:a05:600c:1f8e:b0:46e:36f9:c57e with SMTP id 5b1f17b1804b1-4778fea51f1mr825465e9.5.1763052148336; Thu, 13 Nov 2025 08:42:28 -0800 (PST) Received: from localhost ([2a03:2880:31ff:53::]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-42b53e7ae88sm4824499f8f.6.2025.11.13.08.42.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Nov 2025 08:42:27 -0800 (PST) From: Gustavo Luiz Duarte Date: Thu, 13 Nov 2025 08:42:18 -0800 Subject: [PATCH net-next v2 1/4] netconsole: Simplify send_fragmented_body() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251113-netconsole_dynamic_extradata-v2-1-18cf7fed1026@meta.com> References: <20251113-netconsole_dynamic_extradata-v2-0-18cf7fed1026@meta.com> In-Reply-To: <20251113-netconsole_dynamic_extradata-v2-0-18cf7fed1026@meta.com> To: Breno Leitao , Andre Carvalho , Simon Horman , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Shuah Khan Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Gustavo Luiz Duarte X-Mailer: b4 0.13.0 Refactor send_fragmented_body() to use separate offset tracking for msgbody, and extradata instead of complex conditional logic. The previous implementation used boolean flags and calculated offsets which made the code harder to follow. The new implementation maintains independent offset counters (msgbody_offset, extradata_offset) and processes each section sequentially, making the data flow more straightforward and the code easier to maintain. This is a preparatory refactoring with no functional changes, which will allow easily splitting extradata_complete into separate userdata and sysdata buffers in the next patch. Signed-off-by: Gustavo Luiz Duarte Reviewed-by: Breno Leitao --- drivers/net/netconsole.c | 111 ++++++++++++++++++++-----------------------= ---- 1 file changed, 46 insertions(+), 65 deletions(-) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index bb6e03a92956..5fe5896d6ff5 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -1560,89 +1560,70 @@ static void append_release(char *buf) } =20 static void send_fragmented_body(struct netconsole_target *nt, - const char *msgbody, int header_len, + const char *msgbody_ptr, int header_len, int msgbody_len, int extradata_len) { - int sent_extradata, preceding_bytes; - const char *extradata =3D NULL; - int body_len, offset =3D 0; + const char *extradata_ptr =3D NULL; + int data_len, data_sent =3D 0; + int extradata_offset =3D 0; + int msgbody_offset =3D 0; =20 #ifdef CONFIG_NETCONSOLE_DYNAMIC - extradata =3D nt->extradata_complete; + extradata_ptr =3D nt->extradata_complete; #endif + if (WARN_ON_ONCE(!extradata_ptr && extradata_len !=3D 0)) + return; =20 - /* body_len represents the number of bytes that will be sent. This is + /* data_len represents the number of bytes that will be sent. This is * bigger than MAX_PRINT_CHUNK, thus, it will be split in multiple * packets */ - body_len =3D msgbody_len + extradata_len; + data_len =3D msgbody_len + extradata_len; =20 /* In each iteration of the while loop below, we send a packet - * containing the header and a portion of the body. The body is + * containing the header and a portion of the data. The data is * composed of two parts: msgbody and extradata. We keep track of how - * many bytes have been sent so far using the offset variable, which - * ranges from 0 to the total length of the body. + * many bytes have been sent so far using the data_sent variable, which + * ranges from 0 to the total bytes to be sent. */ - while (offset < body_len) { - int this_header =3D header_len; - bool msgbody_written =3D false; - int this_offset =3D 0; + while (data_sent < data_len) { + int extradata_left =3D extradata_len - extradata_offset; + int msgbody_left =3D msgbody_len - msgbody_offset; + int buf_offset =3D 0; int this_chunk =3D 0; =20 - this_header +=3D scnprintf(nt->buf + this_header, - MAX_PRINT_CHUNK - this_header, - ",ncfrag=3D%d/%d;", offset, - body_len); - - /* Not all msgbody data has been written yet */ - if (offset < msgbody_len) { - this_chunk =3D min(msgbody_len - offset, - MAX_PRINT_CHUNK - this_header); - if (WARN_ON_ONCE(this_chunk <=3D 0)) - return; - memcpy(nt->buf + this_header, msgbody + offset, - this_chunk); - this_offset +=3D this_chunk; + /* header is already populated in nt->buf, just append to it */ + buf_offset =3D header_len; + + buf_offset +=3D scnprintf(nt->buf + buf_offset, + MAX_PRINT_CHUNK - buf_offset, + ",ncfrag=3D%d/%d;", data_sent, + data_len); + + /* append msgbody first */ + this_chunk =3D min(msgbody_left, MAX_PRINT_CHUNK - buf_offset); + memcpy(nt->buf + buf_offset, msgbody_ptr + msgbody_offset, + this_chunk); + msgbody_offset +=3D this_chunk; + buf_offset +=3D this_chunk; + data_sent +=3D this_chunk; + + /* after msgbody, append extradata */ + if (extradata_ptr && extradata_left) { + this_chunk =3D min(extradata_left, + MAX_PRINT_CHUNK - buf_offset); + memcpy(nt->buf + buf_offset, + extradata_ptr + extradata_offset, this_chunk); + extradata_offset +=3D this_chunk; + buf_offset +=3D this_chunk; + data_sent +=3D this_chunk; } =20 - /* msgbody was finally written, either in the previous - * messages and/or in the current buf. Time to write - * the extradata. - */ - msgbody_written |=3D offset + this_offset >=3D msgbody_len; - - /* Msg body is fully written and there is pending extradata to - * write, append extradata in this chunk - */ - if (msgbody_written && offset + this_offset < body_len) { - /* Track how much user data was already sent. First - * time here, sent_userdata is zero - */ - sent_extradata =3D (offset + this_offset) - msgbody_len; - /* offset of bytes used in current buf */ - preceding_bytes =3D this_chunk + this_header; - - if (WARN_ON_ONCE(sent_extradata < 0)) - return; - - this_chunk =3D min(extradata_len - sent_extradata, - MAX_PRINT_CHUNK - preceding_bytes); - if (WARN_ON_ONCE(this_chunk < 0)) - /* this_chunk could be zero if all the previous - * message used all the buffer. This is not a - * problem, extradata will be sent in the next - * iteration - */ - return; - - memcpy(nt->buf + this_header + this_offset, - extradata + sent_extradata, - this_chunk); - this_offset +=3D this_chunk; - } + /* if all is good, send the packet out */ + if (WARN_ON_ONCE(data_sent > data_len)) + return; =20 - send_udp(nt, nt->buf, this_header + this_offset); - offset +=3D this_offset; + send_udp(nt, nt->buf, buf_offset); } } =20 --=20 2.47.3 From nobody Sun Feb 8 16:12:01 2026 Received: from mail-wr1-f44.google.com (mail-wr1-f44.google.com [209.85.221.44]) (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 E8A713587D7 for ; Thu, 13 Nov 2025 16:42:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763052154; cv=none; b=ZKTzqKl+pOjKFHvYMAAOaZN/H/6pFYb7vxxD2StbIdi5w7Z3fORgbXJ0S/vYXtTBDbhLgyoQsNpGG5Al+ZJqVC+oTPF9EVnUUG+vYRa0jLSp818ZEj/VRYzzRL8OXaVzMORw94GZuSdieZf4Xg18i/lYQ3WTKyevxs8ysCp8rzs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763052154; c=relaxed/simple; bh=XnSl+e7Mv0ReQ70IMR8QE8vWBucnxfNkshrw+tadZ5A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=XFKrKxmd5dXx81BMStOzhYj77KB2yEzEkrCyIQ7AWiZXdFbtB75Y2L6pQBxBtpHzayauMhtZsTlfSY0VzuIpgbwJXq436qPv3bNFZJGckBCKkqMMFdHBH54Ao5hEF+DdLLo1tjgkXe23z9DZzaSKV7EB8e3BbUOgbvQcvJlYPkA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=MOVZCASF; arc=none smtp.client-ip=209.85.221.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="MOVZCASF" Received: by mail-wr1-f44.google.com with SMTP id ffacd0b85a97d-429c8d1be2eso108553f8f.0 for ; Thu, 13 Nov 2025 08:42:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1763052150; x=1763656950; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=5xz0y3KJ6p5IbueJDXB+2l4hCwWH/Yg3kMmdcZegJCU=; b=MOVZCASFrywk+g3DYPysbcOUXBZk79hhoPXhdKc1oywlfiHhBTvOBLlvAVdfE2iLcB n4/2ztT4DAJx6ciUI6Guj2ezpO3UqbE2IA29VbpOl5nnHJDwyayeAeqizA2aRGvI5H2t Gg+lb+buSPJwYQRTeIthxnC9b0Tv+4MqQTFz6pQvPxRW5Fmrq2yiBfTHAQmtT2zJtBNF RytorvBPMGxwYQNTcdLM22FXPK9Ygg3dQYx94HMndM/gt20EIcxB2SAo8OjodBRac1LO HFH5n/CSoFp/AlSQyle1gIc1OYu1aQLPu7sv9DoTz3NAnXWroIVmOIlfIpfLJXelI3Z2 h2kg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763052150; x=1763656950; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=5xz0y3KJ6p5IbueJDXB+2l4hCwWH/Yg3kMmdcZegJCU=; b=WwcBrxTip0ZhbavPMYZcugF3A7p09tbBCAhBOCt7iMPRFy8SqL47c3HW8enkll5ztN sjT8fJ/xxNePpaSQHVtbecqQjm41fHtZcKFIP37f2EDiy2wromt83G5nge4OUQxnyuYd OF611z0UWXeKwQ7GUEWBs8Qg5o7fMg1KFh2V60VAyCeABb/Hefj4cWmmZ6QZl5JYBI3M 9cnXbN1dDeSTnxDOUX69DNITJ4rvzsoh1CUzi1g9mLqhHU8tgrFrqxZ/dP6avJhMpkEZ rWSKRvWydeszD8cNJ28MUjtXF14o6KsugB2SQEShH2EaqBHOf5CPMbAUXo2jbbx01/2Y 2QVQ== X-Forwarded-Encrypted: i=1; AJvYcCUxGsRk22AlhMK+95DHw+Yo6KbNgiZ3/Vx9Hemi4n6N40+SLQ+3cXDzrQGK8itRwLvE89L8sY66KiD60BY=@vger.kernel.org X-Gm-Message-State: AOJu0YxI8b8dRz8Fdrzjyi1wDFR6rkwMQ+9WZ/SM3GujLPtUZDvnm/hV GywMfCtQSNOWG0VIztIKFyS1XO+OlUOXgeUwpl6OZF76b7JKfuRz2hLA X-Gm-Gg: ASbGncuWnACT5NaAr8K9jYE4oapdl+mijPjrgO2idONGcaI+eQiL96iCTPQM9dfWtsY FL3GQUvqXovKcKf0M3hNiOrMT23+Sve5GTGSSpLq2c26RGk1a8mOTU20OZuIPrrtxwBaLB4qORM Z9WyjErcmLBgZyg9Ygf/izDgdCet6LESq70hwysvzWKrVtiwRgANYJ0G+dDi+LFjELauqgWgGB+ sd1zc9Ndx8HCcpcnvVEIhrO0Ze6s2N4/MT//G2AyTCGbZhcJqZca8TvrS0oJjrksiD7wXXTQOh6 4t9CymkDEoVHI1fvljJ0mYtgLkXWJ3S8FBcVLRzsJ1BtS6L/bTKmlS340or7N9n+AU0mginHUPK RMJGDY4WS6tvhAEppJAkQanbDMZP7540NZWKVO9FO1GF/DaUpS60WVgIuAeTlKOCo0Z6Y6A2D8v ylF+NwAHzEy7S2aVdCnvx1KpcHMDstTjTPEynK X-Google-Smtp-Source: AGHT+IGhNnEPec5+FBsAp3vnSvc0/M3J1MuNwenJpEDSVtVn66SukqVhYMOMxe9+CaO1VBCpTTSGMw== X-Received: by 2002:a05:6000:2509:b0:429:c8f6:587c with SMTP id ffacd0b85a97d-42b592d61d3mr53101f8f.0.1763052150134; Thu, 13 Nov 2025 08:42:30 -0800 (PST) Received: from localhost ([2a03:2880:31ff:40::]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-42b53e84a44sm4617135f8f.14.2025.11.13.08.42.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Nov 2025 08:42:29 -0800 (PST) From: Gustavo Luiz Duarte Date: Thu, 13 Nov 2025 08:42:19 -0800 Subject: [PATCH net-next v2 2/4] netconsole: Split userdata and sysdata Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251113-netconsole_dynamic_extradata-v2-2-18cf7fed1026@meta.com> References: <20251113-netconsole_dynamic_extradata-v2-0-18cf7fed1026@meta.com> In-Reply-To: <20251113-netconsole_dynamic_extradata-v2-0-18cf7fed1026@meta.com> To: Breno Leitao , Andre Carvalho , Simon Horman , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Shuah Khan Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Gustavo Luiz Duarte X-Mailer: b4 0.13.0 Separate userdata and sysdata into distinct buffers to enable independent management. Previously, both were stored in a single extradata_complete buffer with a fixed size that accommodated both types of data. This separation allows: - userdata to grow dynamically (in subsequent patch) - sysdata to remain in a small static buffer - removal of complex entry counting logic that tracked both types together The split also simplifies the code by eliminating the need to check total entry count across both userdata and sysdata when enabling features, which allows to drop holding su_mutex on sysdata_*_enabled_store(). No functional change in this patch, just structural preparation for dynamic userdata allocation. Signed-off-by: Gustavo Luiz Duarte Reviewed-by: Breno Leitao --- drivers/net/netconsole.c | 215 +++++++++++++++++++++----------------------= ---- 1 file changed, 98 insertions(+), 117 deletions(-) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 5fe5896d6ff5..1bd811714322 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -50,7 +50,7 @@ MODULE_LICENSE("GPL"); /* The number 3 comes from userdata entry format characters (' ', '=3D', '= \n') */ #define MAX_EXTRADATA_NAME_LEN (MAX_EXTRADATA_ENTRY_LEN - \ MAX_EXTRADATA_VALUE_LEN - 3) -#define MAX_EXTRADATA_ITEMS 16 +#define MAX_USERDATA_ITEMS 16 #define MAX_PRINT_CHUNK 1000 =20 static char config[MAX_PARAM_LENGTH]; @@ -115,6 +115,8 @@ enum sysdata_feature { SYSDATA_RELEASE =3D BIT(2), /* Include a per-target message ID as part of sysdata */ SYSDATA_MSGID =3D BIT(3), + /* Sentinel: highest bit position */ + MAX_SYSDATA_ITEMS =3D 4, }; =20 /** @@ -122,8 +124,9 @@ enum sysdata_feature { * @list: Links this target into the target_list. * @group: Links us into the configfs subsystem hierarchy. * @userdata_group: Links to the userdata configfs hierarchy - * @extradata_complete: Cached, formatted string of append - * @userdata_length: String length of usedata in extradata_complete. + * @userdata: Cached, formatted string of append + * @userdata_length: String length of userdata. + * @sysdata: Cached, formatted string of append * @sysdata_fields: Sysdata features enabled. * @msgcounter: Message sent counter. * @stats: Packet send stats for the target. Used for debugging. @@ -152,8 +155,10 @@ struct netconsole_target { #ifdef CONFIG_NETCONSOLE_DYNAMIC struct config_group group; struct config_group userdata_group; - char extradata_complete[MAX_EXTRADATA_ENTRY_LEN * MAX_EXTRADATA_ITEMS]; + char userdata[MAX_EXTRADATA_ENTRY_LEN * MAX_USERDATA_ITEMS]; size_t userdata_length; + char sysdata[MAX_EXTRADATA_ENTRY_LEN * MAX_SYSDATA_ITEMS]; + /* bit-wise with sysdata_feature bits */ u32 sysdata_fields; /* protected by target_list_lock */ @@ -802,28 +807,14 @@ static ssize_t remote_ip_store(struct config_item *it= em, const char *buf, return ret; } =20 -/* Count number of entries we have in extradata. - * This is important because the extradata_complete only supports - * MAX_EXTRADATA_ITEMS entries. Before enabling any new {user,sys}data - * feature, number of entries needs to checked for available space. +/* Count number of entries we have in userdata. + * This is important because userdata only supports MAX_USERDATA_ITEMS + * entries. Before enabling any new userdata feature, number of entries ne= eds + * to checked for available space. */ -static size_t count_extradata_entries(struct netconsole_target *nt) +static size_t count_userdata_entries(struct netconsole_target *nt) { - size_t entries; - - /* Userdata entries */ - entries =3D list_count_nodes(&nt->userdata_group.cg_children); - /* Plus sysdata entries */ - if (nt->sysdata_fields & SYSDATA_CPU_NR) - entries +=3D 1; - if (nt->sysdata_fields & SYSDATA_TASKNAME) - entries +=3D 1; - if (nt->sysdata_fields & SYSDATA_RELEASE) - entries +=3D 1; - if (nt->sysdata_fields & SYSDATA_MSGID) - entries +=3D 1; - - return entries; + return list_count_nodes(&nt->userdata_group.cg_children); } =20 static ssize_t remote_mac_store(struct config_item *item, const char *buf, @@ -894,13 +885,13 @@ static void update_userdata(struct netconsole_target = *nt) =20 /* Clear the current string in case the last userdatum was deleted */ nt->userdata_length =3D 0; - nt->extradata_complete[0] =3D 0; + nt->userdata[0] =3D 0; =20 list_for_each(entry, &nt->userdata_group.cg_children) { struct userdatum *udm_item; struct config_item *item; =20 - if (child_count >=3D MAX_EXTRADATA_ITEMS) { + if (child_count >=3D MAX_USERDATA_ITEMS) { spin_unlock_irqrestore(&target_list_lock, flags); WARN_ON_ONCE(1); return; @@ -914,11 +905,11 @@ static void update_userdata(struct netconsole_target = *nt) if (strnlen(udm_item->value, MAX_EXTRADATA_VALUE_LEN) =3D=3D 0) continue; =20 - /* This doesn't overflow extradata_complete since it will write - * one entry length (1/MAX_EXTRADATA_ITEMS long), entry count is + /* This doesn't overflow userdata since it will write + * one entry length (1/MAX_USERDATA_ITEMS long), entry count is * checked to not exceed MAX items with child_count above */ - nt->userdata_length +=3D scnprintf(&nt->extradata_complete[nt->userdata_= length], + nt->userdata_length +=3D scnprintf(&nt->userdata[nt->userdata_length], MAX_EXTRADATA_ENTRY_LEN, " %s=3D%s\n", item->ci_name, udm_item->value); } @@ -962,7 +953,7 @@ static void disable_sysdata_feature(struct netconsole_t= arget *nt, enum sysdata_feature feature) { nt->sysdata_fields &=3D ~feature; - nt->extradata_complete[nt->userdata_length] =3D 0; + nt->sysdata[0] =3D 0; } =20 static ssize_t sysdata_msgid_enabled_store(struct config_item *item, @@ -982,12 +973,6 @@ static ssize_t sysdata_msgid_enabled_store(struct conf= ig_item *item, if (msgid_enabled =3D=3D curr) goto unlock_ok; =20 - if (msgid_enabled && - count_extradata_entries(nt) >=3D MAX_EXTRADATA_ITEMS) { - ret =3D -ENOSPC; - goto unlock; - } - if (msgid_enabled) nt->sysdata_fields |=3D SYSDATA_MSGID; else @@ -995,7 +980,6 @@ static ssize_t sysdata_msgid_enabled_store(struct confi= g_item *item, =20 unlock_ok: ret =3D strnlen(buf, count); -unlock: mutex_unlock(&dynamic_netconsole_mutex); mutex_unlock(&netconsole_subsys.su_mutex); return ret; @@ -1018,12 +1002,6 @@ static ssize_t sysdata_release_enabled_store(struct = config_item *item, if (release_enabled =3D=3D curr) goto unlock_ok; =20 - if (release_enabled && - count_extradata_entries(nt) >=3D MAX_EXTRADATA_ITEMS) { - ret =3D -ENOSPC; - goto unlock; - } - if (release_enabled) nt->sysdata_fields |=3D SYSDATA_RELEASE; else @@ -1031,7 +1009,6 @@ static ssize_t sysdata_release_enabled_store(struct c= onfig_item *item, =20 unlock_ok: ret =3D strnlen(buf, count); -unlock: mutex_unlock(&dynamic_netconsole_mutex); mutex_unlock(&netconsole_subsys.su_mutex); return ret; @@ -1054,12 +1031,6 @@ static ssize_t sysdata_taskname_enabled_store(struct= config_item *item, if (taskname_enabled =3D=3D curr) goto unlock_ok; =20 - if (taskname_enabled && - count_extradata_entries(nt) >=3D MAX_EXTRADATA_ITEMS) { - ret =3D -ENOSPC; - goto unlock; - } - if (taskname_enabled) nt->sysdata_fields |=3D SYSDATA_TASKNAME; else @@ -1067,7 +1038,6 @@ static ssize_t sysdata_taskname_enabled_store(struct = config_item *item, =20 unlock_ok: ret =3D strnlen(buf, count); -unlock: mutex_unlock(&dynamic_netconsole_mutex); mutex_unlock(&netconsole_subsys.su_mutex); return ret; @@ -1092,27 +1062,16 @@ static ssize_t sysdata_cpu_nr_enabled_store(struct = config_item *item, /* no change requested */ goto unlock_ok; =20 - if (cpu_nr_enabled && - count_extradata_entries(nt) >=3D MAX_EXTRADATA_ITEMS) { - /* user wants the new feature, but there is no space in the - * buffer. - */ - ret =3D -ENOSPC; - goto unlock; - } - if (cpu_nr_enabled) nt->sysdata_fields |=3D SYSDATA_CPU_NR; else - /* This is special because extradata_complete might have - * remaining data from previous sysdata, and it needs to be - * cleaned. + /* This is special because sysdata might have remaining data + * from previous sysdata, and it needs to be cleaned. */ disable_sysdata_feature(nt, SYSDATA_CPU_NR); =20 unlock_ok: ret =3D strnlen(buf, count); -unlock: mutex_unlock(&dynamic_netconsole_mutex); mutex_unlock(&netconsole_subsys.su_mutex); return ret; @@ -1156,7 +1115,7 @@ static struct config_item *userdatum_make_item(struct= config_group *group, =20 ud =3D to_userdata(&group->cg_item); nt =3D userdata_to_target(ud); - if (count_extradata_entries(nt) >=3D MAX_EXTRADATA_ITEMS) + if (count_userdata_entries(nt) >=3D MAX_USERDATA_ITEMS) return ERR_PTR(-ENOSPC); =20 udm =3D kzalloc(sizeof(*udm), GFP_KERNEL); @@ -1363,22 +1322,21 @@ static void populate_configfs_item(struct netconsol= e_target *nt, =20 static int sysdata_append_cpu_nr(struct netconsole_target *nt, int offset) { - /* Append cpu=3D%d at extradata_complete after userdata str */ - return scnprintf(&nt->extradata_complete[offset], + return scnprintf(&nt->sysdata[offset], MAX_EXTRADATA_ENTRY_LEN, " cpu=3D%u\n", raw_smp_processor_id()); } =20 static int sysdata_append_taskname(struct netconsole_target *nt, int offse= t) { - return scnprintf(&nt->extradata_complete[offset], + return scnprintf(&nt->sysdata[offset], MAX_EXTRADATA_ENTRY_LEN, " taskname=3D%s\n", current->comm); } =20 static int sysdata_append_release(struct netconsole_target *nt, int offset) { - return scnprintf(&nt->extradata_complete[offset], + return scnprintf(&nt->sysdata[offset], MAX_EXTRADATA_ENTRY_LEN, " release=3D%s\n", init_utsname()->release); } @@ -1386,46 +1344,36 @@ static int sysdata_append_release(struct netconsole= _target *nt, int offset) static int sysdata_append_msgid(struct netconsole_target *nt, int offset) { wrapping_assign_add(nt->msgcounter, 1); - return scnprintf(&nt->extradata_complete[offset], + return scnprintf(&nt->sysdata[offset], MAX_EXTRADATA_ENTRY_LEN, " msgid=3D%u\n", nt->msgcounter); } =20 /* - * prepare_extradata - append sysdata at extradata_complete in runtime + * prepare_sysdata - append sysdata in runtime * @nt: target to send message to */ -static int prepare_extradata(struct netconsole_target *nt) +static int prepare_sysdata(struct netconsole_target *nt) { - int extradata_len; - - /* userdata was appended when configfs write helper was called - * by update_userdata(). - */ - extradata_len =3D nt->userdata_length; + int sysdata_len =3D 0; =20 if (!nt->sysdata_fields) goto out; =20 if (nt->sysdata_fields & SYSDATA_CPU_NR) - extradata_len +=3D sysdata_append_cpu_nr(nt, extradata_len); + sysdata_len +=3D sysdata_append_cpu_nr(nt, sysdata_len); if (nt->sysdata_fields & SYSDATA_TASKNAME) - extradata_len +=3D sysdata_append_taskname(nt, extradata_len); + sysdata_len +=3D sysdata_append_taskname(nt, sysdata_len); if (nt->sysdata_fields & SYSDATA_RELEASE) - extradata_len +=3D sysdata_append_release(nt, extradata_len); + sysdata_len +=3D sysdata_append_release(nt, sysdata_len); if (nt->sysdata_fields & SYSDATA_MSGID) - extradata_len +=3D sysdata_append_msgid(nt, extradata_len); + sysdata_len +=3D sysdata_append_msgid(nt, sysdata_len); =20 - WARN_ON_ONCE(extradata_len > - MAX_EXTRADATA_ENTRY_LEN * MAX_EXTRADATA_ITEMS); + WARN_ON_ONCE(sysdata_len > + MAX_EXTRADATA_ENTRY_LEN * MAX_SYSDATA_ITEMS); =20 out: - return extradata_len; -} -#else /* CONFIG_NETCONSOLE_DYNAMIC not set */ -static int prepare_extradata(struct netconsole_target *nt) -{ - return 0; + return sysdata_len; } #endif /* CONFIG_NETCONSOLE_DYNAMIC */ =20 @@ -1527,11 +1475,13 @@ static void send_msg_no_fragmentation(struct netcon= sole_target *nt, int msg_len, int release_len) { - const char *extradata =3D NULL; + const char *userdata =3D NULL; + const char *sysdata =3D NULL; const char *release; =20 #ifdef CONFIG_NETCONSOLE_DYNAMIC - extradata =3D nt->extradata_complete; + userdata =3D nt->userdata; + sysdata =3D nt->sysdata; #endif =20 if (release_len) { @@ -1543,10 +1493,15 @@ static void send_msg_no_fragmentation(struct netcon= sole_target *nt, memcpy(nt->buf, msg, msg_len); } =20 - if (extradata) + if (userdata) msg_len +=3D scnprintf(&nt->buf[msg_len], - MAX_PRINT_CHUNK - msg_len, - "%s", extradata); + MAX_PRINT_CHUNK - msg_len, "%s", + userdata); + + if (sysdata) + msg_len +=3D scnprintf(&nt->buf[msg_len], + MAX_PRINT_CHUNK - msg_len, "%s", + sysdata); =20 send_udp(nt, nt->buf, msg_len); } @@ -1561,33 +1516,45 @@ static void append_release(char *buf) =20 static void send_fragmented_body(struct netconsole_target *nt, const char *msgbody_ptr, int header_len, - int msgbody_len, int extradata_len) + int msgbody_len, int sysdata_len) { - const char *extradata_ptr =3D NULL; + const char *userdata_ptr =3D NULL; + const char *sysdata_ptr =3D NULL; int data_len, data_sent =3D 0; - int extradata_offset =3D 0; + int userdata_offset =3D 0; + int sysdata_offset =3D 0; int msgbody_offset =3D 0; + int userdata_len =3D 0; =20 #ifdef CONFIG_NETCONSOLE_DYNAMIC - extradata_ptr =3D nt->extradata_complete; + userdata_ptr =3D nt->userdata; + sysdata_ptr =3D nt->sysdata; + userdata_len =3D nt->userdata_length; #endif - if (WARN_ON_ONCE(!extradata_ptr && extradata_len !=3D 0)) + if (WARN_ON_ONCE(!userdata_ptr && userdata_len !=3D 0)) + return; + + if (WARN_ON_ONCE(!sysdata_ptr && sysdata_len !=3D 0)) return; =20 /* data_len represents the number of bytes that will be sent. This is * bigger than MAX_PRINT_CHUNK, thus, it will be split in multiple * packets */ - data_len =3D msgbody_len + extradata_len; + data_len =3D msgbody_len + userdata_len + sysdata_len; =20 /* In each iteration of the while loop below, we send a packet * containing the header and a portion of the data. The data is - * composed of two parts: msgbody and extradata. We keep track of how - * many bytes have been sent so far using the data_sent variable, which - * ranges from 0 to the total bytes to be sent. + * composed of three parts: msgbody, userdata, and sysdata. + * We keep track of how many bytes have been sent from each part using + * the *_offset variables. + * We keep track of how many bytes have been sent overall using the + * data_sent variable, which ranges from 0 to the total bytes to be + * sent. */ while (data_sent < data_len) { - int extradata_left =3D extradata_len - extradata_offset; + int userdata_left =3D userdata_len - userdata_offset; + int sysdata_left =3D sysdata_len - sysdata_offset; int msgbody_left =3D msgbody_len - msgbody_offset; int buf_offset =3D 0; int this_chunk =3D 0; @@ -1608,13 +1575,24 @@ static void send_fragmented_body(struct netconsole_= target *nt, buf_offset +=3D this_chunk; data_sent +=3D this_chunk; =20 - /* after msgbody, append extradata */ - if (extradata_ptr && extradata_left) { - this_chunk =3D min(extradata_left, + /* after msgbody, append userdata */ + if (userdata_ptr && userdata_left) { + this_chunk =3D min(userdata_left, MAX_PRINT_CHUNK - buf_offset); memcpy(nt->buf + buf_offset, - extradata_ptr + extradata_offset, this_chunk); - extradata_offset +=3D this_chunk; + userdata_ptr + userdata_offset, this_chunk); + userdata_offset +=3D this_chunk; + buf_offset +=3D this_chunk; + data_sent +=3D this_chunk; + } + + /* after userdata, append sysdata */ + if (sysdata_ptr && sysdata_left) { + this_chunk =3D min(sysdata_left, + MAX_PRINT_CHUNK - buf_offset); + memcpy(nt->buf + buf_offset, + sysdata_ptr + sysdata_offset, this_chunk); + sysdata_offset +=3D this_chunk; buf_offset +=3D this_chunk; data_sent +=3D this_chunk; } @@ -1631,7 +1609,7 @@ static void send_msg_fragmented(struct netconsole_tar= get *nt, const char *msg, int msg_len, int release_len, - int extradata_len) + int sysdata_len) { int header_len, msgbody_len; const char *msgbody; @@ -1660,7 +1638,7 @@ static void send_msg_fragmented(struct netconsole_tar= get *nt, * will be replaced */ send_fragmented_body(nt, msgbody, header_len, msgbody_len, - extradata_len); + sysdata_len); } =20 /** @@ -1676,19 +1654,22 @@ static void send_msg_fragmented(struct netconsole_t= arget *nt, static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg, int msg_len) { + int userdata_len =3D 0; int release_len =3D 0; - int extradata_len; - - extradata_len =3D prepare_extradata(nt); + int sysdata_len =3D 0; =20 +#ifdef CONFIG_NETCONSOLE_DYNAMIC + sysdata_len =3D prepare_sysdata(nt); + userdata_len =3D nt->userdata_length; +#endif if (nt->release) release_len =3D strlen(init_utsname()->release) + 1; =20 - if (msg_len + release_len + extradata_len <=3D MAX_PRINT_CHUNK) + if (msg_len + release_len + sysdata_len + userdata_len <=3D MAX_PRINT_CHU= NK) return send_msg_no_fragmentation(nt, msg, msg_len, release_len); =20 return send_msg_fragmented(nt, msg, msg_len, release_len, - extradata_len); + sysdata_len); } =20 static void write_ext_msg(struct console *con, const char *msg, --=20 2.47.3 From nobody Sun Feb 8 16:12:01 2026 Received: from mail-wm1-f47.google.com (mail-wm1-f47.google.com [209.85.128.47]) (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 E268E364EBC for ; Thu, 13 Nov 2025 16:42:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763052156; cv=none; b=cRUDKh6cObvLHKiuL8P7rrakJR89g9RlYC/xIAa5tuad9rwIQAYD9BtGR13JCazFqnLT3OniLffdp08fRNFFJCEh09S1ZBrPP/xy7W4jjfE64e9hDJIQPkigjYesDAoqG0hNW2DBYoNC5r8i3NaAl4IsQnCK/9daZb71JjZtd0w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763052156; c=relaxed/simple; bh=Weou4cUBuJ16J994m9Jw12hAclJS9i+Gx49oiGHsCsU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tVMYmD6xvEv6MA/9ZWFK0dnfEB7xG2pZCaujnpYyDS1qRlJWaNU0IoYEhOnICvfWYPslog0ZbN6sPWtKI8vVJP6XhnCFH6l+SnbhmsZkg6nNMim3LzWOHb3H5wKzJZTaCW0cGTv18wBZUcuNKb0HzdeppsMv09h5SMO+91Nw1ag= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=IWEFJ+4D; arc=none smtp.client-ip=209.85.128.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IWEFJ+4D" Received: by mail-wm1-f47.google.com with SMTP id 5b1f17b1804b1-477774a878aso416475e9.1 for ; Thu, 13 Nov 2025 08:42:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1763052152; x=1763656952; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=1hVzY4UcjZPSPLTWhsYT/R2QUElmT1sTuICo+mmiFn8=; b=IWEFJ+4DL/wy3+wN8YGUOIG92GC4IQERsK6S5w9DEXeTpZvWgW8LNzLpcld8NKSNlJ sCHbTEwdYzYj8dvXDUyPS2geINyWQ0i1MzVFsnfeKiupBzxwEVsdmX54tf0mQOwZeUQe CmRkRIbxpKCiO8i1R30QSUETpS4yNU4J31j/ZU6U+vRLawShMFL1wf/1lF272CrmcNdS E8Dmf94Js9XpgQKXZO3JB6QprrT+jiwziO2zKzPAdkAjwy7RNeaYhxq0gvWEfiOcrSYL jlzHGaNCdgup6jo4XcXS1C5yD7H0IpSY0rIQayexy8k3bO8HevF1368UObB150h3+wic cenA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763052152; x=1763656952; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=1hVzY4UcjZPSPLTWhsYT/R2QUElmT1sTuICo+mmiFn8=; b=D5+6nPTyBuqNp7rEsoqKqqNn9SuiHRXl7KPCpVsUQdfElYrevEACHmnetxiPacaXcW dSGBKFqmoyT6bzuHOyfyxDtKErIKaRWEsb6qvrFWlQEEXlSLGitG2h4W2slwy0LS2hLI twzIjD2B/GsS7mMvmTUgpxANCG0HYud9ck2QpmzXiwJtq3bIq5Vms4e2ki7Ls10gQgmi SiEVEJTVGKDrqHxAaji5bfEvnNw8PO2Iec5ZFeKWg2SRl8ctRyQ8MNxwpWqtnVW+92EM Vyim06jguRmkTA6qwV91qeqWShIOSekv+NUsDEyjbcNxMy+CCJVZFIbDyaA0MIAdByvo 0vJQ== X-Forwarded-Encrypted: i=1; AJvYcCWExyKGiQK/DjZERlUbzp5F6ut6sxgk+BeDi7ktLfjvOcC5nDIeY3LeYR+axDyq8rBYC3MhfDb3+o7sAAY=@vger.kernel.org X-Gm-Message-State: AOJu0Yx4BM8QK8DjXCk5j/6CteLLWZ3XB5cSExVLmpJfY2J7uaHS8ChE Ce23MPAoWpBxQ65gOAmyyDhZqBScOSPRqxIU2WyGSGgVHdZDTRlvEZY2 X-Gm-Gg: ASbGnctJFCB3WyDvvHsZh1oQn20K6TXAUH9Fp9RUcFDuVFQS/ufl0Gc30mYM3etL9ET ZCH40uCWhOGl3rFvAy66MT/mcr35tLXVNxyhGFB+BrZUza5rqeWNwE+cNUJ7v9AVQn8IWXCK73f Hzo8tMAdmklzdANKpR1UmGAxIlVWyj8mO1Ib2QvnSdN9i/bh9FhnXa/6jD2AYFF1EAfnz+vuSJL OTwGS0+KY9tFtHon4jONH02xbF4Qp8AsLKZlHq++9JqZWYBr7zTI4Tac1QaoH39L1pSJeLTHy7Z 8flbCnWA/mjfR07FUFw5mYMO2M0vEc67gVrsCgWlqU1m1HikqLggu6mwl0ppPKvsiOk34SPq//F kcahvHPbCtxtvrD8L4kKAEr+uY9EXEgyrFf5NZCQ5hPbQzUx01KLTAOkuEhVJDvTbv7OopPSK9A /ejeuh7deloVq0RLwI/J0d8Mq1SQ== X-Google-Smtp-Source: AGHT+IGL/X4HO9I7flrMiWlzkMQGvXs40YCMrVJCpAD7fTFYE/9mwv7lP2H6UO+hyYu+NjKatOjUZQ== X-Received: by 2002:a05:600c:3b19:b0:477:555b:3411 with SMTP id 5b1f17b1804b1-4778fe5c885mr734175e9.1.1763052151844; Thu, 13 Nov 2025 08:42:31 -0800 (PST) Received: from localhost ([2a03:2880:31ff:43::]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47787e8e6a1sm96002735e9.11.2025.11.13.08.42.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Nov 2025 08:42:31 -0800 (PST) From: Gustavo Luiz Duarte Date: Thu, 13 Nov 2025 08:42:20 -0800 Subject: [PATCH net-next v2 3/4] netconsole: Dynamic allocation of userdata buffer Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251113-netconsole_dynamic_extradata-v2-3-18cf7fed1026@meta.com> References: <20251113-netconsole_dynamic_extradata-v2-0-18cf7fed1026@meta.com> In-Reply-To: <20251113-netconsole_dynamic_extradata-v2-0-18cf7fed1026@meta.com> To: Breno Leitao , Andre Carvalho , Simon Horman , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Shuah Khan Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Gustavo Luiz Duarte X-Mailer: b4 0.13.0 The userdata buffer in struct netconsole_target is currently statically allocated with a size of MAX_USERDATA_ITEMS * MAX_EXTRADATA_ENTRY_LEN (16 * 256 =3D 4096 bytes). This wastes memory when userdata entries are not used or when only a few entries are configured, which is common in typical usage scenarios. It also forces us to keep MAX_USERDATA_ITEMS small to limit the memory wasted. Change the userdata buffer from a static array to a dynamically allocated pointer. The buffer is now allocated on-demand in update_userdata() whenever userdata entries are added, modified, or removed via configfs. The implementation calculates the exact size needed for all current userdata entries, allocates a new buffer of that size, formats the entries into it, and atomically swaps it with the old buffer. This approach provides several benefits: - Memory efficiency: Targets with no userdata use zero bytes instead of 4KB, and targets with userdata only allocate what they need; - Scalability: Makes it practical to increase MAX_USERDATA_ITEMS to a much larger value without imposing a fixed memory cost on every target; - No hot-path overhead: Allocation occurs during configuration (write to configfs), not during message transmission If memory allocation fails during userdata update, -ENOMEM is returned to userspace through the configfs attribute write operation. The sysdata buffer remains statically allocated since it has a smaller fixed size (MAX_SYSDATA_ITEMS * MAX_EXTRADATA_ENTRY_LEN =3D 4 * 256 =3D 1024 bytes) and its content length is less predictable. Signed-off-by: Gustavo Luiz Duarte --- drivers/net/netconsole.c | 84 +++++++++++++++++++++++++++++++-------------= ---- 1 file changed, 54 insertions(+), 30 deletions(-) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 1bd811714322..12fbc303a824 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -155,7 +155,7 @@ struct netconsole_target { #ifdef CONFIG_NETCONSOLE_DYNAMIC struct config_group group; struct config_group userdata_group; - char userdata[MAX_EXTRADATA_ENTRY_LEN * MAX_USERDATA_ITEMS]; + char *userdata; size_t userdata_length; char sysdata[MAX_EXTRADATA_ENTRY_LEN * MAX_SYSDATA_ITEMS]; =20 @@ -875,45 +875,61 @@ static ssize_t userdatum_value_show(struct config_ite= m *item, char *buf) return sysfs_emit(buf, "%s\n", &(to_userdatum(item)->value[0])); } =20 -static void update_userdata(struct netconsole_target *nt) +static int update_userdata(struct netconsole_target *nt) { + struct userdatum *udm_item; + struct config_item *item; struct list_head *entry; - int child_count =3D 0; + char *old_buf =3D NULL; + char *new_buf =3D NULL; unsigned long flags; + int offset =3D 0; + int len =3D 0; =20 - spin_lock_irqsave(&target_list_lock, flags); - - /* Clear the current string in case the last userdatum was deleted */ - nt->userdata_length =3D 0; - nt->userdata[0] =3D 0; - + /* Calculate buffer size */ list_for_each(entry, &nt->userdata_group.cg_children) { - struct userdatum *udm_item; - struct config_item *item; - - if (child_count >=3D MAX_USERDATA_ITEMS) { - spin_unlock_irqrestore(&target_list_lock, flags); - WARN_ON_ONCE(1); - return; + item =3D container_of(entry, struct config_item, ci_entry); + udm_item =3D to_userdatum(item); + /* Skip userdata with no value set */ + if (udm_item->value[0]) { + len +=3D snprintf(NULL, 0, " %s=3D%s\n", item->ci_name, + udm_item->value); } - child_count++; + } + + WARN_ON_ONCE(len > MAX_EXTRADATA_ENTRY_LEN * MAX_USERDATA_ITEMS); + + /* Allocate new buffer */ + if (len) { + new_buf =3D kmalloc(len + 1, GFP_KERNEL); + if (!new_buf) + return -ENOMEM; + } =20 + /* Write userdata to new buffer */ + list_for_each(entry, &nt->userdata_group.cg_children) { item =3D container_of(entry, struct config_item, ci_entry); udm_item =3D to_userdatum(item); - /* Skip userdata with no value set */ - if (strnlen(udm_item->value, MAX_EXTRADATA_VALUE_LEN) =3D=3D 0) - continue; - - /* This doesn't overflow userdata since it will write - * one entry length (1/MAX_USERDATA_ITEMS long), entry count is - * checked to not exceed MAX items with child_count above - */ - nt->userdata_length +=3D scnprintf(&nt->userdata[nt->userdata_length], - MAX_EXTRADATA_ENTRY_LEN, " %s=3D%s\n", - item->ci_name, udm_item->value); + if (udm_item->value[0]) { + offset +=3D scnprintf(&new_buf[offset], len + 1 - offset, + " %s=3D%s\n", item->ci_name, + udm_item->value); + } } + + WARN_ON_ONCE(offset !=3D len); + + /* Switch to new buffer and free old buffer */ + spin_lock_irqsave(&target_list_lock, flags); + old_buf =3D nt->userdata; + nt->userdata =3D new_buf; + nt->userdata_length =3D len; spin_unlock_irqrestore(&target_list_lock, flags); + + kfree(old_buf); + + return 0; } =20 static ssize_t userdatum_value_store(struct config_item *item, const char = *buf, @@ -937,7 +953,9 @@ static ssize_t userdatum_value_store(struct config_item= *item, const char *buf, =20 ud =3D to_userdata(item->ci_parent); nt =3D userdata_to_target(ud); - update_userdata(nt); + ret =3D update_userdata(nt); + if (ret < 0) + goto out_unlock; ret =3D count; out_unlock: mutex_unlock(&dynamic_netconsole_mutex); @@ -1193,7 +1211,10 @@ static struct configfs_attribute *netconsole_target_= attrs[] =3D { =20 static void netconsole_target_release(struct config_item *item) { - kfree(to_target(item)); + struct netconsole_target *nt =3D to_target(item); + + kfree(nt->userdata); + kfree(nt); } =20 static struct configfs_item_operations netconsole_target_item_ops =3D { @@ -1874,6 +1895,9 @@ static struct netconsole_target *alloc_param_target(c= har *target_config, static void free_param_target(struct netconsole_target *nt) { netpoll_cleanup(&nt->np); +#ifdef CONFIG_NETCONSOLE_DYNAMIC + kfree(nt->userdata); +#endif kfree(nt); } =20 --=20 2.47.3 From nobody Sun Feb 8 16:12:01 2026 Received: from mail-wr1-f49.google.com (mail-wr1-f49.google.com [209.85.221.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 62C43364E9B for ; Thu, 13 Nov 2025 16:42:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763052157; cv=none; b=Q/6pmlXh50j7rYeVJqVasW2YHX4hoAOlMzBUt7/IqCEOORTeYKcVUvRdvWHjDDzQ/mHIrqZj4KMIcSbSw84ptJU49italYP9/ev3wbT+fRJLlT7/hSzQhwlgNh8EG8KLklhUZw2qifJJZFbaattRj+diGT9Lx8tAgMlUVhTN2u4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763052157; c=relaxed/simple; bh=AZDhgFsJHk/7/ccWHmuKjRVzzDMIUsT8B2xszzmjcS4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=T+RjydmQmWyDie3qi83OeAP2BjnZtxdlsbhwJFjh9UAwxc1n90NJ/RHrSPgCbCvzLuXzMIGB9nkPzLnyIvR/Z/tgNUXAVQ0o+TjMl8r1w6A7XDzuKcvsl2JRo4R0r6tt6UZnPmtGbU1Y0FP/2SAetRSHaDJJ1xjC7fkVwamEEIg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=IuJ4IYJX; arc=none smtp.client-ip=209.85.221.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IuJ4IYJX" Received: by mail-wr1-f49.google.com with SMTP id ffacd0b85a97d-42b2dd19681so187261f8f.3 for ; Thu, 13 Nov 2025 08:42:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1763052154; x=1763656954; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=Tnv5GvLZO90fssK5mBO/V2ejb0VVnidgq+QHki0NiLw=; b=IuJ4IYJXLJ2V5+7Y5+mRDTUTL2yzgqfIK7tEPsOTetMWojJb6Y1g9LSVir2GIvKVRf Yv+a1pGGPiP6Gfxk16B/uaFurp0SkXbX+hphQNp07ksmvhtcOWOV7mjdOuI0BqjvYYKU zDONzb9C2el/O/eHTD6PIjHk62BdfujD1UdFvbAhW0UuvYcywIzbmM9w7oUWYdX62qrk DFBCpTUbKm+UhP7HXJ7dusVMcE2FsBbdwYrOUlcKBjsaVC2379pTisGc+099x7tO//2V e/1QdPmECdMRPGnOfCRPRTJO4BLRv+D3Hbpl4s0fCD/vFymEydKWRfbkioWs0E5X+Hzt glvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763052154; x=1763656954; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=Tnv5GvLZO90fssK5mBO/V2ejb0VVnidgq+QHki0NiLw=; b=uXUqPz4jLQMzP6iGIZkN8ozQxj0A/LrUD20Hem7hAkMwRB65IFJ8zQYC/kj+Lriom2 6qWIYBlD4Hu/TJyw8YZAx+F1gAxaZNS1gl9BiiEhrU8TpKZ3yfFXfApRFmC/b13gjrbC gTWsBCwo1zzFzO7IjbrM8g8zDcGIS2lggPACgSsUDTNbeUi4lOawAbW5/cyXBWoI2EM/ 2EFPlG+aBOXJHrOKh/RwulNj903QQ93I7LaU+bull+iQAwWhkOyMWKahZQNl1wbJIf8t uIPlWUdHjX47zI/Nl4+RYOV5IwnZXyCgUPfhKVflUY9SpLmdWjQoL1/dFmaJwWc0fda5 2/3A== X-Forwarded-Encrypted: i=1; AJvYcCWv3justqjOxolUjcdKOEkwSoiN53pi3D4JPktQ/Fs3l/Scqq5s2OjnMecJXEWyYF6h4QQfFdDPgBkHibs=@vger.kernel.org X-Gm-Message-State: AOJu0YzI/4TahYHDGOkvFnpG5Bsm40WGIsV5VemjFampRj5cOWZn7orF l4JSROLc7vAJTqL87hiE7egLXTGqf+gBtudELDbS5pL8zpa5EuSyj+i3 X-Gm-Gg: ASbGnct4pp9l5IlSumtuM0vc2W14Lws9yzzoelxeOOI/w3J4+QpZJ4WEB+pg0LzPt9s ZHZ7Gr5Ulr41DDZg6sM/4eA9LijQw4gijR5mXFYPUmsrd7+UuknWi4RpyUXKbh/WIlaWIc/GMkl w9RUCZVlzOk0+2GBQXEK5IPHuN6f0rv0L2R6RMIollRVw/r4ot8a8AQbaakG92sCdH5+m5MUE+x bPwceIRNIPLnDbPL36YvC/oZ2IarSe/+oEriHi8G6D4oGj+h4fIFodz/wqMTBxGesrtOP/HZYyq veLsG7pN9aZDtvJ17ct0cXR4o3/MPRzvLYNd0Ol6E/VcaiE3r7+PJQxDZ5SWWHFu+oyHgP5cSiY semJ5k1hBbFNiAnuLCUGYAr3BiaIAcAmVCzILoH1kOCweXbVy/HKHpEqgQql+es0vMK3YtuQFAH F3UddrG8VAulfzahY= X-Google-Smtp-Source: AGHT+IFlJhZQHRbGLobb3YLbAsBiS2Koyw/Ec1i06oLS8N0XCLnx1tPyDdy1oAHB/rz71WT4cMX8YQ== X-Received: by 2002:a05:600c:c4b8:b0:477:5b01:7d42 with SMTP id 5b1f17b1804b1-4778fee8183mr614895e9.5.1763052153366; Thu, 13 Nov 2025 08:42:33 -0800 (PST) Received: from localhost ([2a03:2880:31ff:50::]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-42b53f21948sm4877254f8f.43.2025.11.13.08.42.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Nov 2025 08:42:32 -0800 (PST) From: Gustavo Luiz Duarte Date: Thu, 13 Nov 2025 08:42:21 -0800 Subject: [PATCH net-next v2 4/4] netconsole: Increase MAX_USERDATA_ITEMS Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251113-netconsole_dynamic_extradata-v2-4-18cf7fed1026@meta.com> References: <20251113-netconsole_dynamic_extradata-v2-0-18cf7fed1026@meta.com> In-Reply-To: <20251113-netconsole_dynamic_extradata-v2-0-18cf7fed1026@meta.com> To: Breno Leitao , Andre Carvalho , Simon Horman , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Shuah Khan Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Gustavo Luiz Duarte X-Mailer: b4 0.13.0 Increase MAX_USERDATA_ITEMS from 16 to 256 entries now that the userdata buffer is allocated dynamically. The previous limit of 16 was necessary because the buffer was statically allocated for all targets. With dynamic allocation, we can support more entries without wasting memory on targets that don't use userdata. This allows users to attach more metadata to their netconsole messages, which is useful for complex debugging and logging scenarios. Also update the testcase accordingly. Signed-off-by: Gustavo Luiz Duarte Reviewed-by: Breno Leitao --- drivers/net/netconsole.c | 2 +- tools/testing/selftests/drivers/net/netcons_overflow.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 12fbc303a8240..36ce19936fa39 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -50,7 +50,7 @@ MODULE_LICENSE("GPL"); /* The number 3 comes from userdata entry format characters (' ', '=3D', '= \n') */ #define MAX_EXTRADATA_NAME_LEN (MAX_EXTRADATA_ENTRY_LEN - \ MAX_EXTRADATA_VALUE_LEN - 3) -#define MAX_USERDATA_ITEMS 16 +#define MAX_USERDATA_ITEMS 256 #define MAX_PRINT_CHUNK 1000 =20 static char config[MAX_PARAM_LENGTH]; diff --git a/tools/testing/selftests/drivers/net/netcons_overflow.sh b/tool= s/testing/selftests/drivers/net/netcons_overflow.sh index 29bad56448a24..06089643b7716 100755 --- a/tools/testing/selftests/drivers/net/netcons_overflow.sh +++ b/tools/testing/selftests/drivers/net/netcons_overflow.sh @@ -15,7 +15,7 @@ SCRIPTDIR=3D$(dirname "$(readlink -e "${BASH_SOURCE[0]}")= ") =20 source "${SCRIPTDIR}"/lib/sh/lib_netcons.sh # This is coming from netconsole code. Check for it in drivers/net/netcons= ole.c -MAX_USERDATA_ITEMS=3D16 +MAX_USERDATA_ITEMS=3D256 =20 # Function to create userdata entries function create_userdata_max_entries() { --=20 2.47.3