aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/netconsole.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-11-21 08:28:08 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2024-11-21 08:28:08 -0800
commitfcc79e1714e8c2b8e216dc3149812edd37884eef (patch)
tree17a51d29db810b81412be040aaf380936b3261b4 /drivers/net/netconsole.c
parent6e95ef0258ff4ee23ae3b06bf6b00b33dbbd5ef7 (diff)
parentdd7207838d38780b51e4690ee508ab2d5057e099 (diff)
downloadlinux-fcc79e1714e8c2b8e216dc3149812edd37884eef.tar.gz
linux-fcc79e1714e8c2b8e216dc3149812edd37884eef.tar.bz2
linux-fcc79e1714e8c2b8e216dc3149812edd37884eef.zip
Merge tag 'net-next-6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next
Pull networking updates from Paolo Abeni: "The most significant set of changes is the per netns RTNL. The new behavior is disabled by default, regression risk should be contained. Notably the new config knob PTP_1588_CLOCK_VMCLOCK will inherit its default value from PTP_1588_CLOCK_KVM, as the first is intended to be a more reliable replacement for the latter. Core: - Started a very large, in-progress, effort to make the RTNL lock scope per network-namespace, thus reducing the lock contention significantly in the containerized use-case, comprising: - RCU-ified some relevant slices of the FIB control path - introduce basic per netns locking helpers - namespacified the IPv4 address hash table - remove rtnl_register{,_module}() in favour of rtnl_register_many() - refactor rtnl_{new,del,set}link() moving as much validation as possible out of RTNL lock - convert all phonet doit() and dumpit() handlers to RCU - convert IPv4 addresses manipulation to per-netns RTNL - convert virtual interface creation to per-netns RTNL the per-netns lock infrastructure is guarded by the CONFIG_DEBUG_NET_SMALL_RTNL knob, disabled by default ad interim. - Introduce NAPI suspension, to efficiently switching between busy polling (NAPI processing suspended) and normal processing. - Migrate the IPv4 routing input, output and control path from direct ToS usage to DSCP macros. This is a work in progress to make ECN handling consistent and reliable. - Add drop reasons support to the IPv4 rotue input path, allowing better introspection in case of packets drop. - Make FIB seqnum lockless, dropping RTNL protection for read access. - Make inet{,v6} addresses hashing less predicable. - Allow providing timestamp OPT_ID via cmsg, to correlate TX packets and timestamps Things we sprinkled into general kernel code: - Add small file operations for debugfs, to reduce the struct ops size. - Refactoring and optimization for the implementation of page_frag API, This is a preparatory work to consolidate the page_frag implementation. Netfilter: - Optimize set element transactions to reduce memory consumption - Extended netlink error reporting for attribute parser failure. - Make legacy xtables configs user selectable, giving users the option to configure iptables without enabling any other config. - Address a lot of false-positive RCU issues, pointed by recent CI improvements. BPF: - Put xsk sockets on a struct diet and add various cleanups. Overall, this helps to bump performance by 12% for some workloads. - Extend BPF selftests to increase coverage of XDP features in combination with BPF cpumap. - Optimize and homogenize bpf_csum_diff helper for all archs and also add a batch of new BPF selftests for it. - Extend netkit with an option to delegate skb->{mark,priority} scrubbing to its BPF program. - Make the bpf_get_netns_cookie() helper available also to tc(x) BPF programs. Protocols: - Introduces 4-tuple hash for connected udp sockets, speeding-up significantly connected sockets lookup. - Add a fastpath for some TCP timers that usually expires after close, the socket lock contention. - Add inbound and outbound xfrm state caches to speed up state lookups. - Avoid sending MPTCP advertisements on stale subflows, reducing risks on loosing them. - Make neighbours table flushing more scalable, maintaining per device neigh lists. Driver API: - Introduce a unified interface to configure transmission H/W shaping, and expose it to user-space via generic-netlink. - Add support for per-NAPI config via netlink. This makes napi configuration persistent across queues removal and re-creation. Requires driver updates, currently supported drivers are: nVidia/Mellanox mlx4 and mlx5, Broadcom brcm and Intel ice. - Add ethtool support for writing SFP / PHY firmware blocks. - Track RSS context allocation from ethtool core. - Implement support for mirroring to DSA CPU port, via TC mirror offload. - Consolidate FDB updates notification, to avoid duplicates on device-specific entries. - Expose DPLL clock quality level to the user-space. - Support master-slave PHY config via device tree. Tests and tooling: - forwarding: introduce deferred commands, to simplify the cleanup phase Drivers: - Updated several drivers - Amazon vNic, Google vNic, Microsoft vNic, Intel e1000e and Broadcom Tigon3 - to use netdev-genl to link the IRQs and queues to NAPI IDs, allowing busy polling and better introspection. - Ethernet high-speed NICs: - nVidia/Mellanox: - mlx5: - a large refactor to implement support for cross E-Switch scheduling - refactor H/W conter management to let it scale better - H/W GRO cleanups - Intel (100G, ice):: - add support for ethtool reset - implement support for per TX queue H/W shaping - AMD/Solarflare: - implement per device queue stats support - Broadcom (bnxt): - improve wildcard l4proto on IPv4/IPv6 ntuple rules - Marvell Octeon: - Add representor support for each Resource Virtualization Unit (RVU) device. - Hisilicon: - add support for the BMC Gigabit Ethernet - IBM (EMAC): - driver cleanup and modernization - Cisco (VIC): - raise the queues number limit to 256 - Ethernet virtual: - Google vNIC: - implement page pool support - macsec: - inherit lower device's features and TSO limits when offloading - virtio_net: - enable premapped mode by default - support for XDP socket(AF_XDP) zerocopy TX - wireguard: - set the TSO max size to be GSO_MAX_SIZE, to aggregate larger packets. - Ethernet NICs embedded and virtual: - Broadcom ASP: - enable software timestamping - Freescale: - add enetc4 PF driver - MediaTek: Airoha SoC: - implement BQL support - RealTek r8169: - enable TSO by default on r8168/r8125 - implement extended ethtool stats - Renesas AVB: - enable TX checksum offload - Synopsys (stmmac): - support header splitting for vlan tagged packets - move common code for DWMAC4 and DWXGMAC into a separate FPE module. - add dwmac driver support for T-HEAD TH1520 SoC - Synopsys (xpcs): - driver refactor and cleanup - TI: - icssg_prueth: add VLAN offload support - Xilinx emaclite: - add clock support - Ethernet switches: - Microchip: - implement support for the lan969x Ethernet switch family - add LAN9646 switch support to KSZ DSA driver - Ethernet PHYs: - Marvel: 88q2x: enable auto negotiation - Microchip: add support for LAN865X Rev B1 and LAN867X Rev C1/C2 - PTP: - Add support for the Amazon virtual clock device - Add PtP driver for s390 clocks - WiFi: - mac80211 - EHT 1024 aggregation size for transmissions - new operation to indicate that a new interface is to be added - support radio separation of multi-band devices - move wireless extension spy implementation to libiw - Broadcom: - brcmfmac: optional LPO clock support - Microchip: - add support for Atmel WILC3000 - Qualcomm (ath12k): - firmware coredump collection support - add debugfs support for a multitude of statistics - Qualcomm (ath5k): - Arcadyan ARV45XX AR2417 & Gigaset SX76[23] AR241[34]A support - Realtek: - rtw88: 8821au and 8812au USB adapters support - rtw89: add thermal protection - rtw89: fine tune BT-coexsitence to improve user experience - rtw89: firmware secure boot for WiFi 6 chip - Bluetooth - add Qualcomm WCN785x support for ids Foxconn 0xe0fc/0xe0f3 and 0x13d3:0x3623 - add Realtek RTL8852BE support for id Foxconn 0xe123 - add MediaTek MT7920 support for wireless module ids - btintel_pcie: add handshake between driver and firmware - btintel_pcie: add recovery mechanism - btnxpuart: add GPIO support to power save feature" * tag 'net-next-6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (1475 commits) mm: page_frag: fix a compile error when kernel is not compiled Documentation: tipc: fix formatting issue in tipc.rst selftests: nic_performance: Add selftest for performance of NIC driver selftests: nic_link_layer: Add selftest case for speed and duplex states selftests: nic_link_layer: Add link layer selftest for NIC driver bnxt_en: Add FW trace coredump segments to the coredump bnxt_en: Add a new ethtool -W dump flag bnxt_en: Add 2 parameters to bnxt_fill_coredump_seg_hdr() bnxt_en: Add functions to copy host context memory bnxt_en: Do not free FW log context memory bnxt_en: Manage the FW trace context memory bnxt_en: Allocate backing store memory for FW trace logs bnxt_en: Add a 'force' parameter to bnxt_free_ctx_mem() bnxt_en: Refactor bnxt_free_ctx_mem() bnxt_en: Add mem_valid bit to struct bnxt_ctx_mem_type bnxt_en: Update firmware interface spec to 1.10.3.85 selftests/bpf: Add some tests with sockmap SK_PASS bpf: fix recursive lock when verdict program return SK_PASS wireguard: device: support big tcp GSO wireguard: selftests: load nf_conntrack if not present ...
Diffstat (limited to 'drivers/net/netconsole.c')
-rw-r--r--drivers/net/netconsole.c197
1 files changed, 132 insertions, 65 deletions
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index de20928f7402..4ea44a2f48f7 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -1058,102 +1058,105 @@ static struct notifier_block netconsole_netdev_notifier = {
.notifier_call = netconsole_netdev_event,
};
-/**
- * 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_no_fragmentation(struct netconsole_target *nt,
+ const char *msg,
+ int msg_len,
+ int release_len)
{
static char buf[MAX_PRINT_CHUNK]; /* protected by target_list_lock */
- const char *header, *body;
- int offset = 0;
- int header_len, body_len;
- const char *msg_ready = msg;
+ const char *userdata = NULL;
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;
#endif
- if (nt->release) {
+ if (release_len) {
release = init_utsname()->release;
- release_len = strlen(release) + 1;
+
+ scnprintf(buf, MAX_PRINT_CHUNK, "%s,%s", release, msg);
+ msg_len += release_len;
+ } else {
+ memcpy(buf, msg, msg_len);
}
- 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);
- if (userdata)
- msg_len += scnprintf(&buf[msg_len],
- MAX_PRINT_CHUNK - msg_len,
- "%s", userdata);
+ netpoll_send_udp(&nt->np, buf, msg_len);
+}
- msg_ready = buf;
- netpoll_send_udp(&nt->np, msg_ready, msg_len);
- return;
- }
+static void append_release(char *buf)
+{
+ const char *release;
- /* need to insert extra header fields, detect header and body */
- header = msg;
- body = memchr(msg, ';', msg_len);
- if (WARN_ON_ONCE(!body))
- return;
+ release = init_utsname()->release;
+ scnprintf(buf, MAX_PRINT_CHUNK, "%s,", release);
+}
- header_len = body - header;
- body_len = msg_len - header_len - 1;
- body++;
+static void send_fragmented_body(struct netconsole_target *nt, char *buf,
+ const char *msgbody, int header_len,
+ int msgbody_len)
+{
+ const char *userdata = NULL;
+ int body_len, offset = 0;
+ int userdata_len = 0;
- /*
- * Transfer multiple chunks with the following extra header.
- * "ncfrag=<byte-offset>/<total-bytes>"
+#ifdef CONFIG_NETCONSOLE_DYNAMIC
+ userdata = nt->userdata_complete;
+ userdata_len = nt->userdata_length;
+#endif
+
+ /* 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 (nt->release)
- scnprintf(buf, MAX_PRINT_CHUNK, "%s,", release);
- memcpy(buf + release_len, header, header_len);
- header_len += release_len;
+ body_len = msgbody_len + userdata_len;
- while (offset < body_len + userdata_len) {
+ /* 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;
+ bool msgbody_written = false;
int this_offset = 0;
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 + userdata_len);
+ body_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
+
+ /* msgbody was finally written, either in the previous
+ * messages and/or in the current buf. Time to write
+ * the userdata.
*/
- if (offset + this_offset >= body_len &&
- offset + this_offset < userdata_len + body_len) {
- int sent_userdata = (offset + this_offset) - body_len;
+ 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 (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))
@@ -1180,6 +1183,70 @@ static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
}
}
+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
+ * @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)
+{
+ int userdata_len = 0;
+ int release_len = 0;
+
+#ifdef CONFIG_NETCONSOLE_DYNAMIC
+ 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, 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,
unsigned int len)
{