From nobody Fri Dec 19 14:23:43 2025 Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com [209.85.128.48]) (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 8C7A023EAA4 for ; Wed, 5 Nov 2025 17:07:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762362431; cv=none; b=KhNtQO40CqjNOgYd34Za5cf8bw2FAc3O0vPK9AnJShsDY6DHM/60fGjlAWVZ7UStm/iub4kUomdVsyMI3XyNjqe9/CEDNddEk7PHRLqPFSYFS31QV/1l+ERRJexpGyQk2D3dgJU2MVcaA0dVD/OuBTcm2zrj1J0Wpn5MjqXLhfE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762362431; c=relaxed/simple; bh=vlDt8G7La6rBbMdsXh2EQ/UTfNoCsRjoqiLTl6V/5rw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dA4aS94UlAmp6S5SSvw+Fc/6zmEkyNk0V7y+SANcVboirYFfndzMkhtV7Em8xDZh6VE0kAYS9y8JMw1klG+8noDYzxsu7DQKrcOkPXL3FcOVgKEoCwc3dFloCJBXOO5WiZQ9Ja0gHxSYYGKm/gbM/M4+HayTdVfMT5XB6Aes+VA= 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=aYfmOXX5; arc=none smtp.client-ip=209.85.128.48 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="aYfmOXX5" Received: by mail-wm1-f48.google.com with SMTP id 5b1f17b1804b1-47754cbe1feso22255e9.1 for ; Wed, 05 Nov 2025 09:07:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1762362427; x=1762967227; 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=IyStgM1cwvNYi0rgpR5EPyADWjSnrMmQqly0Xyjd5fk=; b=aYfmOXX5G0SJ5qqGxFj6G3lngDY9pviWHuS1taLorV6Wc9wUQjogwvO1y6Jvrl8/Bw yQXptQib6stQy04bO0DNz5AuokiilTKEOb5GjjhWZi6d0mzBZoiVz/Y9J/4aomwIF5lx 6Y2suJcmRVv4HPBd844d8rqzmtKyvtVesTAd2Mhax4DhUT6NxwjE1pbCkwCnx4+zKcaG RP7IGuO/VR/dEseK+Km4YmmpSrcfrS17lHs279A6biqpIJW3VPecvgxHWLjRSvX0OmQV PRlwht/tvFNhZKB+2GRnhO1ukhEOY86/eTZ1ixeRFnzfw2JuIXAtct4H9+WVpDN6S3Xg CyWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762362427; x=1762967227; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=IyStgM1cwvNYi0rgpR5EPyADWjSnrMmQqly0Xyjd5fk=; b=JiJXTlbd6CD5LlBQ7z/eQwx9b/NVM3S1NiRcX2f0fyFBaqCC2xaAdzQrT0n6EJ3WZK tQBwcRVtQTwkate3PP9woyjFb89bmndR2MpGU8tTwvVyVPK8NzyCnCRhpI55RDjbFqUF CCspnTpHQYKYDJlXKhPFrsF2/mR9OzSy77XSGQDrIZqSsytx0yoLv1VyrUINuv3uL23n hJAMsnq+l5KXf1cw5Rv6+1A1dVWk0SXardm3oMOlHcJU7MVchqfZ/k9cQQW6+RZP0WYH NPAMvn0B7EcEliV7m1hkkgDwHKfspC9UZoQN241pHPhC4a7WLq0JwG/m3S4KRa1PFp0K D5sg== X-Forwarded-Encrypted: i=1; AJvYcCU0M5Pfdu8mcGYqrmbaWgZZBPCQpSjQLGXzQaqs9IHZP1b1UqofBrHykmRG7d0PiIj0AKtJDUINqRUVgpk=@vger.kernel.org X-Gm-Message-State: AOJu0YxAfgCo53rRj0WZIRf9ngJKTMwajJ7FLpcy5S+hNYIuaHKnSTWB yul2j8/lo9CNCBV1BupOe1/FR0tRgkzGotYi1ojOrmzOuN8VZgnlNom3 X-Gm-Gg: ASbGncvotPlZjhKE7XypSUQmaEpHkR8TcTlsYJZSOpGHohgqQSBkLNUYWUvMyKnquOd 4/qYfKuXO0Jx286NKXtSYEtzhj9CjqM36IHigSWWxmNTS7VLFui456OPhCPCGYxR1HAhZuOq3cf 1UR8fB2NeaP6uddXUMbc9dlkflO0o1uPQIhmdF33dKBDwqYeZNdsEOk08L4DEbcfgTPC8BFYZs7 VgsQUEXSBNOm4O0lGI/Elh+ek5OUOZe7KiLaZqwCYucFKRWTGqBcFl5NFiHyZH2URuNJ9ZaijEb SpMbPXl21lfPhXuwN2zonmN1iMqx2DJztenRwsQWKttmBqzZ4PVcuQxHDuWvFPspLBWNW6bsAwc IkyKzxyxYmcye7FeJtydfArlWdjPADn9nheP50g2xMjruFBCYOqiweWjxfURVwoxjI+RSiEiWag GJLz+e X-Google-Smtp-Source: AGHT+IGO0uLduZurL5aiN3AILM28uZ4tKx7/MgWBJ8XXYSUROQlAHXvVRDNx5TsJBFuXRoics2RZRg== X-Received: by 2002:a05:600c:46ce:b0:475:ddae:c4b5 with SMTP id 5b1f17b1804b1-4775ce16416mr18619705e9.4.1762362426572; Wed, 05 Nov 2025 09:07:06 -0800 (PST) Received: from localhost ([2a03:2880:31ff:4e::]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-429dc1f5ab9sm11179552f8f.22.2025.11.05.09.07.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Nov 2025 09:07:05 -0800 (PST) From: Gustavo Luiz Duarte Date: Wed, 05 Nov 2025 09:06:43 -0800 Subject: [PATCH net-next 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: <20251105-netconsole_dynamic_extradata-v1-1-142890bf4936@meta.com> References: <20251105-netconsole_dynamic_extradata-v1-0-142890bf4936@meta.com> In-Reply-To: <20251105-netconsole_dynamic_extradata-v1-0-142890bf4936@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 --- drivers/net/netconsole.c | 73 ++++++++++++++++----------------------------= ---- 1 file changed, 24 insertions(+), 49 deletions(-) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 5d8d0214786c..0a8ba7c4bc9d 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -1553,13 +1553,16 @@ static void send_fragmented_body(struct netconsole_= target *nt, const char *msgbody, 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; + int extradata_offset =3D 0; + int msgbody_offset =3D 0; =20 #ifdef CONFIG_NETCONSOLE_DYNAMIC extradata =3D nt->extradata_complete; #endif + if (WARN_ON_ONCE(!extradata && extradata_len !=3D 0)) + return; =20 /* body_len represents the number of bytes that will be sent. This is * bigger than MAX_PRINT_CHUNK, thus, it will be split in multiple @@ -1575,7 +1578,6 @@ static void send_fragmented_body(struct netconsole_ta= rget *nt, */ while (offset < body_len) { int this_header =3D header_len; - bool msgbody_written =3D false; int this_offset =3D 0; int this_chunk =3D 0; =20 @@ -1584,55 +1586,28 @@ static void send_fragmented_body(struct netconsole_= target *nt, ",ncfrag=3D%d/%d;", offset, body_len); =20 - /* 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; - } - - /* 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; - } + /* write msgbody first */ + this_chunk =3D min(msgbody_len - msgbody_offset, + MAX_PRINT_CHUNK - this_header); + memcpy(nt->buf + this_header, msgbody + msgbody_offset, + this_chunk); + msgbody_offset +=3D this_chunk; + this_offset +=3D this_chunk; + + /* after msgbody, append extradata */ + this_chunk =3D min(extradata_len - extradata_offset, + MAX_PRINT_CHUNK - this_header - this_offset); + memcpy(nt->buf + this_header + this_offset, + extradata + extradata_offset, this_chunk); + extradata_offset +=3D this_chunk; + this_offset +=3D this_chunk; + + /* if all is good, send the packet out */ + offset +=3D this_offset; + if (WARN_ON_ONCE(offset > body_len)) + return; =20 send_udp(nt, nt->buf, this_header + this_offset); - offset +=3D this_offset; } } =20 --=20 2.47.3 From nobody Fri Dec 19 14:23:43 2025 Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) (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 18A6E33DECC for ; Wed, 5 Nov 2025 17:07:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762362434; cv=none; b=LMUdWu2xUr1ccxerUqV3J60pKEGw49/CnpWjnjtBrEJJLkRhSnfdfJuO8TtFfqmN6yJzSwvY6N0ZFeOElvIk8M6Wvh5J8/hNEAJsenV+/kUNaruKwwhNvtRD3BXPV3pG0Xi/mRtSwOr6jgZoFePPiXdHL2uOeOoX/lx6ZSwJXP0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762362434; c=relaxed/simple; bh=eaE16VgmGggegeN1BwWmj0QHqIn4/sNyqXWlWFoejMQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=S8KBmbGagjgaEg7HJqNkdUVzBiQ+oCcmwv0To6JlLi3h+xI0w92Ffk0sQQkhdiO4+q86M8hVEap6FPHBvPep03SZpfJyN7jlT1griOqbRAbJsqaM9GlDJtpk4Mzju/SNWZAEtI38cyRPspAsUIyC6riSRaLncekHEEduwt/HjHg= 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=a/8UDSpS; arc=none smtp.client-ip=209.85.128.52 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="a/8UDSpS" Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-47754cbe1feso22295e9.1 for ; Wed, 05 Nov 2025 09:07:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1762362428; x=1762967228; 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=burJbSG4PCBpYev8kKjngMRTrj8HazTfwLvWO+aw4Hs=; b=a/8UDSpSYckHws8+YpKF21UDCxXaFrfcewEjDQ4QX4g33Z/8YbypR9xViGwZWHl3If SM++rbUaexighBgaAjXJBCUMSppd3Ibh0n8bofTEpq6py0FaEpVqMuKU36L07pREtctQ lap1tDrFskSxNQau0WmzFv74AHkJktg/dy383W+s6zwluCgRwyCC96ZdhF6CHaie5U3j LP1p0Rp2RRXa3K4YGkcJ9JKS3VXSTlM8fYPrwZE9xoAJZSRQAReITIahCQuOl4k8dDC9 O1mahQSX5PQ3WTTsYDAQwjMlBrBoZD51m+8jqDsAIY1nBR6uG6JPAWWn4FP/DO542uNh 1xHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762362428; x=1762967228; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=burJbSG4PCBpYev8kKjngMRTrj8HazTfwLvWO+aw4Hs=; b=w4/Lk1eejaRstS5JZxL2ko7u4un8kkWEy48bLFH9M+7QrkIynAewOA3kyq+4gkLDDA 61cmctQXT20wgYsOErf4vh3EH2jlmfGnugyZxIjtHFJ/GTSxpTMLyTx4kFHxMWnUaVlv rpY526fRlmadqUbqZGnbbrtLeBavCDvEoWMFVbDoLnu++5XX7FYOi0MgCrHaP0+jQ8uK hP7tLAhyepZJHwKH+TQGZLBHec1xKbw3OddcXpzmN4YXmVsaAMRfe+VZysi6n47Odxw/ Ydfs7+qFui5hIwiqGi2F7OjE/aPzPrwIgfK8udmvDeP93qhEVAw9ptIjbHznY495ZfMc OuNQ== X-Forwarded-Encrypted: i=1; AJvYcCUPu05hTPLdzC41u2Bb79eB39RSIkeA7BEuoj/l1VONJk/bBUzLXnCJgxzm1/+cgAaA1pWbBRlA+9mH1/A=@vger.kernel.org X-Gm-Message-State: AOJu0Yy+pAXl3mVTSRxnW91U8+dySBneV2xTM5IcCzyYstj9ZLTUiPVj cD1uuWjuLFbq1KFTNozvOjtK8l+CzZdTcDT2tSrQe8kbsSwf5eC5+Z7L X-Gm-Gg: ASbGnctpioW1aHB6aF14lQ6BTe0Ce30b8cFZroOym6NDnihkgZ+csSm6MKE7tPM++f+ a6nsbNUvcvya1ySXpALkD1tHbY9oxVh1piWaLQ5GcvjAIZyglCU9OTFv6ektGmNLb/shxSbYzgA qFy8O+Y6hCi8bdphH8H6waj6wukgN0YiuYA3QhVUh+AfWYuR6hB+JrzW9AbW+0Ks68mX+ckJSSY iHydTWbAyM7tG+9QiCn5d4JITV/JnEDdJACWXpA/V8OUspLtkYA3a+zPB/uSPbWcDOvq8iqW7vE aSs3SsrblAQKwCLgaP+f2CDygOmzllvbDNnfcDvpqnQUmNANkl6V8EtJJleCJFZDYn8ugGVN2kS 90yKnu9dHkwrQ+1a0hSs/AcQ07OG+4hXYf38f2AwGpA5zsvEQjpqPpZz+qgWcyV/aJ1M6afP89g s5wqXR X-Google-Smtp-Source: AGHT+IHDK9t1hYzjHzU+6mjzWoH6s/etvwyCbcPLyDUSLcDVPzdD0VstKOWPkuplNrgu0TEqwF6POw== X-Received: by 2002:a05:600c:1993:b0:46f:da97:91cc with SMTP id 5b1f17b1804b1-4775ce4b8c8mr20586985e9.6.1762362428079; Wed, 05 Nov 2025 09:07:08 -0800 (PST) Received: from localhost ([2a03:2880:31ff:70::]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4775ce329afsm56703195e9.16.2025.11.05.09.07.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Nov 2025 09:07:07 -0800 (PST) From: Gustavo Luiz Duarte Date: Wed, 05 Nov 2025 09:06:44 -0800 Subject: [PATCH net-next 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: <20251105-netconsole_dynamic_extradata-v1-2-142890bf4936@meta.com> References: <20251105-netconsole_dynamic_extradata-v1-0-142890bf4936@meta.com> In-Reply-To: <20251105-netconsole_dynamic_extradata-v1-0-142890bf4936@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 --- drivers/net/netconsole.c | 204 +++++++++++++++++++------------------------= ---- 1 file changed, 84 insertions(+), 120 deletions(-) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 0a8ba7c4bc9d..e780c884db83 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -50,7 +50,8 @@ 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_SYSDATA_ITEMS 4 #define MAX_PRINT_CHUNK 1000 =20 static char config[MAX_PARAM_LENGTH]; @@ -122,8 +123,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 +154,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 +806,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 +884,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 +904,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); } @@ -960,7 +950,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, @@ -979,12 +969,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 @@ -992,7 +976,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); return ret; } @@ -1013,12 +996,6 @@ static ssize_t sysdata_release_enabled_store(struct c= onfig_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 @@ -1026,7 +1003,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); return ret; } @@ -1047,12 +1023,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 @@ -1060,7 +1030,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); return ret; } @@ -1083,27 +1052,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); return ret; } @@ -1146,7 +1104,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); @@ -1353,22 +1311,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); } @@ -1376,46 +1333,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 @@ -1517,13 +1464,8 @@ static void send_msg_no_fragmentation(struct netcons= ole_target *nt, int msg_len, int release_len) { - const char *extradata =3D NULL; const char *release; =20 -#ifdef CONFIG_NETCONSOLE_DYNAMIC - extradata =3D nt->extradata_complete; -#endif - if (release_len) { release =3D init_utsname()->release; =20 @@ -1533,11 +1475,11 @@ static void send_msg_no_fragmentation(struct netcon= sole_target *nt, memcpy(nt->buf, msg, msg_len); } =20 - if (extradata) - msg_len +=3D scnprintf(&nt->buf[msg_len], - MAX_PRINT_CHUNK - msg_len, - "%s", extradata); - +#ifdef CONFIG_NETCONSOLE_DYNAMIC + msg_len +=3D scnprintf(&nt->buf[msg_len], + MAX_PRINT_CHUNK - msg_len, + "%s%s", nt->userdata, nt->sysdata); +#endif send_udp(nt, nt->buf, msg_len); } =20 @@ -1551,30 +1493,41 @@ static void append_release(char *buf) =20 static void send_fragmented_body(struct netconsole_target *nt, const char *msgbody, int header_len, - int msgbody_len, int extradata_len) + int msgbody_len, int sysdata_len) { - const char *extradata =3D NULL; + const char *userdata =3D NULL; + const char *sysdata =3D NULL; int body_len, offset =3D 0; - int extradata_offset =3D 0; + int userdata_offset =3D 0; int msgbody_offset =3D 0; + int sysdata_offset =3D 0; + int userdata_len =3D 0; =20 #ifdef CONFIG_NETCONSOLE_DYNAMIC - extradata =3D nt->extradata_complete; + userdata =3D nt->userdata; + sysdata =3D nt->sysdata; + userdata_len =3D nt->userdata_length; #endif - if (WARN_ON_ONCE(!extradata && extradata_len !=3D 0)) + if (WARN_ON_ONCE(!userdata && userdata_len !=3D 0)) + return; + + if (WARN_ON_ONCE(!sysdata && sysdata_len !=3D 0)) return; =20 /* body_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; + body_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 body. The body 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. + * 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 + * offset variable, which ranges from 0 to the total length of the + * body. */ while (offset < body_len) { int this_header =3D header_len; @@ -1594,12 +1547,20 @@ static void send_fragmented_body(struct netconsole_= target *nt, msgbody_offset +=3D this_chunk; this_offset +=3D this_chunk; =20 - /* after msgbody, append extradata */ - this_chunk =3D min(extradata_len - extradata_offset, + /* after msgbody, append userdata */ + this_chunk =3D min(userdata_len - userdata_offset, MAX_PRINT_CHUNK - this_header - this_offset); memcpy(nt->buf + this_header + this_offset, - extradata + extradata_offset, this_chunk); - extradata_offset +=3D this_chunk; + userdata + userdata_offset, this_chunk); + userdata_offset +=3D this_chunk; + this_offset +=3D this_chunk; + + /* after userdata, append sysdata */ + this_chunk =3D min(sysdata_len - sysdata_offset, + MAX_PRINT_CHUNK - this_header - this_offset); + memcpy(nt->buf + this_header + this_offset, + sysdata + sysdata_offset, this_chunk); + sysdata_offset +=3D this_chunk; this_offset +=3D this_chunk; =20 /* if all is good, send the packet out */ @@ -1615,7 +1576,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; @@ -1644,7 +1605,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 /** @@ -1660,19 +1621,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 Fri Dec 19 14:23:43 2025 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 0631D33EAFD for ; Wed, 5 Nov 2025 17:07:11 +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=1762362434; cv=none; b=PMmNEd4ooB8eTYprfL7Yh9gLhWBswBIY+sZIR0w+T8mv5sAzrS41Cx0AXUUu2wIIxq8BMdki/pq8G+sLTHY4M8n+HLTPI4gW9ZPhOJaznxeqa3z/KfFt1sTP14sm07NpkP5fVcOObO4zMAjlaC5SlMxmfnkguSx7A2ntox2T83c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762362434; c=relaxed/simple; bh=DFNz/ejJkffO4oOSwMvau6qAbhIyxUbFeMtY00HZjvw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eER23Unohrk/vo+msghWlP6LIkDqj65QeR2+s4f6tiQR5sBDKr4N9ZiwBLZKIg9d55fKzUssj2CoWc5RXzKLzWYz3N7e4gho4kh9UWxfQJCsBKKDX9LVWIrTaqGXu5SzQEmFoiWkPSoy3uAVgajCkVxUS3dv7yedGJEpMfdSV4A= 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=Nk235gMz; 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="Nk235gMz" Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-4770e0b0b7dso19255e9.1 for ; Wed, 05 Nov 2025 09:07:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1762362430; x=1762967230; 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=VSpTpNA8dU2VgWFE2OXhins+HfyeU+CDDzVZ8NCLtPo=; b=Nk235gMzsSxCkwjjC6gJFqR0dYM+XO7iGmS7RizM4Cp2HQyKOUkMbV1ntKBuy/P5W2 jszk4k1qaVs6zP/O8JSHUV07oVO0wDokOlAB35RdDtzttEgw/W+UBUgFu21CVjbO+UNw VJXDGIiapk29HPwwQrnFL1XIr0IEC2G1gmY/CXY5DXglPYnrAF0TgWwe5q6HFXhqGlry +Q/eSZ9VI5NCBoNXTV2+ziaEj0JBAFwnoZIPtPh7WuPc99Lv99y+8vzy6qtJClb7Mb3C bOIinhzUYwk77EOUiUnM0gBu/MW7Ogp9CILtbWdF5Ot/UCcpn2DhF2pWu3VzNwmAvXfN 3uUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762362430; x=1762967230; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=VSpTpNA8dU2VgWFE2OXhins+HfyeU+CDDzVZ8NCLtPo=; b=Qio3hmvAmuCbMhGoiYijHotPQ43P0Lp8ypxTzKadJ++ic1hMEkLz+hVrWV7EOq3wgN DiuC29M/9czAUkQf9E40vJZM/AtCVnIaYRLHFVST5xxOmsPTyB9oD6BzJnnTal9zvmke NKrybdGWOQGL+qmc3q9ihVRoZ4HV3btJG4FxjJhlecQJaXFTqlCsg/bdlQlK9Dw7R/B/ MEHx6ieqrmyc1t11shB59+yMLfsbDeXtqjqjZOwmTOTgW8UO2XylPO4qsaJk2J/0w6Gc 8VLx1S+fsJnRPTQPvLTO694wHLboXHfQ1LQMXaHeG6+OXNUB2xbyWt269+2Cnjcn4i8C jfVw== X-Forwarded-Encrypted: i=1; AJvYcCXGtt9tr2gP3udsrImdiSczN04A9l9KFaFsrsfSzXYG4AdKajnifBPivKSkDstPEKkWj8qkjA59OgTp2pA=@vger.kernel.org X-Gm-Message-State: AOJu0Yy1XvqZ4dAkRD75mnvaUvzEcXxgOxsQQR1pv3xURLvggH9eW4ta fJmio9hFd7mmY9b5YZ9uC2y+hkxjDklHuMBnay2iKb806MCIPirqGK1z X-Gm-Gg: ASbGnctuKti6W08W6zjdds4Wzc4e3B/h9Xeobv/knSpzH2D2wMx6PEoJZMmnhM+znjc Jfu2zaF/X0X/7xSXzq9q37oReGKeyLEM2lL0acf3Zr2omvnWyUfej9WF3kYkX8AdvQ73oVar2M9 TEZtaMIunQJh2jJQPwLTt9Ao6eAymWCfOISyaqnU6Im0dSZCid4Yfrce7wBTjP5NSrQoVpVFYKP uOsdNxdKbSgMj5x6uRqWoSeigAv7VwcKHTw4YaisE6UIO+GmuqYLU/1o0gx9H7V/LdSUqh3ve0U EhQSAN8EjfwDqW+vZI4UhgvLSi2JT7LmPwcuIdhUoRSBiZ33dvR2+gf0O0dtnGInwYh43EdcQRC ZiUQmQ0k2jc3srXEMcqyAEx1CovCKqeROyp2J2wEXVhC5HyVVd/fceD27ZYF7P8J5NscUtyv5ui 0rZe1HKIH7qlrulNs= X-Google-Smtp-Source: AGHT+IGnZ+2VvaWa5GyWqJqzkHv1KLVSFIQGStAfdtAnK0L8qP0/HIRfoQhdMFNTRaDwvqH7Ca/tkA== X-Received: by 2002:a05:600c:198a:b0:475:dc06:b5a8 with SMTP id 5b1f17b1804b1-4775ce24f38mr19442805e9.7.1762362429569; Wed, 05 Nov 2025 09:07:09 -0800 (PST) Received: from localhost ([2a03:2880:31ff:48::]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-429dbf53e86sm11553010f8f.0.2025.11.05.09.07.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Nov 2025 09:07:09 -0800 (PST) From: Gustavo Luiz Duarte Date: Wed, 05 Nov 2025 09:06:45 -0800 Subject: [PATCH net-next 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: <20251105-netconsole_dynamic_extradata-v1-3-142890bf4936@meta.com> References: <20251105-netconsole_dynamic_extradata-v1-0-142890bf4936@meta.com> In-Reply-To: <20251105-netconsole_dynamic_extradata-v1-0-142890bf4936@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 | 87 +++++++++++++++++++++++++++++++-------------= ---- 1 file changed, 56 insertions(+), 31 deletions(-) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index e780c884db83..8a11b3ca2763 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -154,7 +154,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 @@ -874,45 +874,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, @@ -935,7 +951,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); @@ -1182,7 +1200,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 { @@ -1478,7 +1499,8 @@ static void send_msg_no_fragmentation(struct netconso= le_target *nt, #ifdef CONFIG_NETCONSOLE_DYNAMIC msg_len +=3D scnprintf(&nt->buf[msg_len], MAX_PRINT_CHUNK - msg_len, - "%s%s", nt->userdata, nt->sysdata); + "%s%s", nt->userdata ? nt->userdata : "", + nt->sysdata); #endif send_udp(nt, nt->buf, msg_len); } @@ -1841,6 +1863,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 Fri Dec 19 14:23:43 2025 Received: from mail-wr1-f53.google.com (mail-wr1-f53.google.com [209.85.221.53]) (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 AF61133F8D7 for ; Wed, 5 Nov 2025 17:07:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762362436; cv=none; b=Vm7VYxc4exLlC7CqiUjdiHiLk/Xqd2qgzt9f/tvC6B0o4VVEImBjjIs7BA3VFd/v2x/WqfPG8p1tdf+8A4vSjBYuj/xYV6PinEKTqpVSec1BoQj4e76dSmYIeYq2LzViGkSM7bIxiFxbBcmL9AvikiIzS0xA97a8xVEyLBH5x+o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762362436; c=relaxed/simple; bh=SHevSYfAflYvIOjcPM2PiuslQ8TTF9Z0OzcTTNZ+A3o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=o6KDlkVwKPKL6UceYb6p7gokRXX80STmDUfal0Ck/PFbfz17uPpExxtRMgaSwRYEerNhhU3MAjbgbao8EVR2Egb8VBjc2fOARsDvP5c+6pZxzuq1IDt58MPtLqugw5x0epeo+KysTt7tewjAO9YcHRPAhUJ2vQXhmS66HiPmpns= 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=j5EYisWQ; arc=none smtp.client-ip=209.85.221.53 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="j5EYisWQ" Received: by mail-wr1-f53.google.com with SMTP id ffacd0b85a97d-429c1b68cd3so12071f8f.1 for ; Wed, 05 Nov 2025 09:07:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1762362431; x=1762967231; 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=zDPGEALHiJj9n97uz8lWTxmttupO8bbW3KYaPlpx77g=; b=j5EYisWQ67d8B0KV1KsvwaJB31nZ1jLTUsyxImW0bIJPYe3MySyolb21OLoX1xEuOe CtPkFMWxJkrMJ7BsuFsiOE+PgjjZtevIVLveB4isJuuH4lRg+X+LObmAi599rzPiOmZG dB4CtPTfTHJvnTZlvJIhqj/Vhac913z32sAuuPd/Uui7VrTzD4FK1/0X21Ty56tykP3y vro9TYtvTRr1XTStnqzk3OOtWDf8Rl1IOvwDKXI86nCx+upoyAyzn1uJ/bs7Efl/WHiS /WkoxvE9v4hKJHbT3U3mAO6zMMYN/JntUFWWfJo56vSAS5ImjiqElig1FSKmw/mmJwtA iMoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762362432; x=1762967232; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zDPGEALHiJj9n97uz8lWTxmttupO8bbW3KYaPlpx77g=; b=KNS2L5M1PfKSfKZZ75bjmbxyEq7zsOJTx1F4NBQQdc8+upkm4fhN3oziBXvvAUtuWa /VBh7aeFtb1jnlTMjaLWXHChgZNxTs5l5Bg9AqrpVvZfcjjEPAMAhTfhlKVaf+CFDoRw OiXxw3DWsQdNsb66cNYKBnhGKtRri3OZc+EEl/9CmVaQVO++CyyDM7hfIODv/ijVlmVc q68galDFunaloYqK8LJjAwIeGcHdLjKOX74lHqmsWsO1N5R7RY2LGVBl3Z5/dE8EXCrR kCrPMxSXsV7QKjA2gLq7ksr70PRq1nbio7Wxho2CcOgrTDtAbN4Q551WXeC3z9OcDRZR 9nGQ== X-Forwarded-Encrypted: i=1; AJvYcCVeT+9KPnuI3eXuyUUGpIL1tZMYbf5VQfqcBp1gWsjzNwMuYXxAfdsTqHLveYwH/eqz0nqD01kEH5b272U=@vger.kernel.org X-Gm-Message-State: AOJu0YzWr8EkA2+mLDq0nX8e2EYC/wlNXr0u3/bZ6n1/BuPPodtkdDAp Ii6QTKlcwBhS1UF6Rri5Kt4f5C2nSX6/jT7o/+2W5Tkr/3pp7CeswpQen/KeSH39Z74= X-Gm-Gg: ASbGncv0YXySl2q9Q8HLu2yx7HUthlZ7jzgSSeAZ8AdN7dVq69kE6Zdi6f7FICOpP3n 9J2BQupBgjF1ciwFZqgj6ZFyJxESICPPtrlr/edvZ9c9fo60zp+A4DcE5FmTSTWTZwm6HDnR2Io nEzJ3+vL2OSQGuFcDDqxUJN9AscL9884JZ8TMHCPhKKst1PVyp/CeebW2oYRHb30t9mtcT+WOg7 JHmKkit77q5j88N87/1ddfZazBvwD2+JKrye771NsiG/pl2RXbbbY0eyhSvL0PwHqZdvOMi8UQC 2SpXlQ67Yrm1CbWtQZR54RFPo67Xv+4ABPvG4frOcMwMjfV/evXBwEd8csax7xoMIN8acMd0i3e qJp0jzlt56E8u3ttuC15mZ8dAdIzgalJNNF+JR9hkOsUGZHPv/x/Ev+ndiLhEg3dM9kxc55ckbz XUkwc= X-Google-Smtp-Source: AGHT+IFGFX9DslUYNk9iBEXMdGr7oaOJipOJWDtvY1Tg3EGRYJjFwA8CB5hzyW6XylUnko4CikmxTg== X-Received: by 2002:a05:6000:2f81:b0:426:f590:3cab with SMTP id ffacd0b85a97d-429e3275af0mr1981253f8f.0.1762362431350; Wed, 05 Nov 2025 09:07:11 -0800 (PST) Received: from localhost ([2a03:2880:31ff:8::]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-429dc1f9d33sm11871563f8f.36.2025.11.05.09.07.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Nov 2025 09:07:10 -0800 (PST) From: Gustavo Luiz Duarte Date: Wed, 05 Nov 2025 09:06:46 -0800 Subject: [PATCH net-next 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: <20251105-netconsole_dynamic_extradata-v1-4-142890bf4936@meta.com> References: <20251105-netconsole_dynamic_extradata-v1-0-142890bf4936@meta.com> In-Reply-To: <20251105-netconsole_dynamic_extradata-v1-0-142890bf4936@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 --- 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 8a11b3ca2763..040bae29d485 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_SYSDATA_ITEMS 4 #define MAX_PRINT_CHUNK 1000 =20 diff --git a/tools/testing/selftests/drivers/net/netcons_overflow.sh b/tool= s/testing/selftests/drivers/net/netcons_overflow.sh index 29bad56448a2..06089643b771 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