[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240824215130.2134153-2-max@kutsevol.com>
Date: Sat, 24 Aug 2024 14:50:24 -0700
From: Maksym Kutsevol <max@...sevol.com>
To: "David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
Breno Leitao <leitao@...ian.org>,
Maksym Kutsevol <max@...sevol.com>
Cc: netdev@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: [PATCH 2/2] netcons: Add udp send fail statistics to netconsole
Enhance observability of netconsole. UDP sends can fail. Start tracking at
least two failure possibilities: ENOMEM and NET_XMIT_DROP for every target.
Stats are exposed via an additional attribute in CONFIGFS.
The exposed statistics allows easier debugging of cases when netconsole
messages were not seen by receivers, eliminating the guesswork if the
sender thinks that messages in question were sent out.
Stats are not reset on enable/disable/change remote ip/etc, they
belong to the netcons target itself.
Signed-off-by: Maksym Kutsevol <max@...sevol.com>
---
Documentation/networking/netconsole.rst | 1 +
drivers/net/netconsole.c | 54 +++++++++++++++++++++++--
2 files changed, 52 insertions(+), 3 deletions(-)
diff --git a/Documentation/networking/netconsole.rst b/Documentation/networking/netconsole.rst
index d55c2a22ec7a..733d4a93878e 100644
--- a/Documentation/networking/netconsole.rst
+++ b/Documentation/networking/netconsole.rst
@@ -135,6 +135,7 @@ The interface exposes these parameters of a netconsole target to userspace:
remote_ip Remote agent's IP address (read-write)
local_mac Local interface's MAC address (read-only)
remote_mac Remote agent's MAC address (read-write)
+ stats Send error stats (read-only)
============== ================================= ============
The "enabled" attribute is also used to control whether the parameters of
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 9c09293b5258..45c07ec7842d 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -82,6 +82,13 @@ static DEFINE_SPINLOCK(target_list_lock);
*/
static struct console netconsole_ext;
+#ifdef CONFIG_NETCONSOLE_DYNAMIC
+struct netconsole_target_stats {
+ size_t xmit_drop_count;
+ size_t enomem_count;
+};
+#endif
+
/**
* struct netconsole_target - Represents a configured netconsole target.
* @list: Links this target into the target_list.
@@ -89,6 +96,7 @@ static struct console netconsole_ext;
* @userdata_group: Links to the userdata configfs hierarchy
* @userdata_complete: Cached, formatted string of append
* @userdata_length: String length of userdata_complete
+ * @stats: UDP send stats for the target. Used for debugging.
* @enabled: On / off knob to enable / disable target.
* Visible from userspace (read-write).
* We maintain a strict 1:1 correspondence between this and
@@ -115,6 +123,7 @@ struct netconsole_target {
struct config_group userdata_group;
char userdata_complete[MAX_USERDATA_ENTRY_LENGTH * MAX_USERDATA_ITEMS];
size_t userdata_length;
+ struct netconsole_target_stats stats;
#endif
bool enabled;
bool extended;
@@ -227,6 +236,7 @@ static struct netconsole_target *alloc_and_init(void)
* | remote_ip
* | local_mac
* | remote_mac
+ * | stats
* | userdata/
* | <key>/
* | value
@@ -323,6 +333,14 @@ static ssize_t remote_mac_show(struct config_item *item, char *buf)
return sysfs_emit(buf, "%pM\n", to_target(item)->np.remote_mac);
}
+static ssize_t stats_show(struct config_item *item, char *buf)
+{
+ struct netconsole_target *nt = to_target(item);
+
+ return sysfs_emit(buf, "xmit_drop: %lu enomem: %lu\n",
+ nt->stats.xmit_drop_count, nt->stats.enomem_count);
+}
+
/*
* This one is special -- targets created through the configfs interface
* are not enabled (and the corresponding netpoll activated) by default.
@@ -795,6 +813,7 @@ CONFIGFS_ATTR(, remote_ip);
CONFIGFS_ATTR_RO(, local_mac);
CONFIGFS_ATTR(, remote_mac);
CONFIGFS_ATTR(, release);
+CONFIGFS_ATTR_RO(, stats);
static struct configfs_attribute *netconsole_target_attrs[] = {
&attr_enabled,
@@ -807,6 +826,7 @@ static struct configfs_attribute *netconsole_target_attrs[] = {
&attr_remote_ip,
&attr_local_mac,
&attr_remote_mac,
+ &attr_stats,
NULL,
};
@@ -1015,6 +1035,25 @@ static struct notifier_block netconsole_netdev_notifier = {
.notifier_call = netconsole_netdev_event,
};
+/**
+ * count_udp_send_stats - Classify netpoll_send_udp result and count errors.
+ * @nt: target that was sent to
+ * @result: result of netpoll_send_udp
+ *
+ * Takes the result of netpoll_send_udp and classifies the type of error that
+ * occurred. Increments statistics in nt->stats accordingly.
+ */
+static void count_udp_send_stats(struct netconsole_target *nt, int result)
+{
+#ifdef CONFIG_NETCONSOLE_DYNAMIC
+ if (result == NET_XMIT_DROP) {
+ nt->stats.xmit_drop_count++;
+ } else if (result == -ENOMEM) {
+ nt->stats.enomem_count++;
+ };
+#endif
+}
+
/**
* send_ext_msg_udp - send extended log message to target
* @nt: target to send message to
@@ -1063,7 +1102,9 @@ static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
"%s", userdata);
msg_ready = buf;
- netpoll_send_udp(&nt->np, msg_ready, msg_len);
+ count_udp_send_stats(nt, netpoll_send_udp(&nt->np,
+ msg_ready,
+ msg_len));
return;
}
@@ -1126,7 +1167,11 @@ static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
this_offset += this_chunk;
}
- netpoll_send_udp(&nt->np, buf, this_header + this_offset);
+ count_udp_send_stats(nt,
+ netpoll_send_udp(&nt->np,
+ buf,
+ this_header + this_offset)
+ );
offset += this_offset;
}
}
@@ -1172,7 +1217,10 @@ static void write_msg(struct console *con, const char *msg, unsigned int len)
tmp = msg;
for (left = len; left;) {
frag = min(left, MAX_PRINT_CHUNK);
- netpoll_send_udp(&nt->np, tmp, frag);
+ int send_result = netpoll_send_udp(&nt->np,
+ tmp,
+ frag);
+ count_udp_send_stats(nt, send_result);
tmp += frag;
left -= frag;
}
--
2.43.5
Powered by blists - more mailing lists