* [PATCH net-next v4 01/10] net: netconsole: remove msg_ready variable
2024-09-30 13:11 [PATCH net-next v4 00/10] net: netconsole refactoring and warning fix Breno Leitao
@ 2024-09-30 13:12 ` Breno Leitao
2024-09-30 13:12 ` [PATCH net-next v4 02/10] net: netconsole: split send_ext_msg_udp() function Breno Leitao
` (9 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Breno Leitao @ 2024-09-30 13:12 UTC (permalink / raw)
To: kuba, davem, edumazet, pabeni
Cc: thepacketgeek, horms, netdev, linux-kernel, davej, max
Variable msg_ready is useless, since it does not represent anything. Get
rid of it, using buf directly instead.
Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Simon Horman <horms@kernel.org>
---
drivers/net/netconsole.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 01cf33fa7503..03150e513cb2 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -1075,7 +1075,6 @@ static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
const char *header, *body;
int offset = 0;
int header_len, body_len;
- const char *msg_ready = msg;
const char *release;
int release_len = 0;
int userdata_len = 0;
@@ -1105,8 +1104,7 @@ static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
MAX_PRINT_CHUNK - msg_len,
"%s", userdata);
- msg_ready = buf;
- netpoll_send_udp(&nt->np, msg_ready, msg_len);
+ netpoll_send_udp(&nt->np, buf, msg_len);
return;
}
--
2.43.5
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH net-next v4 02/10] net: netconsole: split send_ext_msg_udp() function
2024-09-30 13:11 [PATCH net-next v4 00/10] net: netconsole refactoring and warning fix Breno Leitao
2024-09-30 13:12 ` [PATCH net-next v4 01/10] net: netconsole: remove msg_ready variable Breno Leitao
@ 2024-09-30 13:12 ` Breno Leitao
2024-09-30 13:12 ` [PATCH net-next v4 03/10] net: netconsole: separate fragmented message handling in send_ext_msg Breno Leitao
` (8 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Breno Leitao @ 2024-09-30 13:12 UTC (permalink / raw)
To: kuba, davem, edumazet, pabeni
Cc: thepacketgeek, horms, netdev, linux-kernel, davej, max
The send_ext_msg_udp() function has become quite large, currently
spanning 102 lines. Its complexity, along with extensive pointer and
offset manipulation, makes it difficult to read and error-prone.
The function has evolved over time, and it’s now due for a refactor.
To improve readability and maintainability, isolate the case where no
message fragmentation occurs into a separate function, into a new
send_msg_no_fragmentation() function. This scenario covers about 95% of
the messages.
Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Simon Horman <horms@kernel.org>
---
drivers/net/netconsole.c | 46 +++++++++++++++++++++++++---------------
1 file changed, 29 insertions(+), 17 deletions(-)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 03150e513cb2..d31ac47b496a 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -1058,6 +1058,32 @@ static struct notifier_block netconsole_netdev_notifier = {
.notifier_call = netconsole_netdev_event,
};
+static void send_msg_no_fragmentation(struct netconsole_target *nt,
+ const char *msg,
+ const char *userdata,
+ int msg_len,
+ int release_len)
+{
+ static char buf[MAX_PRINT_CHUNK]; /* protected by target_list_lock */
+ const char *release;
+
+ if (release_len) {
+ release = init_utsname()->release;
+
+ scnprintf(buf, MAX_PRINT_CHUNK, "%s,%s", release, msg);
+ msg_len += release_len;
+ } else {
+ memcpy(buf, msg, msg_len);
+ }
+
+ if (userdata)
+ msg_len += scnprintf(&buf[msg_len],
+ MAX_PRINT_CHUNK - msg_len,
+ "%s", userdata);
+
+ netpoll_send_udp(&nt->np, buf, msg_len);
+}
+
/**
* send_ext_msg_udp - send extended log message to target
* @nt: target to send message to
@@ -1090,23 +1116,9 @@ static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
release_len = strlen(release) + 1;
}
- if (msg_len + release_len + userdata_len <= MAX_PRINT_CHUNK) {
- /* No fragmentation needed */
- if (nt->release) {
- scnprintf(buf, MAX_PRINT_CHUNK, "%s,%s", release, msg);
- msg_len += release_len;
- } else {
- memcpy(buf, msg, msg_len);
- }
-
- if (userdata)
- msg_len += scnprintf(&buf[msg_len],
- MAX_PRINT_CHUNK - msg_len,
- "%s", userdata);
-
- netpoll_send_udp(&nt->np, buf, msg_len);
- return;
- }
+ if (msg_len + release_len + userdata_len <= MAX_PRINT_CHUNK)
+ return send_msg_no_fragmentation(nt, msg, userdata, msg_len,
+ release_len);
/* need to insert extra header fields, detect header and body */
header = msg;
--
2.43.5
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH net-next v4 03/10] net: netconsole: separate fragmented message handling in send_ext_msg
2024-09-30 13:11 [PATCH net-next v4 00/10] net: netconsole refactoring and warning fix Breno Leitao
2024-09-30 13:12 ` [PATCH net-next v4 01/10] net: netconsole: remove msg_ready variable Breno Leitao
2024-09-30 13:12 ` [PATCH net-next v4 02/10] net: netconsole: split send_ext_msg_udp() function Breno Leitao
@ 2024-09-30 13:12 ` Breno Leitao
2024-09-30 13:12 ` [PATCH net-next v4 04/10] net: netconsole: rename body to msg_body Breno Leitao
` (7 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Breno Leitao @ 2024-09-30 13:12 UTC (permalink / raw)
To: kuba, davem, edumazet, pabeni
Cc: thepacketgeek, horms, netdev, linux-kernel, davej, max
Following the previous change, where the non-fragmented case was moved
to its own function, this update introduces a new function called
send_msg_fragmented to specifically manage scenarios where message
fragmentation is required.
Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Simon Horman <horms@kernel.org>
---
drivers/net/netconsole.c | 76 +++++++++++++++++++++++++---------------
1 file changed, 48 insertions(+), 28 deletions(-)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index d31ac47b496a..6cd0a9f25db3 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -1084,42 +1084,23 @@ static void send_msg_no_fragmentation(struct netconsole_target *nt,
netpoll_send_udp(&nt->np, buf, msg_len);
}
-/**
- * send_ext_msg_udp - send extended log message to target
- * @nt: target to send message to
- * @msg: extended log message to send
- * @msg_len: length of message
- *
- * Transfer extended log @msg to @nt. If @msg is longer than
- * MAX_PRINT_CHUNK, it'll be split and transmitted in multiple chunks with
- * ncfrag header field added to identify them.
- */
-static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
- int msg_len)
+static void send_msg_fragmented(struct netconsole_target *nt,
+ const char *msg,
+ const char *userdata,
+ int msg_len,
+ int release_len)
{
static char buf[MAX_PRINT_CHUNK]; /* protected by target_list_lock */
+ int offset = 0, userdata_len = 0;
const char *header, *body;
- int offset = 0;
int header_len, body_len;
const char *release;
- int release_len = 0;
- int userdata_len = 0;
- char *userdata = NULL;
#ifdef CONFIG_NETCONSOLE_DYNAMIC
- userdata = nt->userdata_complete;
- userdata_len = nt->userdata_length;
+ if (userdata)
+ userdata_len = nt->userdata_length;
#endif
- if (nt->release) {
- release = init_utsname()->release;
- release_len = strlen(release) + 1;
- }
-
- if (msg_len + release_len + userdata_len <= MAX_PRINT_CHUNK)
- return send_msg_no_fragmentation(nt, msg, userdata, msg_len,
- release_len);
-
/* need to insert extra header fields, detect header and body */
header = msg;
body = memchr(msg, ';', msg_len);
@@ -1134,11 +1115,18 @@ static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
* Transfer multiple chunks with the following extra header.
* "ncfrag=<byte-offset>/<total-bytes>"
*/
- if (nt->release)
+ if (release_len) {
+ release = init_utsname()->release;
scnprintf(buf, MAX_PRINT_CHUNK, "%s,", release);
+ }
+
+ /* Copy the header into the buffer */
memcpy(buf + release_len, header, header_len);
header_len += release_len;
+ /* for now on, the header will be persisted, and the body
+ * will be replaced
+ */
while (offset < body_len + userdata_len) {
int this_header = header_len;
int this_offset = 0;
@@ -1184,6 +1172,38 @@ static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
}
}
+/**
+ * send_ext_msg_udp - send extended log message to target
+ * @nt: target to send message to
+ * @msg: extended log message to send
+ * @msg_len: length of message
+ *
+ * Transfer extended log @msg to @nt. If @msg is longer than
+ * MAX_PRINT_CHUNK, it'll be split and transmitted in multiple chunks with
+ * ncfrag header field added to identify them.
+ */
+static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
+ int msg_len)
+{
+ char *userdata = NULL;
+ int userdata_len = 0;
+ int release_len = 0;
+
+#ifdef CONFIG_NETCONSOLE_DYNAMIC
+ userdata = nt->userdata_complete;
+ userdata_len = nt->userdata_length;
+#endif
+
+ if (nt->release)
+ release_len = strlen(init_utsname()->release) + 1;
+
+ if (msg_len + release_len + userdata_len <= MAX_PRINT_CHUNK)
+ return send_msg_no_fragmentation(nt, msg, userdata, msg_len,
+ release_len);
+
+ return send_msg_fragmented(nt, msg, userdata, msg_len, release_len);
+}
+
static void write_ext_msg(struct console *con, const char *msg,
unsigned int len)
{
--
2.43.5
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH net-next v4 04/10] net: netconsole: rename body to msg_body
2024-09-30 13:11 [PATCH net-next v4 00/10] net: netconsole refactoring and warning fix Breno Leitao
` (2 preceding siblings ...)
2024-09-30 13:12 ` [PATCH net-next v4 03/10] net: netconsole: separate fragmented message handling in send_ext_msg Breno Leitao
@ 2024-09-30 13:12 ` Breno Leitao
2024-09-30 13:12 ` [PATCH net-next v4 05/10] net: netconsole: introduce variable to track body length Breno Leitao
` (6 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Breno Leitao @ 2024-09-30 13:12 UTC (permalink / raw)
To: kuba, davem, edumazet, pabeni
Cc: thepacketgeek, horms, netdev, linux-kernel, davej, max
With the introduction of the userdata concept, the term body has become
ambiguous and less intuitive.
To improve clarity, body is renamed to msg_body, making it clear that
the body is not the only content following the header.
In an upcoming patch, the term body_len will also be revised for further
clarity.
The current packet structure is as follows:
release, header, body, [msg_body + userdata]
Here, [msg_body + userdata] collectively forms what is currently
referred to as "body." This renaming helps to distinguish and better
understand each component of the packet.
Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Simon Horman <horms@kernel.org>
---
drivers/net/netconsole.c | 41 ++++++++++++++++++++--------------------
1 file changed, 21 insertions(+), 20 deletions(-)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 6cd0a9f25db3..da42dffa6296 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -1092,8 +1092,8 @@ static void send_msg_fragmented(struct netconsole_target *nt,
{
static char buf[MAX_PRINT_CHUNK]; /* protected by target_list_lock */
int offset = 0, userdata_len = 0;
- const char *header, *body;
- int header_len, body_len;
+ const char *header, *msgbody;
+ int header_len, msgbody_len;
const char *release;
#ifdef CONFIG_NETCONSOLE_DYNAMIC
@@ -1101,15 +1101,15 @@ static void send_msg_fragmented(struct netconsole_target *nt,
userdata_len = nt->userdata_length;
#endif
- /* need to insert extra header fields, detect header and body */
+ /* need to insert extra header fields, detect header and msgbody */
header = msg;
- body = memchr(msg, ';', msg_len);
- if (WARN_ON_ONCE(!body))
+ msgbody = memchr(msg, ';', msg_len);
+ if (WARN_ON_ONCE(!msgbody))
return;
- header_len = body - header;
- body_len = msg_len - header_len - 1;
- body++;
+ header_len = msgbody - header;
+ msgbody_len = msg_len - header_len - 1;
+ msgbody++;
/*
* Transfer multiple chunks with the following extra header.
@@ -1124,10 +1124,10 @@ static void send_msg_fragmented(struct netconsole_target *nt,
memcpy(buf + release_len, header, header_len);
header_len += release_len;
- /* for now on, the header will be persisted, and the body
+ /* for now on, the header will be persisted, and the msgbody
* will be replaced
*/
- while (offset < body_len + userdata_len) {
+ while (offset < msgbody_len + userdata_len) {
int this_header = header_len;
int this_offset = 0;
int this_chunk = 0;
@@ -1135,23 +1135,24 @@ static void send_msg_fragmented(struct netconsole_target *nt,
this_header += scnprintf(buf + this_header,
sizeof(buf) - this_header,
",ncfrag=%d/%d;", offset,
- body_len + userdata_len);
+ msgbody_len + userdata_len);
- /* Not all body data has been written yet */
- if (offset < body_len) {
- this_chunk = min(body_len - offset,
+ /* Not all msgbody data has been written yet */
+ if (offset < msgbody_len) {
+ this_chunk = min(msgbody_len - offset,
MAX_PRINT_CHUNK - this_header);
if (WARN_ON_ONCE(this_chunk <= 0))
return;
- memcpy(buf + this_header, body + offset, this_chunk);
+ memcpy(buf + this_header, msgbody + offset, this_chunk);
this_offset += this_chunk;
}
- /* Body is fully written and there is pending userdata to write,
- * append userdata in this chunk
+
+ /* Msg body is fully written and there is pending userdata to
+ * write, append userdata in this chunk
*/
- if (offset + this_offset >= body_len &&
- offset + this_offset < userdata_len + body_len) {
- int sent_userdata = (offset + this_offset) - body_len;
+ if (offset + this_offset >= msgbody_len &&
+ offset + this_offset < userdata_len + msgbody_len) {
+ int sent_userdata = (offset + this_offset) - msgbody_len;
int preceding_bytes = this_chunk + this_header;
if (WARN_ON_ONCE(sent_userdata < 0))
--
2.43.5
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH net-next v4 05/10] net: netconsole: introduce variable to track body length
2024-09-30 13:11 [PATCH net-next v4 00/10] net: netconsole refactoring and warning fix Breno Leitao
` (3 preceding siblings ...)
2024-09-30 13:12 ` [PATCH net-next v4 04/10] net: netconsole: rename body to msg_body Breno Leitao
@ 2024-09-30 13:12 ` Breno Leitao
2024-09-30 13:12 ` [PATCH net-next v4 06/10] net: netconsole: track explicitly if msgbody was written to buffer Breno Leitao
` (5 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Breno Leitao @ 2024-09-30 13:12 UTC (permalink / raw)
To: kuba, davem, edumazet, pabeni
Cc: thepacketgeek, horms, netdev, linux-kernel, davej, max
This new variable tracks the total length of the data to be sent,
encompassing both the message body (msgbody) and userdata, which is
collectively called body.
By explicitly defining body_len, the code becomes clearer and easier to
reason about, simplifying offset calculations and improving overall
readability of the function.
Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Simon Horman <horms@kernel.org>
---
drivers/net/netconsole.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index da42dffa6296..eacb1bdb0c30 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -1090,10 +1090,10 @@ static void send_msg_fragmented(struct netconsole_target *nt,
int msg_len,
int release_len)
{
+ int header_len, msgbody_len, body_len;
static char buf[MAX_PRINT_CHUNK]; /* protected by target_list_lock */
int offset = 0, userdata_len = 0;
const char *header, *msgbody;
- int header_len, msgbody_len;
const char *release;
#ifdef CONFIG_NETCONSOLE_DYNAMIC
@@ -1124,10 +1124,11 @@ static void send_msg_fragmented(struct netconsole_target *nt,
memcpy(buf + release_len, header, header_len);
header_len += release_len;
+ body_len = msgbody_len + userdata_len;
/* for now on, the header will be persisted, and the msgbody
* will be replaced
*/
- while (offset < msgbody_len + userdata_len) {
+ while (offset < body_len) {
int this_header = header_len;
int this_offset = 0;
int this_chunk = 0;
@@ -1135,7 +1136,7 @@ static void send_msg_fragmented(struct netconsole_target *nt,
this_header += scnprintf(buf + this_header,
sizeof(buf) - this_header,
",ncfrag=%d/%d;", offset,
- msgbody_len + userdata_len);
+ body_len);
/* Not all msgbody data has been written yet */
if (offset < msgbody_len) {
@@ -1151,7 +1152,7 @@ static void send_msg_fragmented(struct netconsole_target *nt,
* write, append userdata in this chunk
*/
if (offset + this_offset >= msgbody_len &&
- offset + this_offset < userdata_len + msgbody_len) {
+ offset + this_offset < body_len) {
int sent_userdata = (offset + this_offset) - msgbody_len;
int preceding_bytes = this_chunk + this_header;
--
2.43.5
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH net-next v4 06/10] net: netconsole: track explicitly if msgbody was written to buffer
2024-09-30 13:11 [PATCH net-next v4 00/10] net: netconsole refactoring and warning fix Breno Leitao
` (4 preceding siblings ...)
2024-09-30 13:12 ` [PATCH net-next v4 05/10] net: netconsole: introduce variable to track body length Breno Leitao
@ 2024-09-30 13:12 ` Breno Leitao
2024-09-30 13:12 ` [PATCH net-next v4 07/10] net: netconsole: extract release appending into separate function Breno Leitao
` (4 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Breno Leitao @ 2024-09-30 13:12 UTC (permalink / raw)
To: kuba, davem, edumazet, pabeni
Cc: thepacketgeek, horms, netdev, linux-kernel, davej, max
The current check to determine if the message body was fully sent is
difficult to follow. To improve clarity, introduce a variable that
explicitly tracks whether the message body (msgbody) has been completely
sent, indicating when it's time to begin sending userdata.
Additionally, add comments to make the code more understandable for
others who may work with it.
Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Simon Horman <horms@kernel.org>
---
drivers/net/netconsole.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index eacb1bdb0c30..4e3b68a2c7c6 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -1130,6 +1130,7 @@ static void send_msg_fragmented(struct netconsole_target *nt,
*/
while (offset < body_len) {
int this_header = header_len;
+ bool msgbody_written = false;
int this_offset = 0;
int this_chunk = 0;
@@ -1148,12 +1149,21 @@ static void send_msg_fragmented(struct netconsole_target *nt,
this_offset += this_chunk;
}
+ /* msgbody was finally written, either in the previous
+ * messages and/or in the current buf. Time to write
+ * the userdata.
+ */
+ msgbody_written |= offset + this_offset >= msgbody_len;
+
/* Msg body is fully written and there is pending userdata to
* write, append userdata in this chunk
*/
- if (offset + this_offset >= msgbody_len &&
- offset + this_offset < body_len) {
+ if (msgbody_written && offset + this_offset < body_len) {
+ /* Track how much user data was already sent. First
+ * time here, sent_userdata is zero
+ */
int sent_userdata = (offset + this_offset) - msgbody_len;
+ /* offset of bytes used in current buf */
int preceding_bytes = this_chunk + this_header;
if (WARN_ON_ONCE(sent_userdata < 0))
--
2.43.5
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH net-next v4 07/10] net: netconsole: extract release appending into separate function
2024-09-30 13:11 [PATCH net-next v4 00/10] net: netconsole refactoring and warning fix Breno Leitao
` (5 preceding siblings ...)
2024-09-30 13:12 ` [PATCH net-next v4 06/10] net: netconsole: track explicitly if msgbody was written to buffer Breno Leitao
@ 2024-09-30 13:12 ` Breno Leitao
2024-09-30 13:12 ` [PATCH net-next v4 08/10] net: netconsole: do not pass userdata up to the tail Breno Leitao
` (3 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Breno Leitao @ 2024-09-30 13:12 UTC (permalink / raw)
To: kuba, davem, edumazet, pabeni
Cc: thepacketgeek, horms, netdev, linux-kernel, davej, max
Refactor the code by extracting the logic for appending the
release into the buffer into a separate function.
The goal is to reduce the size of send_msg_fragmented() and improve
code readability.
Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Simon Horman <horms@kernel.org>
---
drivers/net/netconsole.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 4e3b68a2c7c6..4a20bcab0b02 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -1084,6 +1084,14 @@ static void send_msg_no_fragmentation(struct netconsole_target *nt,
netpoll_send_udp(&nt->np, buf, msg_len);
}
+static void append_release(char *buf)
+{
+ const char *release;
+
+ release = init_utsname()->release;
+ scnprintf(buf, MAX_PRINT_CHUNK, "%s,", release);
+}
+
static void send_msg_fragmented(struct netconsole_target *nt,
const char *msg,
const char *userdata,
@@ -1094,7 +1102,6 @@ static void send_msg_fragmented(struct netconsole_target *nt,
static char buf[MAX_PRINT_CHUNK]; /* protected by target_list_lock */
int offset = 0, userdata_len = 0;
const char *header, *msgbody;
- const char *release;
#ifdef CONFIG_NETCONSOLE_DYNAMIC
if (userdata)
@@ -1115,10 +1122,8 @@ static void send_msg_fragmented(struct netconsole_target *nt,
* Transfer multiple chunks with the following extra header.
* "ncfrag=<byte-offset>/<total-bytes>"
*/
- if (release_len) {
- release = init_utsname()->release;
- scnprintf(buf, MAX_PRINT_CHUNK, "%s,", release);
- }
+ if (release_len)
+ append_release(buf);
/* Copy the header into the buffer */
memcpy(buf + release_len, header, header_len);
--
2.43.5
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH net-next v4 08/10] net: netconsole: do not pass userdata up to the tail
2024-09-30 13:11 [PATCH net-next v4 00/10] net: netconsole refactoring and warning fix Breno Leitao
` (6 preceding siblings ...)
2024-09-30 13:12 ` [PATCH net-next v4 07/10] net: netconsole: extract release appending into separate function Breno Leitao
@ 2024-09-30 13:12 ` Breno Leitao
2024-09-30 13:12 ` [PATCH net-next v4 09/10] net: netconsole: split send_msg_fragmented Breno Leitao
` (2 subsequent siblings)
10 siblings, 0 replies; 15+ messages in thread
From: Breno Leitao @ 2024-09-30 13:12 UTC (permalink / raw)
To: kuba, davem, edumazet, pabeni
Cc: thepacketgeek, horms, netdev, linux-kernel, davej, max
Do not pass userdata to send_msg_fragmented, since we can get it later.
This will be more useful in the next patch, where send_msg_fragmented()
will be split even more, and userdata is only necessary in the last
function.
Suggested-by: Simon Horman <horms@kernel.org>
Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Simon Horman <horms@kernel.org>
---
drivers/net/netconsole.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 4a20bcab0b02..7266d4232d5d 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -1060,13 +1060,17 @@ static struct notifier_block netconsole_netdev_notifier = {
static void send_msg_no_fragmentation(struct netconsole_target *nt,
const char *msg,
- const char *userdata,
int msg_len,
int release_len)
{
static char buf[MAX_PRINT_CHUNK]; /* protected by target_list_lock */
+ const char *userdata = NULL;
const char *release;
+#ifdef CONFIG_NETCONSOLE_DYNAMIC
+ userdata = nt->userdata_complete;
+#endif
+
if (release_len) {
release = init_utsname()->release;
@@ -1094,7 +1098,6 @@ static void append_release(char *buf)
static void send_msg_fragmented(struct netconsole_target *nt,
const char *msg,
- const char *userdata,
int msg_len,
int release_len)
{
@@ -1102,10 +1105,11 @@ static void send_msg_fragmented(struct netconsole_target *nt,
static char buf[MAX_PRINT_CHUNK]; /* protected by target_list_lock */
int offset = 0, userdata_len = 0;
const char *header, *msgbody;
+ const char *userdata = NULL;
#ifdef CONFIG_NETCONSOLE_DYNAMIC
- if (userdata)
- userdata_len = nt->userdata_length;
+ userdata = nt->userdata_complete;
+ userdata_len = nt->userdata_length;
#endif
/* need to insert extra header fields, detect header and msgbody */
@@ -1202,12 +1206,10 @@ static void send_msg_fragmented(struct netconsole_target *nt,
static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
int msg_len)
{
- char *userdata = NULL;
int userdata_len = 0;
int release_len = 0;
#ifdef CONFIG_NETCONSOLE_DYNAMIC
- userdata = nt->userdata_complete;
userdata_len = nt->userdata_length;
#endif
@@ -1215,10 +1217,9 @@ static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
release_len = strlen(init_utsname()->release) + 1;
if (msg_len + release_len + userdata_len <= MAX_PRINT_CHUNK)
- return send_msg_no_fragmentation(nt, msg, userdata, msg_len,
- release_len);
+ return send_msg_no_fragmentation(nt, msg, msg_len, release_len);
- return send_msg_fragmented(nt, msg, userdata, msg_len, release_len);
+ return send_msg_fragmented(nt, msg, msg_len, release_len);
}
static void write_ext_msg(struct console *con, const char *msg,
--
2.43.5
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH net-next v4 09/10] net: netconsole: split send_msg_fragmented
2024-09-30 13:11 [PATCH net-next v4 00/10] net: netconsole refactoring and warning fix Breno Leitao
` (7 preceding siblings ...)
2024-09-30 13:12 ` [PATCH net-next v4 08/10] net: netconsole: do not pass userdata up to the tail Breno Leitao
@ 2024-09-30 13:12 ` Breno Leitao
2024-09-30 13:12 ` [PATCH net-next v4 10/10] net: netconsole: fix wrong warning Breno Leitao
2024-10-04 0:29 ` [PATCH net-next v4 00/10] net: netconsole refactoring and warning fix Jakub Kicinski
10 siblings, 0 replies; 15+ messages in thread
From: Breno Leitao @ 2024-09-30 13:12 UTC (permalink / raw)
To: kuba, davem, edumazet, pabeni
Cc: thepacketgeek, horms, netdev, linux-kernel, davej, max
Refactor the send_msg_fragmented() function by extracting the logic for
sending the message body into a new function called
send_fragmented_body().
Now, send_msg_fragmented() handles appending the release and header, and
then delegates the task of breaking up the body and sending the
fragments to send_fragmented_body().
This is the final flow now:
When send_ext_msg_udp() is called to send a message, it will:
- call send_msg_no_fragmentation() if no fragmentation is needed
or
- call send_msg_fragmented() if fragmentation is needed
* send_msg_fragmented() appends the header to the buffer, which is
be persisted until the function returns
* call send_fragmented_body() to iterate and populate the body of
the message. It will not touch the header, and it will only
replace the body, writing the msgbody and/or userdata.
Also add some comment to make the code easier to review.
Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Simon Horman <horms@kernel.org>
---
drivers/net/netconsole.c | 81 +++++++++++++++++++++++++---------------
1 file changed, 50 insertions(+), 31 deletions(-)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 7266d4232d5d..f724511cf567 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -1096,46 +1096,30 @@ static void append_release(char *buf)
scnprintf(buf, MAX_PRINT_CHUNK, "%s,", release);
}
-static void send_msg_fragmented(struct netconsole_target *nt,
- const char *msg,
- int msg_len,
- int release_len)
+static void send_fragmented_body(struct netconsole_target *nt, char *buf,
+ const char *msgbody, int header_len,
+ int msgbody_len)
{
- int header_len, msgbody_len, body_len;
- static char buf[MAX_PRINT_CHUNK]; /* protected by target_list_lock */
- int offset = 0, userdata_len = 0;
- const char *header, *msgbody;
const char *userdata = NULL;
+ int body_len, offset = 0;
+ int userdata_len = 0;
#ifdef CONFIG_NETCONSOLE_DYNAMIC
userdata = nt->userdata_complete;
userdata_len = nt->userdata_length;
#endif
- /* need to insert extra header fields, detect header and msgbody */
- header = msg;
- msgbody = memchr(msg, ';', msg_len);
- if (WARN_ON_ONCE(!msgbody))
- return;
-
- header_len = msgbody - header;
- msgbody_len = msg_len - header_len - 1;
- msgbody++;
-
- /*
- * Transfer multiple chunks with the following extra header.
- * "ncfrag=<byte-offset>/<total-bytes>"
+ /* 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
*/
- if (release_len)
- append_release(buf);
-
- /* Copy the header into the buffer */
- memcpy(buf + release_len, header, header_len);
- header_len += release_len;
-
body_len = msgbody_len + userdata_len;
- /* for now on, the header will be persisted, and the msgbody
- * will be replaced
+
+ /* 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 userdata. 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.
*/
while (offset < body_len) {
int this_header = header_len;
@@ -1144,7 +1128,7 @@ static void send_msg_fragmented(struct netconsole_target *nt,
int this_chunk = 0;
this_header += scnprintf(buf + this_header,
- sizeof(buf) - this_header,
+ MAX_PRINT_CHUNK - this_header,
",ncfrag=%d/%d;", offset,
body_len);
@@ -1193,6 +1177,41 @@ static void send_msg_fragmented(struct netconsole_target *nt,
}
}
+static void send_msg_fragmented(struct netconsole_target *nt,
+ const char *msg,
+ int msg_len,
+ int release_len)
+{
+ static char buf[MAX_PRINT_CHUNK]; /* protected by target_list_lock */
+ int header_len, msgbody_len;
+ const char *msgbody;
+
+ /* need to insert extra header fields, detect header and msgbody */
+ msgbody = memchr(msg, ';', msg_len);
+ if (WARN_ON_ONCE(!msgbody))
+ return;
+
+ header_len = msgbody - msg;
+ msgbody_len = msg_len - header_len - 1;
+ msgbody++;
+
+ /*
+ * Transfer multiple chunks with the following extra header.
+ * "ncfrag=<byte-offset>/<total-bytes>"
+ */
+ if (release_len)
+ append_release(buf);
+
+ /* Copy the header into the buffer */
+ memcpy(buf + release_len, msg, header_len);
+ header_len += release_len;
+
+ /* for now on, the header will be persisted, and the msgbody
+ * will be replaced
+ */
+ send_fragmented_body(nt, buf, msgbody, header_len, msgbody_len);
+}
+
/**
* send_ext_msg_udp - send extended log message to target
* @nt: target to send message to
--
2.43.5
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH net-next v4 10/10] net: netconsole: fix wrong warning
2024-09-30 13:11 [PATCH net-next v4 00/10] net: netconsole refactoring and warning fix Breno Leitao
` (8 preceding siblings ...)
2024-09-30 13:12 ` [PATCH net-next v4 09/10] net: netconsole: split send_msg_fragmented Breno Leitao
@ 2024-09-30 13:12 ` Breno Leitao
2024-10-01 8:33 ` Simon Horman
2024-10-04 0:29 ` [PATCH net-next v4 00/10] net: netconsole refactoring and warning fix Jakub Kicinski
10 siblings, 1 reply; 15+ messages in thread
From: Breno Leitao @ 2024-09-30 13:12 UTC (permalink / raw)
To: kuba, davem, edumazet, pabeni, Matthew Wood
Cc: horms, netdev, linux-kernel, davej, max
A warning is triggered when there is insufficient space in the buffer
for userdata. However, this is not an issue since userdata will be sent
in the next iteration.
Current warning message:
------------[ cut here ]------------
WARNING: CPU: 13 PID: 3013042 at drivers/net/netconsole.c:1122 write_ext_msg+0x3b6/0x3d0
? write_ext_msg+0x3b6/0x3d0
console_flush_all+0x1e9/0x330
The code incorrectly issues a warning when this_chunk is zero, which is
a valid scenario. The warning should only be triggered when this_chunk
is negative.
Signed-off-by: Breno Leitao <leitao@debian.org>
Fixes: 1ec9daf95093 ("net: netconsole: append userdata to fragmented netconsole messages")
---
drivers/net/netconsole.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index f724511cf567..4ea44a2f48f7 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -1164,8 +1164,14 @@ static void send_fragmented_body(struct netconsole_target *nt, char *buf,
this_chunk = min(userdata_len - sent_userdata,
MAX_PRINT_CHUNK - preceding_bytes);
- if (WARN_ON_ONCE(this_chunk <= 0))
+ 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, userdata will be sent in the next
+ * iteration
+ */
return;
+
memcpy(buf + this_header + this_offset,
userdata + sent_userdata,
this_chunk);
--
2.43.5
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH net-next v4 10/10] net: netconsole: fix wrong warning
2024-09-30 13:12 ` [PATCH net-next v4 10/10] net: netconsole: fix wrong warning Breno Leitao
@ 2024-10-01 8:33 ` Simon Horman
0 siblings, 0 replies; 15+ messages in thread
From: Simon Horman @ 2024-10-01 8:33 UTC (permalink / raw)
To: Breno Leitao
Cc: kuba, davem, edumazet, pabeni, Matthew Wood, netdev, linux-kernel,
davej, max
On Mon, Sep 30, 2024 at 06:12:09AM -0700, Breno Leitao wrote:
> A warning is triggered when there is insufficient space in the buffer
> for userdata. However, this is not an issue since userdata will be sent
> in the next iteration.
>
> Current warning message:
>
> ------------[ cut here ]------------
> WARNING: CPU: 13 PID: 3013042 at drivers/net/netconsole.c:1122 write_ext_msg+0x3b6/0x3d0
> ? write_ext_msg+0x3b6/0x3d0
> console_flush_all+0x1e9/0x330
>
> The code incorrectly issues a warning when this_chunk is zero, which is
> a valid scenario. The warning should only be triggered when this_chunk
> is negative.
>
> Signed-off-by: Breno Leitao <leitao@debian.org>
> Fixes: 1ec9daf95093 ("net: netconsole: append userdata to fragmented netconsole messages")
Reviewed-by: Simon Horman <horms@kernel.org>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next v4 00/10] net: netconsole refactoring and warning fix
2024-09-30 13:11 [PATCH net-next v4 00/10] net: netconsole refactoring and warning fix Breno Leitao
` (9 preceding siblings ...)
2024-09-30 13:12 ` [PATCH net-next v4 10/10] net: netconsole: fix wrong warning Breno Leitao
@ 2024-10-04 0:29 ` Jakub Kicinski
2024-10-04 8:50 ` Breno Leitao
10 siblings, 1 reply; 15+ messages in thread
From: Jakub Kicinski @ 2024-10-04 0:29 UTC (permalink / raw)
To: Breno Leitao
Cc: davem, edumazet, pabeni, thepacketgeek, horms, netdev,
linux-kernel, davej, max
On Mon, 30 Sep 2024 06:11:59 -0700 Breno Leitao wrote:
> To address these issues, the following steps were taken:
>
> * Breaking down write_ext_msg() into smaller functions with clear scopes
> * Improving readability and reasoning about the code
> * Simplifying and clarifying naming conventions
>
> Warning Fix
> -----------
>
> The warning occurred when there was insufficient buffer space to append
> userdata. While this scenario is acceptable (as userdata can be sent in a
> separate packet later), the kernel was incorrectly raising a warning. A
> one-line fix has been implemented to resolve this issue.
>
> A self-test was developed to write messages of every possible length
> This test will be submitted in a separate patchset
Makes sense in general, but why isn't the fix sent to net first,
and then once the trees converge (follow Thursday) we can apply
the refactoring and improvements on top?
The false positive warning went into 6.9 if I'm checking correctly.
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH net-next v4 00/10] net: netconsole refactoring and warning fix
2024-10-04 0:29 ` [PATCH net-next v4 00/10] net: netconsole refactoring and warning fix Jakub Kicinski
@ 2024-10-04 8:50 ` Breno Leitao
2024-10-04 14:30 ` Jakub Kicinski
0 siblings, 1 reply; 15+ messages in thread
From: Breno Leitao @ 2024-10-04 8:50 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, edumazet, pabeni, thepacketgeek, horms, netdev,
linux-kernel, davej, max
On Thu, Oct 03, 2024 at 05:29:50PM -0700, Jakub Kicinski wrote:
> On Mon, 30 Sep 2024 06:11:59 -0700 Breno Leitao wrote:
> > To address these issues, the following steps were taken:
> >
> > * Breaking down write_ext_msg() into smaller functions with clear scopes
> > * Improving readability and reasoning about the code
> > * Simplifying and clarifying naming conventions
> >
> > Warning Fix
> > -----------
> >
> > The warning occurred when there was insufficient buffer space to append
> > userdata. While this scenario is acceptable (as userdata can be sent in a
> > separate packet later), the kernel was incorrectly raising a warning. A
> > one-line fix has been implemented to resolve this issue.
> >
> > A self-test was developed to write messages of every possible length
> > This test will be submitted in a separate patchset
>
> Makes sense in general, but why isn't the fix sent to net first,
> and then once the trees converge (follow Thursday) we can apply
> the refactoring and improvements on top?
>
> The false positive warning went into 6.9 if I'm checking correctly.
Correct. I probably should have separated the fix from the refactor.
For context, I was pursuing the warning, and the code was hard to read,
so, I was refactoring the code while narrowing down the warning.
But you are correct, the warning is in 6.9+ kernels. But, keep in mind
that the warning is very hard to trigger, basically the length of userdata
and the message needs to be certain size to trigger it.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next v4 00/10] net: netconsole refactoring and warning fix
2024-10-04 8:50 ` Breno Leitao
@ 2024-10-04 14:30 ` Jakub Kicinski
0 siblings, 0 replies; 15+ messages in thread
From: Jakub Kicinski @ 2024-10-04 14:30 UTC (permalink / raw)
To: Breno Leitao
Cc: davem, edumazet, pabeni, thepacketgeek, horms, netdev,
linux-kernel, davej, max
On Fri, 4 Oct 2024 01:50:13 -0700 Breno Leitao wrote:
> > Makes sense in general, but why isn't the fix sent to net first,
> > and then once the trees converge (follow Thursday) we can apply
> > the refactoring and improvements on top?
> >
> > The false positive warning went into 6.9 if I'm checking correctly.
>
> Correct. I probably should have separated the fix from the refactor.
>
> For context, I was pursuing the warning, and the code was hard to read,
> so, I was refactoring the code while narrowing down the warning.
>
> But you are correct, the warning is in 6.9+ kernels. But, keep in mind
> that the warning is very hard to trigger, basically the length of userdata
> and the message needs to be certain size to trigger it.
Understood, and to be honest it's a bit of an efficiency thing on
maintainer side - we try to avoid shades of gray as much as possible
because debates on what is and isn't a fix can consume a ton of time.
So in networking we push people to send the fixes for net, even if
triggering the problem isn't very likely.
^ permalink raw reply [flat|nested] 15+ messages in thread