From af2ccc6908f7c2156532de16f8446992b74e74a2 Mon Sep 17 00:00:00 2001 From: John Daley Date: Tue, 7 Jan 2025 13:41:57 -0800 Subject: [PATCH 01/16] enic: Move RX coalescing set function Move the function used for setting the RX coalescing range to before the function that checks the link status. It needs to be called from there instead of from the probe function. There is no functional change. Co-developed-by: Nelson Escobar Signed-off-by: Nelson Escobar Co-developed-by: Satish Kharat Signed-off-by: Satish Kharat Signed-off-by: John Daley Link: https://patch.msgid.link/20250107214159.18807-2-johndale@cisco.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/cisco/enic/enic_main.c | 60 ++++++++++----------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 9913952ccb42..957efe73e41a 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -428,6 +428,36 @@ static void enic_mtu_check(struct enic *enic) } } +static void enic_set_rx_coal_setting(struct enic *enic) +{ + unsigned int speed; + int index = -1; + struct enic_rx_coal *rx_coal = &enic->rx_coalesce_setting; + + /* 1. Read the link speed from fw + * 2. Pick the default range for the speed + * 3. Update it in enic->rx_coalesce_setting + */ + speed = vnic_dev_port_speed(enic->vdev); + if (speed > ENIC_LINK_SPEED_10G) + index = ENIC_LINK_40G_INDEX; + else if (speed > ENIC_LINK_SPEED_4G) + index = ENIC_LINK_10G_INDEX; + else + index = ENIC_LINK_4G_INDEX; + + rx_coal->small_pkt_range_start = mod_range[index].small_pkt_range_start; + rx_coal->large_pkt_range_start = mod_range[index].large_pkt_range_start; + rx_coal->range_end = ENIC_RX_COALESCE_RANGE_END; + + /* Start with the value provided by UCSM */ + for (index = 0; index < enic->rq_count; index++) + enic->cq[index].cur_rx_coal_timeval = + enic->config.intr_timer_usec; + + rx_coal->use_adaptive_rx_coalesce = 1; +} + static void enic_link_check(struct enic *enic) { int link_status = vnic_dev_link_status(enic->vdev); @@ -1901,36 +1931,6 @@ static void enic_synchronize_irqs(struct enic *enic) } } -static void enic_set_rx_coal_setting(struct enic *enic) -{ - unsigned int speed; - int index = -1; - struct enic_rx_coal *rx_coal = &enic->rx_coalesce_setting; - - /* 1. Read the link speed from fw - * 2. Pick the default range for the speed - * 3. Update it in enic->rx_coalesce_setting - */ - speed = vnic_dev_port_speed(enic->vdev); - if (ENIC_LINK_SPEED_10G < speed) - index = ENIC_LINK_40G_INDEX; - else if (ENIC_LINK_SPEED_4G < speed) - index = ENIC_LINK_10G_INDEX; - else - index = ENIC_LINK_4G_INDEX; - - rx_coal->small_pkt_range_start = mod_range[index].small_pkt_range_start; - rx_coal->large_pkt_range_start = mod_range[index].large_pkt_range_start; - rx_coal->range_end = ENIC_RX_COALESCE_RANGE_END; - - /* Start with the value provided by UCSM */ - for (index = 0; index < enic->rq_count; index++) - enic->cq[index].cur_rx_coal_timeval = - enic->config.intr_timer_usec; - - rx_coal->use_adaptive_rx_coalesce = 1; -} - static int enic_dev_notify_set(struct enic *enic) { int err; -- 2.50.1 From 238d77d110f7b54b483bf2b67038d43a7b51800c Mon Sep 17 00:00:00 2001 From: John Daley Date: Tue, 7 Jan 2025 13:41:58 -0800 Subject: [PATCH 02/16] enic: Obtain the Link speed only after the link comes up The link speed is obtained in the RX adaptive coalescing function. It was being called at probe time when the link may not be up. Change the call to run after the Link comes up. The impact of not getting the correct link speed was that the low end of the adaptive interrupt range was always being set to 0 which could have caused a slight increase in the number of RX interrupts. Co-developed-by: Nelson Escobar Signed-off-by: Nelson Escobar Co-developed-by: Satish Kharat Signed-off-by: Satish Kharat Signed-off-by: John Daley Reviewed-by: Kalesh AP Link: https://patch.msgid.link/20250107214159.18807-3-johndale@cisco.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/cisco/enic/enic_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 957efe73e41a..8109e9c484f6 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -466,6 +466,7 @@ static void enic_link_check(struct enic *enic) if (link_status && !carrier_ok) { netdev_info(enic->netdev, "Link UP\n"); netif_carrier_on(enic->netdev); + enic_set_rx_coal_setting(enic); } else if (!link_status && carrier_ok) { netdev_info(enic->netdev, "Link DOWN\n"); netif_carrier_off(enic->netdev); @@ -3063,7 +3064,6 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) timer_setup(&enic->notify_timer, enic_notify_timer, 0); enic_rfs_flw_tbl_init(enic); - enic_set_rx_coal_setting(enic); INIT_WORK(&enic->reset, enic_reset); INIT_WORK(&enic->tx_hang_reset, enic_tx_hang_reset); INIT_WORK(&enic->change_mtu_work, enic_change_mtu_work); -- 2.50.1 From 8e0644e5398be53f44e9c23c6d57ef367b1ad2a2 Mon Sep 17 00:00:00 2001 From: John Daley Date: Tue, 7 Jan 2025 13:41:59 -0800 Subject: [PATCH 03/16] enic: Fix typo in comment in table indexed by link speed The RX adaptive interrupt moderation table is indexed by link speed range, where the last row of the table is the catch-all for all link speeds greater than 10Gbps. The comment said 10 - 40Gbps, but since there are now adapters with link speeds than 40Gbps, the comment is now wrong and should indicate it applies to all speeds greater than 10Gbps. Co-developed-by: Nelson Escobar Signed-off-by: Nelson Escobar Co-developed-by: Satish Kharat Signed-off-by: Satish Kharat Signed-off-by: John Daley Reviewed-by: Kalesh AP Link: https://patch.msgid.link/20250107214159.18807-4-johndale@cisco.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/cisco/enic/enic_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 8109e9c484f6..49f6cab01ed5 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -109,7 +109,7 @@ static struct enic_intr_mod_table mod_table[ENIC_MAX_COALESCE_TIMERS + 1] = { static struct enic_intr_mod_range mod_range[ENIC_MAX_LINK_SPEEDS] = { {0, 0}, /* 0 - 4 Gbps */ {0, 3}, /* 4 - 10 Gbps */ - {3, 6}, /* 10 - 40 Gbps */ + {3, 6}, /* 10+ Gbps */ }; static void enic_init_affinity_hint(struct enic *enic) -- 2.50.1 From 93e505a300aa4314995f14a2083d0df97a0d80e3 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Wed, 8 Jan 2025 12:07:58 -0800 Subject: [PATCH 04/16] tools: ynl-gen-c: improve support for empty nests Empty nests are the same size as a flag at the netlink level (just a 4 byte nlattr without a payload). They are sometimes useful in case we want to only communicate a presence of something but may want to add more details later. This may be the case in the upcoming io_uring ZC patches, for example. Improve handling of nested empty structs. We already support empty structs since a lot of netlink replies are empty, but for nested ones we need minor tweaks to avoid pointless empty lines and unused variables. Acked-by: Stanislav Fomichev Reviewed-by: Nicolas Dichtel Link: https://patch.msgid.link/20250108200758.2693155-1-kuba@kernel.org Signed-off-by: Jakub Kicinski --- tools/net/ynl/ynl-gen-c.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py index 58657dd7dedb..d3a7dfbcf929 100755 --- a/tools/net/ynl/ynl-gen-c.py +++ b/tools/net/ynl/ynl-gen-c.py @@ -1783,7 +1783,14 @@ def parse_rsp_nested(ri, struct): f'{struct.ptr_name}dst = yarg->data;'] init_lines = [] - _multi_parse(ri, struct, init_lines, local_vars) + if struct.member_list(): + _multi_parse(ri, struct, init_lines, local_vars) + else: + # Empty nest + ri.cw.block_start() + ri.cw.p('return 0;') + ri.cw.block_end() + ri.cw.nl() def parse_rsp_msg(ri, deref=False): @@ -2610,7 +2617,8 @@ def render_uapi(family, cw): val = attr.value val += 1 cw.p(attr.enum_name + suffix) - cw.nl() + if attr_set.items(): + cw.nl() cw.p(attr_set.cnt_name + ('' if max_by_define else ',')) if not max_by_define: cw.p(f"{attr_set.max_name} = {max_value}") -- 2.50.1 From ab88c2b3739a3d839b04f57d9ee0d6b1dc311cc8 Mon Sep 17 00:00:00 2001 From: Jan Stancek Date: Wed, 8 Jan 2025 14:56:14 +0100 Subject: [PATCH 05/16] tools: ynl: move python code to separate sub-directory Move python code to a separate directory so it can be packaged as a python module. Updates existing references in selftests and docs. Also rename ynl-gen-[c|rst] to ynl_gen_[c|rst], avoid dashes as these prevent easy imports for entrypoints. Signed-off-by: Jan Stancek Reviewed-by: Donald Hunter Link: https://patch.msgid.link/a4151bad0e6984e7164d395125ce87fd2e048bf1.1736343575.git.jstancek@redhat.com Signed-off-by: Jakub Kicinski --- Documentation/Makefile | 2 +- Documentation/networking/multi-pf-netdev.rst | 4 ++-- Documentation/networking/napi.rst | 4 ++-- Documentation/networking/netlink_spec/readme.txt | 2 +- Documentation/userspace-api/netlink/intro-specs.rst | 8 ++++---- tools/net/ynl/Makefile | 2 ++ tools/net/ynl/generated/Makefile | 2 +- tools/net/ynl/lib/.gitignore | 1 - tools/net/ynl/lib/Makefile | 1 - tools/net/ynl/pyynl/.gitignore | 2 ++ tools/net/ynl/pyynl/__init__.py | 0 tools/net/ynl/{ => pyynl}/cli.py | 0 tools/net/ynl/{ => pyynl}/ethtool.py | 0 tools/net/ynl/{ => pyynl}/lib/__init__.py | 0 tools/net/ynl/{ => pyynl}/lib/nlspec.py | 0 tools/net/ynl/{ => pyynl}/lib/ynl.py | 0 tools/net/ynl/{ynl-gen-c.py => pyynl/ynl_gen_c.py} | 0 tools/net/ynl/{ynl-gen-rst.py => pyynl/ynl_gen_rst.py} | 0 tools/net/ynl/ynl-regen.sh | 2 +- tools/testing/selftests/net/lib/py/ynl.py | 4 ++-- tools/testing/selftests/net/ynl.mk | 3 ++- 21 files changed, 20 insertions(+), 17 deletions(-) create mode 100644 tools/net/ynl/pyynl/.gitignore create mode 100644 tools/net/ynl/pyynl/__init__.py rename tools/net/ynl/{ => pyynl}/cli.py (100%) rename tools/net/ynl/{ => pyynl}/ethtool.py (100%) rename tools/net/ynl/{ => pyynl}/lib/__init__.py (100%) rename tools/net/ynl/{ => pyynl}/lib/nlspec.py (100%) rename tools/net/ynl/{ => pyynl}/lib/ynl.py (100%) rename tools/net/ynl/{ynl-gen-c.py => pyynl/ynl_gen_c.py} (100%) rename tools/net/ynl/{ynl-gen-rst.py => pyynl/ynl_gen_rst.py} (100%) diff --git a/Documentation/Makefile b/Documentation/Makefile index fa71602ec961..52c6c5a3efa9 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -104,7 +104,7 @@ quiet_cmd_sphinx = SPHINX $@ --> file://$(abspath $(BUILDDIR)/$3/$4) YNL_INDEX:=$(srctree)/Documentation/networking/netlink_spec/index.rst YNL_RST_DIR:=$(srctree)/Documentation/networking/netlink_spec YNL_YAML_DIR:=$(srctree)/Documentation/netlink/specs -YNL_TOOL:=$(srctree)/tools/net/ynl/ynl-gen-rst.py +YNL_TOOL:=$(srctree)/tools/net/ynl/pyynl/ynl_gen_rst.py YNL_RST_FILES_TMP := $(patsubst %.yaml,%.rst,$(wildcard $(YNL_YAML_DIR)/*.yaml)) YNL_RST_FILES := $(patsubst $(YNL_YAML_DIR)%,$(YNL_RST_DIR)%, $(YNL_RST_FILES_TMP)) diff --git a/Documentation/networking/multi-pf-netdev.rst b/Documentation/networking/multi-pf-netdev.rst index 2cd25d81aaa7..2f5a5bb3ca9a 100644 --- a/Documentation/networking/multi-pf-netdev.rst +++ b/Documentation/networking/multi-pf-netdev.rst @@ -89,7 +89,7 @@ Observability ============= The relation between PF, irq, napi, and queue can be observed via netlink spec:: - $ ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/netdev.yaml --dump queue-get --json='{"ifindex": 13}' + $ ./tools/net/ynl/pyynl/cli.py --spec Documentation/netlink/specs/netdev.yaml --dump queue-get --json='{"ifindex": 13}' [{'id': 0, 'ifindex': 13, 'napi-id': 539, 'type': 'rx'}, {'id': 1, 'ifindex': 13, 'napi-id': 540, 'type': 'rx'}, {'id': 2, 'ifindex': 13, 'napi-id': 541, 'type': 'rx'}, @@ -101,7 +101,7 @@ The relation between PF, irq, napi, and queue can be observed via netlink spec:: {'id': 3, 'ifindex': 13, 'napi-id': 542, 'type': 'tx'}, {'id': 4, 'ifindex': 13, 'napi-id': 543, 'type': 'tx'}] - $ ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/netdev.yaml --dump napi-get --json='{"ifindex": 13}' + $ ./tools/net/ynl/pyynl/cli.py --spec Documentation/netlink/specs/netdev.yaml --dump napi-get --json='{"ifindex": 13}' [{'id': 543, 'ifindex': 13, 'irq': 42}, {'id': 542, 'ifindex': 13, 'irq': 41}, {'id': 541, 'ifindex': 13, 'irq': 40}, diff --git a/Documentation/networking/napi.rst b/Documentation/networking/napi.rst index 02720dd71a76..6083210ab2a4 100644 --- a/Documentation/networking/napi.rst +++ b/Documentation/networking/napi.rst @@ -199,13 +199,13 @@ parameters mentioned above use hyphens instead of underscores: Per-NAPI configuration can be done programmatically in a user application or by using a script included in the kernel source tree: -``tools/net/ynl/cli.py``. +``tools/net/ynl/pyynl/cli.py``. For example, using the script: .. code-block:: bash - $ kernel-source/tools/net/ynl/cli.py \ + $ kernel-source/tools/net/ynl/pyynl/cli.py \ --spec Documentation/netlink/specs/netdev.yaml \ --do napi-set \ --json='{"id": 345, diff --git a/Documentation/networking/netlink_spec/readme.txt b/Documentation/networking/netlink_spec/readme.txt index 6763f99d216c..030b44aca4e6 100644 --- a/Documentation/networking/netlink_spec/readme.txt +++ b/Documentation/networking/netlink_spec/readme.txt @@ -1,4 +1,4 @@ SPDX-License-Identifier: GPL-2.0 This file is populated during the build of the documentation (htmldocs) by the -tools/net/ynl/ynl-gen-rst.py script. +tools/net/ynl/pyynl/ynl_gen_rst.py script. diff --git a/Documentation/userspace-api/netlink/intro-specs.rst b/Documentation/userspace-api/netlink/intro-specs.rst index bada89699455..a4435ae4628d 100644 --- a/Documentation/userspace-api/netlink/intro-specs.rst +++ b/Documentation/userspace-api/netlink/intro-specs.rst @@ -15,7 +15,7 @@ developing Netlink related code. The tool is implemented in Python and can use a YAML specification to issue Netlink requests to the kernel. Only Generic Netlink is supported. -The tool is located at ``tools/net/ynl/cli.py``. It accepts +The tool is located at ``tools/net/ynl/pyynl/cli.py``. It accepts a handul of arguments, the most important ones are: - ``--spec`` - point to the spec file @@ -27,7 +27,7 @@ YAML specs can be found under ``Documentation/netlink/specs/``. Example use:: - $ ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/ethtool.yaml \ + $ ./tools/net/ynl/pyynl/cli.py --spec Documentation/netlink/specs/ethtool.yaml \ --do rings-get \ --json '{"header":{"dev-index": 18}}' {'header': {'dev-index': 18, 'dev-name': 'eni1np1'}, @@ -75,7 +75,7 @@ the two marker lines like above to a file, add that file to git, and run the regeneration tool. Grep the tree for ``YNL-GEN`` to see other examples. -The code generation itself is performed by ``tools/net/ynl/ynl-gen-c.py`` +The code generation itself is performed by ``tools/net/ynl/pyynl/ynl_gen_c.py`` but it takes a few arguments so calling it directly for each file quickly becomes tedious. @@ -84,7 +84,7 @@ YNL lib ``tools/net/ynl/lib/`` contains an implementation of a C library (based on libmnl) which integrates with code generated by -``tools/net/ynl/ynl-gen-c.py`` to create easy to use netlink wrappers. +``tools/net/ynl/pyynl/ynl_gen_c.py`` to create easy to use netlink wrappers. YNL basics ---------- diff --git a/tools/net/ynl/Makefile b/tools/net/ynl/Makefile index d1cdf2a8f826..5268b91bf7ed 100644 --- a/tools/net/ynl/Makefile +++ b/tools/net/ynl/Makefile @@ -21,5 +21,7 @@ clean distclean: fi \ done rm -f libynl.a + rm -rf pyynl/__pycache__ + rm -rf pyynl/lib/__pycache__ .PHONY: all clean distclean $(SUBDIRS) diff --git a/tools/net/ynl/generated/Makefile b/tools/net/ynl/generated/Makefile index 7db5240de58a..00af721b1571 100644 --- a/tools/net/ynl/generated/Makefile +++ b/tools/net/ynl/generated/Makefile @@ -12,7 +12,7 @@ include ../Makefile.deps YNL_GEN_ARG_ethtool:=--user-header linux/ethtool_netlink.h \ --exclude-op stats-get -TOOL:=../ynl-gen-c.py +TOOL:=../pyynl/ynl_gen_c.py GENS_PATHS=$(shell grep -nrI --files-without-match \ 'protocol: netlink' \ diff --git a/tools/net/ynl/lib/.gitignore b/tools/net/ynl/lib/.gitignore index 296c4035dbf2..a4383358ec72 100644 --- a/tools/net/ynl/lib/.gitignore +++ b/tools/net/ynl/lib/.gitignore @@ -1,2 +1 @@ -__pycache__/ *.d diff --git a/tools/net/ynl/lib/Makefile b/tools/net/ynl/lib/Makefile index 94c49cca3dca..4b2b98704ff9 100644 --- a/tools/net/ynl/lib/Makefile +++ b/tools/net/ynl/lib/Makefile @@ -19,7 +19,6 @@ ynl.a: $(OBJS) clean: rm -f *.o *.d *~ - rm -rf __pycache__ distclean: clean rm -f *.a diff --git a/tools/net/ynl/pyynl/.gitignore b/tools/net/ynl/pyynl/.gitignore new file mode 100644 index 000000000000..b801cd2d016e --- /dev/null +++ b/tools/net/ynl/pyynl/.gitignore @@ -0,0 +1,2 @@ +__pycache__/ +lib/__pycache__/ diff --git a/tools/net/ynl/pyynl/__init__.py b/tools/net/ynl/pyynl/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tools/net/ynl/cli.py b/tools/net/ynl/pyynl/cli.py similarity index 100% rename from tools/net/ynl/cli.py rename to tools/net/ynl/pyynl/cli.py diff --git a/tools/net/ynl/ethtool.py b/tools/net/ynl/pyynl/ethtool.py similarity index 100% rename from tools/net/ynl/ethtool.py rename to tools/net/ynl/pyynl/ethtool.py diff --git a/tools/net/ynl/lib/__init__.py b/tools/net/ynl/pyynl/lib/__init__.py similarity index 100% rename from tools/net/ynl/lib/__init__.py rename to tools/net/ynl/pyynl/lib/__init__.py diff --git a/tools/net/ynl/lib/nlspec.py b/tools/net/ynl/pyynl/lib/nlspec.py similarity index 100% rename from tools/net/ynl/lib/nlspec.py rename to tools/net/ynl/pyynl/lib/nlspec.py diff --git a/tools/net/ynl/lib/ynl.py b/tools/net/ynl/pyynl/lib/ynl.py similarity index 100% rename from tools/net/ynl/lib/ynl.py rename to tools/net/ynl/pyynl/lib/ynl.py diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/pyynl/ynl_gen_c.py similarity index 100% rename from tools/net/ynl/ynl-gen-c.py rename to tools/net/ynl/pyynl/ynl_gen_c.py diff --git a/tools/net/ynl/ynl-gen-rst.py b/tools/net/ynl/pyynl/ynl_gen_rst.py similarity index 100% rename from tools/net/ynl/ynl-gen-rst.py rename to tools/net/ynl/pyynl/ynl_gen_rst.py diff --git a/tools/net/ynl/ynl-regen.sh b/tools/net/ynl/ynl-regen.sh index a37304dcc88e..81b4ecd89100 100755 --- a/tools/net/ynl/ynl-regen.sh +++ b/tools/net/ynl/ynl-regen.sh @@ -1,7 +1,7 @@ #!/bin/bash # SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -TOOL=$(dirname $(realpath $0))/ynl-gen-c.py +TOOL=$(dirname $(realpath $0))/pyynl/ynl_gen_c.py force= search= diff --git a/tools/testing/selftests/net/lib/py/ynl.py b/tools/testing/selftests/net/lib/py/ynl.py index 076a7e8dc3eb..ad1e36baee2a 100644 --- a/tools/testing/selftests/net/lib/py/ynl.py +++ b/tools/testing/selftests/net/lib/py/ynl.py @@ -13,14 +13,14 @@ try: SPEC_PATH = KSFT_DIR / "net/lib/specs" sys.path.append(tools_full_path.as_posix()) - from net.lib.ynl.lib import YnlFamily, NlError + from net.lib.ynl.pyynl.lib import YnlFamily, NlError else: # Running in tree tools_full_path = KSRC / "tools" SPEC_PATH = KSRC / "Documentation/netlink/specs" sys.path.append(tools_full_path.as_posix()) - from net.ynl.lib import YnlFamily, NlError + from net.ynl.pyynl.lib import YnlFamily, NlError except ModuleNotFoundError as e: ksft_pr("Failed importing `ynl` library from kernel sources") ksft_pr(str(e)) diff --git a/tools/testing/selftests/net/ynl.mk b/tools/testing/selftests/net/ynl.mk index d43afe243779..12e7cae251be 100644 --- a/tools/testing/selftests/net/ynl.mk +++ b/tools/testing/selftests/net/ynl.mk @@ -31,7 +31,8 @@ $(OUTPUT)/libynl.a: $(YNL_SPECS) $(OUTPUT)/.libynl-$(YNL_GENS_HASH).sig $(Q)cp $(top_srcdir)/tools/net/ynl/libynl.a $(OUTPUT)/libynl.a EXTRA_CLEAN += \ - $(top_srcdir)/tools/net/ynl/lib/__pycache__ \ + $(top_srcdir)/tools/net/ynl/pyynl/__pycache__ \ + $(top_srcdir)/tools/net/ynl/pyynl/lib/__pycache__ \ $(top_srcdir)/tools/net/ynl/lib/*.[ado] \ $(OUTPUT)/.libynl-*.sig \ $(OUTPUT)/libynl.a -- 2.50.1 From a12afefa2eabf435cb1683752b11b9cc2a42502a Mon Sep 17 00:00:00 2001 From: Jan Stancek Date: Wed, 8 Jan 2025 14:56:15 +0100 Subject: [PATCH 06/16] tools: ynl: add initial pyproject.toml for packaging Add pyproject.toml and define authors, dependencies and user-facing scripts. This will be used later by pip to install python code. Signed-off-by: Jan Stancek Reviewed-by: Donald Hunter Link: https://patch.msgid.link/b184b43340f08aef97387bfd7f2b2cd9b015c343.1736343575.git.jstancek@redhat.com Signed-off-by: Jakub Kicinski --- tools/net/ynl/pyproject.toml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tools/net/ynl/pyproject.toml diff --git a/tools/net/ynl/pyproject.toml b/tools/net/ynl/pyproject.toml new file mode 100644 index 000000000000..a81d8779b0e0 --- /dev/null +++ b/tools/net/ynl/pyproject.toml @@ -0,0 +1,24 @@ +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "pyynl" +authors = [ + {name = "Donald Hunter", email = "donald.hunter@gmail.com"}, + {name = "Jakub Kicinski", email = "kuba@kernel.org"}, +] +description = "yaml netlink (ynl)" +version = "0.0.1" +requires-python = ">=3.9" +dependencies = [ + "pyyaml==6.*", + "jsonschema==4.*" +] + +[tool.setuptools.packages.find] +include = ["pyynl", "pyynl.lib"] + +[project.scripts] +ynl = "pyynl.cli:main" +ynl-ethtool = "pyynl.ethtool:main" -- 2.50.1 From 1b038af9f75284d8ea2b8ca5a2a3106c5ac3f232 Mon Sep 17 00:00:00 2001 From: Jan Stancek Date: Wed, 8 Jan 2025 14:56:16 +0100 Subject: [PATCH 07/16] tools: ynl: add install target for generated content Generate docs using ynl_gen_rst and add install target for headers, specs and generates rst files. Factor out SPECS_DIR since it's repeated many times. Signed-off-by: Jan Stancek Reviewed-by: Donald Hunter Link: https://patch.msgid.link/645c68e3d201f1ef4276e3daddfe06262a0c2804.1736343575.git.jstancek@redhat.com Signed-off-by: Jakub Kicinski --- tools/net/ynl/generated/.gitignore | 1 + tools/net/ynl/generated/Makefile | 49 +++++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/tools/net/ynl/generated/.gitignore b/tools/net/ynl/generated/.gitignore index ade488626d26..859a6fb446e1 100644 --- a/tools/net/ynl/generated/.gitignore +++ b/tools/net/ynl/generated/.gitignore @@ -1,2 +1,3 @@ *-user.c *-user.h +*.rst diff --git a/tools/net/ynl/generated/Makefile b/tools/net/ynl/generated/Makefile index 00af721b1571..21f9e299dc75 100644 --- a/tools/net/ynl/generated/Makefile +++ b/tools/net/ynl/generated/Makefile @@ -7,32 +7,44 @@ ifeq ("$(DEBUG)","1") CFLAGS += -g -fsanitize=address -fsanitize=leak -static-libasan endif +INSTALL ?= install +prefix ?= /usr +datarootdir ?= $(prefix)/share +docdir ?= $(datarootdir)/doc +includedir ?= $(prefix)/include + include ../Makefile.deps YNL_GEN_ARG_ethtool:=--user-header linux/ethtool_netlink.h \ --exclude-op stats-get TOOL:=../pyynl/ynl_gen_c.py +TOOL_RST:=../pyynl/ynl_gen_rst.py +SPECS_DIR:=../../../../Documentation/netlink/specs GENS_PATHS=$(shell grep -nrI --files-without-match \ 'protocol: netlink' \ - ../../../../Documentation/netlink/specs/) -GENS=$(patsubst ../../../../Documentation/netlink/specs/%.yaml,%,${GENS_PATHS}) + $(SPECS_DIR)) +GENS=$(patsubst $(SPECS_DIR)/%.yaml,%,${GENS_PATHS}) SRCS=$(patsubst %,%-user.c,${GENS}) HDRS=$(patsubst %,%-user.h,${GENS}) OBJS=$(patsubst %,%-user.o,${GENS}) -all: protos.a $(HDRS) $(SRCS) $(KHDRS) $(KSRCS) $(UAPI) +SPECS_PATHS=$(wildcard $(SPECS_DIR)/*.yaml) +SPECS=$(patsubst $(SPECS_DIR)/%.yaml,%,${SPECS_PATHS}) +RSTS=$(patsubst %,%.rst,${SPECS}) + +all: protos.a $(HDRS) $(SRCS) $(KHDRS) $(KSRCS) $(UAPI) $(RSTS) protos.a: $(OBJS) @echo -e "\tAR $@" @ar rcs $@ $(OBJS) -%-user.h: ../../../../Documentation/netlink/specs/%.yaml $(TOOL) +%-user.h: $(SPECS_DIR)/%.yaml $(TOOL) @echo -e "\tGEN $@" @$(TOOL) --mode user --header --spec $< -o $@ $(YNL_GEN_ARG_$*) -%-user.c: ../../../../Documentation/netlink/specs/%.yaml $(TOOL) +%-user.c: $(SPECS_DIR)/%.yaml $(TOOL) @echo -e "\tGEN $@" @$(TOOL) --mode user --source --spec $< -o $@ $(YNL_GEN_ARG_$*) @@ -40,14 +52,37 @@ protos.a: $(OBJS) @echo -e "\tCC $@" @$(COMPILE.c) $(CFLAGS_$*) -o $@ $< +%.rst: $(SPECS_DIR)/%.yaml $(TOOL_RST) + @echo -e "\tGEN_RST $@" + @$(TOOL_RST) -o $@ -i $< + clean: rm -f *.o distclean: clean - rm -f *.c *.h *.a + rm -f *.c *.h *.a *.rst regen: @../ynl-regen.sh -.PHONY: all clean distclean regen +install-headers: $(HDRS) + @echo -e "\tINSTALL generated headers" + @$(INSTALL) -d $(DESTDIR)$(includedir)/ynl + @$(INSTALL) -m 0644 *.h $(DESTDIR)$(includedir)/ynl/ + +install-rsts: $(RSTS) + @echo -e "\tINSTALL generated docs" + @$(INSTALL) -d $(DESTDIR)$(docdir)/ynl + @$(INSTALL) -m 0644 $(RSTS) $(DESTDIR)$(docdir)/ynl/ + +install-specs: + @echo -e "\tINSTALL specs" + @$(INSTALL) -d $(DESTDIR)$(datarootdir)/ynl + @$(INSTALL) -m 0644 ../../../../Documentation/netlink/*.yaml $(DESTDIR)$(datarootdir)/ynl/ + @$(INSTALL) -d $(DESTDIR)$(datarootdir)/ynl/specs + @$(INSTALL) -m 0644 $(SPECS_DIR)/*.yaml $(DESTDIR)$(datarootdir)/ynl/specs/ + +install: install-headers install-rsts install-specs + +.PHONY: all clean distclean regen install install-headers install-rsts install-specs .DEFAULT_GOAL: all -- 2.50.1 From e5ad1d98234a028dadc3c5b811201399887358c1 Mon Sep 17 00:00:00 2001 From: Jan Stancek Date: Wed, 8 Jan 2025 14:56:17 +0100 Subject: [PATCH 08/16] tools: ynl: add main install target This will install C library, specs, rsts and pyynl. The initial structure is: $ mkdir /tmp/myroot $ make DESTDIR=/tmp/myroot install /usr /usr/lib64 /usr/lib64/libynl.a /usr/lib/python3.XX/site-packages/pyynl/* /usr/lib/python3.XX/site-packages/pyynl-0.0.1.dist-info/* /usr/bin /usr/bin/ynl /usr/bin/ynl-ethtool /usr/include/ynl/*.h /usr/share /usr/share/doc /usr/share/doc/ynl /usr/share/doc/ynl/*.rst /usr/share/ynl /usr/share/ynl/genetlink-c.yaml /usr/share/ynl/genetlink-legacy.yaml /usr/share/ynl/genetlink.yaml /usr/share/ynl/netlink-raw.yaml /usr/share/ynl/specs /usr/share/ynl/specs/devlink.yaml /usr/share/ynl/specs/dpll.yaml /usr/share/ynl/specs/ethtool.yaml /usr/share/ynl/specs/fou.yaml /usr/share/ynl/specs/handshake.yaml /usr/share/ynl/specs/mptcp_pm.yaml /usr/share/ynl/specs/netdev.yaml /usr/share/ynl/specs/net_shaper.yaml /usr/share/ynl/specs/nfsd.yaml /usr/share/ynl/specs/nftables.yaml /usr/share/ynl/specs/nlctrl.yaml /usr/share/ynl/specs/ovs_datapath.yaml /usr/share/ynl/specs/ovs_flow.yaml /usr/share/ynl/specs/ovs_vport.yaml /usr/share/ynl/specs/rt_addr.yaml /usr/share/ynl/specs/rt_link.yaml /usr/share/ynl/specs/rt_neigh.yaml /usr/share/ynl/specs/rt_route.yaml /usr/share/ynl/specs/rt_rule.yaml /usr/share/ynl/specs/tcp_metrics.yaml /usr/share/ynl/specs/tc.yaml /usr/share/ynl/specs/team.yaml Signed-off-by: Jan Stancek Reviewed-by: Donald Hunter Reviewed-by: Joe Damato Link: https://patch.msgid.link/c882688d751295c7f35c7d4eba104cd5174a0861.1736343575.git.jstancek@redhat.com Signed-off-by: Jakub Kicinski --- tools/net/ynl/Makefile | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/tools/net/ynl/Makefile b/tools/net/ynl/Makefile index 5268b91bf7ed..211df5a93ad9 100644 --- a/tools/net/ynl/Makefile +++ b/tools/net/ynl/Makefile @@ -1,5 +1,17 @@ # SPDX-License-Identifier: GPL-2.0 +include ../../scripts/Makefile.arch + +INSTALL ?= install +prefix ?= /usr +ifeq ($(LP64), 1) + libdir_relative = lib64 +else + libdir_relative = lib +endif +libdir ?= $(prefix)/$(libdir_relative) +includedir ?= $(prefix)/include + SUBDIRS = lib generated samples all: $(SUBDIRS) libynl.a @@ -23,5 +35,18 @@ clean distclean: rm -f libynl.a rm -rf pyynl/__pycache__ rm -rf pyynl/lib/__pycache__ + rm -rf pyynl.egg-info + rm -rf build + +install: libynl.a lib/*.h + @echo -e "\tINSTALL libynl.a" + @$(INSTALL) -d $(DESTDIR)$(libdir) + @$(INSTALL) -m 0644 libynl.a $(DESTDIR)$(libdir)/libynl.a + @echo -e "\tINSTALL libynl headers" + @$(INSTALL) -d $(DESTDIR)$(includedir)/ynl + @$(INSTALL) -m 0644 lib/*.h $(DESTDIR)$(includedir)/ynl/ + @echo -e "\tINSTALL pyynl" + @pip install --prefix=$(DESTDIR)$(prefix) . + @make -C generated install -.PHONY: all clean distclean $(SUBDIRS) +.PHONY: all clean distclean install $(SUBDIRS) -- 2.50.1 From e51c7478d23bb484d414fc036cd1ff57afe31b67 Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Wed, 8 Jan 2025 03:50:25 -0800 Subject: [PATCH 09/16] netconsole: Warn if MAX_USERDATA_ITEMS limit is exceeded netconsole configfs helpers doesn't allow the creation of more than MAX_USERDATA_ITEMS items. Add a warning when netconsole userdata update function attempts sees more than MAX_USERDATA_ITEMS entries. Replace silent ignore mechanism with WARN_ON_ONCE() to highlight potential misuse during development and debugging. Signed-off-by: Breno Leitao Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250108-netcons_overflow_test-v3-1-3d85eb091bec@debian.org Signed-off-by: Jakub Kicinski --- drivers/net/netconsole.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index f422a2f666ef..86ab4a42769a 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -730,7 +730,7 @@ static void update_userdata(struct netconsole_target *nt) struct userdatum *udm_item; struct config_item *item; - if (child_count >= MAX_USERDATA_ITEMS) + if (WARN_ON_ONCE(child_count >= MAX_USERDATA_ITEMS)) break; child_count++; -- 2.50.1 From 61f51cc6defeb0faad1f60f1dbc41613e93f31da Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Wed, 8 Jan 2025 03:50:26 -0800 Subject: [PATCH 10/16] netconsole: selftest: Split the helpers from the selftest Split helper functions from the netconsole basic test into a separate library file to enable reuse across different netconsole tests. This change only moves the existing helper functions to lib/sh/lib_netcons.sh while preserving the same test functionality. The helpers provide common functions for: - Setting up network namespaces and interfaces - Managing netconsole dynamic targets - Setting user data - Handling test dependencies - Cleanup operations Do not make any change in the code, other than the mechanical separation. Signed-off-by: Breno Leitao Tested-by: Simon Horman Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250108-netcons_overflow_test-v3-2-3d85eb091bec@debian.org Signed-off-by: Jakub Kicinski --- MAINTAINERS | 1 + tools/testing/selftests/drivers/net/Makefile | 1 + .../drivers/net/lib/sh/lib_netcons.sh | 225 ++++++++++++++++++ .../selftests/drivers/net/netcons_basic.sh | 218 +---------------- 4 files changed, 228 insertions(+), 217 deletions(-) create mode 100644 tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh diff --git a/MAINTAINERS b/MAINTAINERS index 42ac78507213..7a88872fada8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16170,6 +16170,7 @@ M: Breno Leitao S: Maintained F: Documentation/networking/netconsole.rst F: drivers/net/netconsole.c +F: tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh F: tools/testing/selftests/drivers/net/netcons_basic.sh NETDEVSIM diff --git a/tools/testing/selftests/drivers/net/Makefile b/tools/testing/selftests/drivers/net/Makefile index 0fec8f9801ad..dafff5d7fe88 100644 --- a/tools/testing/selftests/drivers/net/Makefile +++ b/tools/testing/selftests/drivers/net/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 TEST_INCLUDES := $(wildcard lib/py/*.py) \ + $(wildcard lib/sh/*.sh) \ ../../net/net_helper.sh \ ../../net/lib.sh \ diff --git a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh new file mode 100644 index 000000000000..fdd45a3468f1 --- /dev/null +++ b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh @@ -0,0 +1,225 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: GPL-2.0 + +# This file contains functions and helpers to support the netconsole +# selftests +# +# Author: Breno Leitao + +set -euo pipefail + +LIBDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")") + +SRCIF="" # to be populated later +SRCIP=192.0.2.1 +DSTIF="" # to be populated later +DSTIP=192.0.2.2 + +PORT="6666" +MSG="netconsole selftest" +USERDATA_KEY="key" +USERDATA_VALUE="value" +TARGET=$(mktemp -u netcons_XXXXX) +DEFAULT_PRINTK_VALUES=$(cat /proc/sys/kernel/printk) +NETCONS_CONFIGFS="/sys/kernel/config/netconsole" +NETCONS_PATH="${NETCONS_CONFIGFS}"/"${TARGET}" +KEY_PATH="${NETCONS_PATH}/userdata/${USERDATA_KEY}" +# NAMESPACE will be populated by setup_ns with a random value +NAMESPACE="" + +# IDs for netdevsim +NSIM_DEV_1_ID=$((256 + RANDOM % 256)) +NSIM_DEV_2_ID=$((512 + RANDOM % 256)) +NSIM_DEV_SYS_NEW="/sys/bus/netdevsim/new_device" + +# Used to create and delete namespaces +source "${LIBDIR}"/../../../../net/lib.sh +source "${LIBDIR}"/../../../../net/net_helper.sh + +# Create netdevsim interfaces +create_ifaces() { + + echo "$NSIM_DEV_2_ID" > "$NSIM_DEV_SYS_NEW" + echo "$NSIM_DEV_1_ID" > "$NSIM_DEV_SYS_NEW" + udevadm settle 2> /dev/null || true + + local NSIM1=/sys/bus/netdevsim/devices/netdevsim"$NSIM_DEV_1_ID" + local NSIM2=/sys/bus/netdevsim/devices/netdevsim"$NSIM_DEV_2_ID" + + # These are global variables + SRCIF=$(find "$NSIM1"/net -maxdepth 1 -type d ! \ + -path "$NSIM1"/net -exec basename {} \;) + DSTIF=$(find "$NSIM2"/net -maxdepth 1 -type d ! \ + -path "$NSIM2"/net -exec basename {} \;) +} + +link_ifaces() { + local NSIM_DEV_SYS_LINK="/sys/bus/netdevsim/link_device" + local SRCIF_IFIDX=$(cat /sys/class/net/"$SRCIF"/ifindex) + local DSTIF_IFIDX=$(cat /sys/class/net/"$DSTIF"/ifindex) + + exec {NAMESPACE_FD} $NSIM_DEV_SYS_LINK + then + echo "linking netdevsim1 with netdevsim2 should succeed" + cleanup + exit "${ksft_skip}" + fi +} + +function configure_ip() { + # Configure the IPs for both interfaces + ip netns exec "${NAMESPACE}" ip addr add "${DSTIP}"/24 dev "${DSTIF}" + ip netns exec "${NAMESPACE}" ip link set "${DSTIF}" up + + ip addr add "${SRCIP}"/24 dev "${SRCIF}" + ip link set "${SRCIF}" up +} + +function set_network() { + # setup_ns function is coming from lib.sh + setup_ns NAMESPACE + + # Create both interfaces, and assign the destination to a different + # namespace + create_ifaces + + # Link both interfaces back to back + link_ifaces + + configure_ip +} + +function create_dynamic_target() { + DSTMAC=$(ip netns exec "${NAMESPACE}" \ + ip link show "${DSTIF}" | awk '/ether/ {print $2}') + + # Create a dynamic target + mkdir "${NETCONS_PATH}" + + echo "${DSTIP}" > "${NETCONS_PATH}"/remote_ip + echo "${SRCIP}" > "${NETCONS_PATH}"/local_ip + echo "${DSTMAC}" > "${NETCONS_PATH}"/remote_mac + echo "${SRCIF}" > "${NETCONS_PATH}"/dev_name + + echo 1 > "${NETCONS_PATH}"/enabled +} + +function cleanup() { + local NSIM_DEV_SYS_DEL="/sys/bus/netdevsim/del_device" + + # delete netconsole dynamic reconfiguration + echo 0 > "${NETCONS_PATH}"/enabled + # Remove key + rmdir "${KEY_PATH}" + # Remove the configfs entry + rmdir "${NETCONS_PATH}" + + # Delete netdevsim devices + echo "$NSIM_DEV_2_ID" > "$NSIM_DEV_SYS_DEL" + echo "$NSIM_DEV_1_ID" > "$NSIM_DEV_SYS_DEL" + + # this is coming from lib.sh + cleanup_all_ns + + # Restoring printk configurations + echo "${DEFAULT_PRINTK_VALUES}" > /proc/sys/kernel/printk +} + +function set_user_data() { + if [[ ! -d "${NETCONS_PATH}""/userdata" ]] + then + echo "Userdata path not available in ${NETCONS_PATH}/userdata" + exit "${ksft_skip}" + fi + + mkdir -p "${KEY_PATH}" + VALUE_PATH="${KEY_PATH}""/value" + echo "${USERDATA_VALUE}" > "${VALUE_PATH}" +} + +function listen_port_and_save_to() { + local OUTPUT=${1} + # Just wait for 2 seconds + timeout 2 ip netns exec "${NAMESPACE}" \ + socat UDP-LISTEN:"${PORT}",fork "${OUTPUT}" +} + +function validate_result() { + local TMPFILENAME="$1" + + # TMPFILENAME will contain something like: + # 6.11.1-0_fbk0_rc13_509_g30d75cea12f7,13,1822,115075213798,-;netconsole selftest: netcons_gtJHM + # key=value + + # Check if the file exists + if [ ! -f "$TMPFILENAME" ]; then + echo "FAIL: File was not generated." >&2 + exit "${ksft_fail}" + fi + + if ! grep -q "${MSG}" "${TMPFILENAME}"; then + echo "FAIL: ${MSG} not found in ${TMPFILENAME}" >&2 + cat "${TMPFILENAME}" >&2 + exit "${ksft_fail}" + fi + + if ! grep -q "${USERDATA_KEY}=${USERDATA_VALUE}" "${TMPFILENAME}"; then + echo "FAIL: ${USERDATA_KEY}=${USERDATA_VALUE} not found in ${TMPFILENAME}" >&2 + cat "${TMPFILENAME}" >&2 + exit "${ksft_fail}" + fi + + # Delete the file once it is validated, otherwise keep it + # for debugging purposes + rm "${TMPFILENAME}" + exit "${ksft_pass}" +} + +function check_for_dependencies() { + if [ "$(id -u)" -ne 0 ]; then + echo "This test must be run as root" >&2 + exit "${ksft_skip}" + fi + + if ! which socat > /dev/null ; then + echo "SKIP: socat(1) is not available" >&2 + exit "${ksft_skip}" + fi + + if ! which ip > /dev/null ; then + echo "SKIP: ip(1) is not available" >&2 + exit "${ksft_skip}" + fi + + if ! which udevadm > /dev/null ; then + echo "SKIP: udevadm(1) is not available" >&2 + exit "${ksft_skip}" + fi + + if [ ! -f "${NSIM_DEV_SYS_NEW}" ]; then + echo "SKIP: file ${NSIM_DEV_SYS_NEW} does not exist. Check if CONFIG_NETDEVSIM is enabled" >&2 + exit "${ksft_skip}" + fi + + if [ ! -d "${NETCONS_CONFIGFS}" ]; then + echo "SKIP: directory ${NETCONS_CONFIGFS} does not exist. Check if NETCONSOLE_DYNAMIC is enabled" >&2 + exit "${ksft_skip}" + fi + + if ip link show "${DSTIF}" 2> /dev/null; then + echo "SKIP: interface ${DSTIF} exists in the system. Not overwriting it." >&2 + exit "${ksft_skip}" + fi + + if ip addr list | grep -E "inet.*(${SRCIP}|${DSTIP})" 2> /dev/null; then + echo "SKIP: IPs already in use. Skipping it" >&2 + exit "${ksft_skip}" + fi +} diff --git a/tools/testing/selftests/drivers/net/netcons_basic.sh b/tools/testing/selftests/drivers/net/netcons_basic.sh index b175f4d966e5..fe765da498e8 100755 --- a/tools/testing/selftests/drivers/net/netcons_basic.sh +++ b/tools/testing/selftests/drivers/net/netcons_basic.sh @@ -18,224 +18,8 @@ set -euo pipefail SCRIPTDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")") -# Simple script to test dynamic targets in netconsole -SRCIF="" # to be populated later -SRCIP=192.0.2.1 -DSTIF="" # to be populated later -DSTIP=192.0.2.2 +source "${SCRIPTDIR}"/lib/sh/lib_netcons.sh -PORT="6666" -MSG="netconsole selftest" -USERDATA_KEY="key" -USERDATA_VALUE="value" -TARGET=$(mktemp -u netcons_XXXXX) -DEFAULT_PRINTK_VALUES=$(cat /proc/sys/kernel/printk) -NETCONS_CONFIGFS="/sys/kernel/config/netconsole" -NETCONS_PATH="${NETCONS_CONFIGFS}"/"${TARGET}" -KEY_PATH="${NETCONS_PATH}/userdata/${USERDATA_KEY}" -# NAMESPACE will be populated by setup_ns with a random value -NAMESPACE="" - -# IDs for netdevsim -NSIM_DEV_1_ID=$((256 + RANDOM % 256)) -NSIM_DEV_2_ID=$((512 + RANDOM % 256)) -NSIM_DEV_SYS_NEW="/sys/bus/netdevsim/new_device" - -# Used to create and delete namespaces -source "${SCRIPTDIR}"/../../net/lib.sh -source "${SCRIPTDIR}"/../../net/net_helper.sh - -# Create netdevsim interfaces -create_ifaces() { - - echo "$NSIM_DEV_2_ID" > "$NSIM_DEV_SYS_NEW" - echo "$NSIM_DEV_1_ID" > "$NSIM_DEV_SYS_NEW" - udevadm settle 2> /dev/null || true - - local NSIM1=/sys/bus/netdevsim/devices/netdevsim"$NSIM_DEV_1_ID" - local NSIM2=/sys/bus/netdevsim/devices/netdevsim"$NSIM_DEV_2_ID" - - # These are global variables - SRCIF=$(find "$NSIM1"/net -maxdepth 1 -type d ! \ - -path "$NSIM1"/net -exec basename {} \;) - DSTIF=$(find "$NSIM2"/net -maxdepth 1 -type d ! \ - -path "$NSIM2"/net -exec basename {} \;) -} - -link_ifaces() { - local NSIM_DEV_SYS_LINK="/sys/bus/netdevsim/link_device" - local SRCIF_IFIDX=$(cat /sys/class/net/"$SRCIF"/ifindex) - local DSTIF_IFIDX=$(cat /sys/class/net/"$DSTIF"/ifindex) - - exec {NAMESPACE_FD} $NSIM_DEV_SYS_LINK - then - echo "linking netdevsim1 with netdevsim2 should succeed" - cleanup - exit "${ksft_skip}" - fi -} - -function configure_ip() { - # Configure the IPs for both interfaces - ip netns exec "${NAMESPACE}" ip addr add "${DSTIP}"/24 dev "${DSTIF}" - ip netns exec "${NAMESPACE}" ip link set "${DSTIF}" up - - ip addr add "${SRCIP}"/24 dev "${SRCIF}" - ip link set "${SRCIF}" up -} - -function set_network() { - # setup_ns function is coming from lib.sh - setup_ns NAMESPACE - - # Create both interfaces, and assign the destination to a different - # namespace - create_ifaces - - # Link both interfaces back to back - link_ifaces - - configure_ip -} - -function create_dynamic_target() { - DSTMAC=$(ip netns exec "${NAMESPACE}" \ - ip link show "${DSTIF}" | awk '/ether/ {print $2}') - - # Create a dynamic target - mkdir "${NETCONS_PATH}" - - echo "${DSTIP}" > "${NETCONS_PATH}"/remote_ip - echo "${SRCIP}" > "${NETCONS_PATH}"/local_ip - echo "${DSTMAC}" > "${NETCONS_PATH}"/remote_mac - echo "${SRCIF}" > "${NETCONS_PATH}"/dev_name - - echo 1 > "${NETCONS_PATH}"/enabled -} - -function cleanup() { - local NSIM_DEV_SYS_DEL="/sys/bus/netdevsim/del_device" - - # delete netconsole dynamic reconfiguration - echo 0 > "${NETCONS_PATH}"/enabled - # Remove key - rmdir "${KEY_PATH}" - # Remove the configfs entry - rmdir "${NETCONS_PATH}" - - # Delete netdevsim devices - echo "$NSIM_DEV_2_ID" > "$NSIM_DEV_SYS_DEL" - echo "$NSIM_DEV_1_ID" > "$NSIM_DEV_SYS_DEL" - - # this is coming from lib.sh - cleanup_all_ns - - # Restoring printk configurations - echo "${DEFAULT_PRINTK_VALUES}" > /proc/sys/kernel/printk -} - -function set_user_data() { - if [[ ! -d "${NETCONS_PATH}""/userdata" ]] - then - echo "Userdata path not available in ${NETCONS_PATH}/userdata" - exit "${ksft_skip}" - fi - - mkdir -p "${KEY_PATH}" - VALUE_PATH="${KEY_PATH}""/value" - echo "${USERDATA_VALUE}" > "${VALUE_PATH}" -} - -function listen_port_and_save_to() { - local OUTPUT=${1} - # Just wait for 2 seconds - timeout 2 ip netns exec "${NAMESPACE}" \ - socat UDP-LISTEN:"${PORT}",fork "${OUTPUT}" -} - -function validate_result() { - local TMPFILENAME="$1" - - # TMPFILENAME will contain something like: - # 6.11.1-0_fbk0_rc13_509_g30d75cea12f7,13,1822,115075213798,-;netconsole selftest: netcons_gtJHM - # key=value - - # Check if the file exists - if [ ! -f "$TMPFILENAME" ]; then - echo "FAIL: File was not generated." >&2 - exit "${ksft_fail}" - fi - - if ! grep -q "${MSG}" "${TMPFILENAME}"; then - echo "FAIL: ${MSG} not found in ${TMPFILENAME}" >&2 - cat "${TMPFILENAME}" >&2 - exit "${ksft_fail}" - fi - - if ! grep -q "${USERDATA_KEY}=${USERDATA_VALUE}" "${TMPFILENAME}"; then - echo "FAIL: ${USERDATA_KEY}=${USERDATA_VALUE} not found in ${TMPFILENAME}" >&2 - cat "${TMPFILENAME}" >&2 - exit "${ksft_fail}" - fi - - # Delete the file once it is validated, otherwise keep it - # for debugging purposes - rm "${TMPFILENAME}" - exit "${ksft_pass}" -} - -function check_for_dependencies() { - if [ "$(id -u)" -ne 0 ]; then - echo "This test must be run as root" >&2 - exit "${ksft_skip}" - fi - - if ! which socat > /dev/null ; then - echo "SKIP: socat(1) is not available" >&2 - exit "${ksft_skip}" - fi - - if ! which ip > /dev/null ; then - echo "SKIP: ip(1) is not available" >&2 - exit "${ksft_skip}" - fi - - if ! which udevadm > /dev/null ; then - echo "SKIP: udevadm(1) is not available" >&2 - exit "${ksft_skip}" - fi - - if [ ! -f "${NSIM_DEV_SYS_NEW}" ]; then - echo "SKIP: file ${NSIM_DEV_SYS_NEW} does not exist. Check if CONFIG_NETDEVSIM is enabled" >&2 - exit "${ksft_skip}" - fi - - if [ ! -d "${NETCONS_CONFIGFS}" ]; then - echo "SKIP: directory ${NETCONS_CONFIGFS} does not exist. Check if NETCONSOLE_DYNAMIC is enabled" >&2 - exit "${ksft_skip}" - fi - - if ip link show "${DSTIF}" 2> /dev/null; then - echo "SKIP: interface ${DSTIF} exists in the system. Not overwriting it." >&2 - exit "${ksft_skip}" - fi - - if ip addr list | grep -E "inet.*(${SRCIP}|${DSTIP})" 2> /dev/null; then - echo "SKIP: IPs already in use. Skipping it" >&2 - exit "${ksft_skip}" - fi -} - -# ========== # -# Start here # -# ========== # modprobe netdevsim 2> /dev/null || true modprobe netconsole 2> /dev/null || true -- 2.50.1 From 7dcb65351b30500a759c857590b73b98c05ac7fd Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Wed, 8 Jan 2025 03:50:27 -0800 Subject: [PATCH 11/16] netconsole: selftest: Delete all userdata keys Modify the cleanup function to remove all userdata keys created during the test, instead of just deleting a single predefined key. This ensures a more thorough cleanup of temporary resources. Move the KEY_PATH variable definition inside the set_user_data function to reduce global variables and improve encapsulation. The KEY_PATH variable is now dynamically created when setting user data. This change has no effect on the current test, while improving an upcoming test that would create several userdata entries. Signed-off-by: Breno Leitao Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250108-netcons_overflow_test-v3-3-3d85eb091bec@debian.org Signed-off-by: Jakub Kicinski --- tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh index fdd45a3468f1..3acaba41ac7b 100644 --- a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh +++ b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh @@ -23,7 +23,6 @@ TARGET=$(mktemp -u netcons_XXXXX) DEFAULT_PRINTK_VALUES=$(cat /proc/sys/kernel/printk) NETCONS_CONFIGFS="/sys/kernel/config/netconsole" NETCONS_PATH="${NETCONS_CONFIGFS}"/"${TARGET}" -KEY_PATH="${NETCONS_PATH}/userdata/${USERDATA_KEY}" # NAMESPACE will be populated by setup_ns with a random value NAMESPACE="" @@ -116,8 +115,8 @@ function cleanup() { # delete netconsole dynamic reconfiguration echo 0 > "${NETCONS_PATH}"/enabled - # Remove key - rmdir "${KEY_PATH}" + # Remove all the keys that got created during the selftest + find "${NETCONS_PATH}/userdata/" -mindepth 1 -type d -delete # Remove the configfs entry rmdir "${NETCONS_PATH}" @@ -139,6 +138,7 @@ function set_user_data() { exit "${ksft_skip}" fi + KEY_PATH="${NETCONS_PATH}/userdata/${USERDATA_KEY}" mkdir -p "${KEY_PATH}" VALUE_PATH="${KEY_PATH}""/value" echo "${USERDATA_VALUE}" > "${VALUE_PATH}" -- 2.50.1 From daea6d23cd2f99a0c70e871a27d473f3ad48845b Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Wed, 8 Jan 2025 03:50:28 -0800 Subject: [PATCH 12/16] netconsole: selftest: verify userdata entry limit Add a new selftest for netconsole that tests the userdata entry limit functionality. The test performs two key verifications: 1. Create MAX_USERDATA_ITEMS (16) userdata entries successfully 2. Confirm that attempting to create an additional userdata entry fails The selftest script uses the netcons library and checks the behavior by attempting to create entries beyond the maximum allowed limit. Signed-off-by: Breno Leitao Tested-by: Simon Horman Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250108-netcons_overflow_test-v3-4-3d85eb091bec@debian.org Signed-off-by: Jakub Kicinski --- MAINTAINERS | 2 +- tools/testing/selftests/drivers/net/Makefile | 1 + .../selftests/drivers/net/netcons_overflow.sh | 67 +++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100755 tools/testing/selftests/drivers/net/netcons_overflow.sh diff --git a/MAINTAINERS b/MAINTAINERS index 7a88872fada8..3f3e289b391c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16171,7 +16171,7 @@ S: Maintained F: Documentation/networking/netconsole.rst F: drivers/net/netconsole.c F: tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh -F: tools/testing/selftests/drivers/net/netcons_basic.sh +F: tools/testing/selftests/drivers/net/netcons\* NETDEVSIM M: Jakub Kicinski diff --git a/tools/testing/selftests/drivers/net/Makefile b/tools/testing/selftests/drivers/net/Makefile index dafff5d7fe88..469179c18935 100644 --- a/tools/testing/selftests/drivers/net/Makefile +++ b/tools/testing/selftests/drivers/net/Makefile @@ -7,6 +7,7 @@ TEST_INCLUDES := $(wildcard lib/py/*.py) \ TEST_PROGS := \ netcons_basic.sh \ + netcons_overflow.sh \ ping.py \ queues.py \ stats.py \ diff --git a/tools/testing/selftests/drivers/net/netcons_overflow.sh b/tools/testing/selftests/drivers/net/netcons_overflow.sh new file mode 100755 index 000000000000..29bad56448a2 --- /dev/null +++ b/tools/testing/selftests/drivers/net/netcons_overflow.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: GPL-2.0 + +# This test verifies that users can successfully create up to +# MAX_USERDATA_ITEMS userdata entries without encountering any failures. +# +# Additionally, it tests for expected failure when attempting to exceed this +# maximum limit. +# +# Author: Breno Leitao + +set -euo pipefail + +SCRIPTDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")") + +source "${SCRIPTDIR}"/lib/sh/lib_netcons.sh +# This is coming from netconsole code. Check for it in drivers/net/netconsole.c +MAX_USERDATA_ITEMS=16 + +# Function to create userdata entries +function create_userdata_max_entries() { + # All these keys should be created without any error + for i in $(seq $MAX_USERDATA_ITEMS) + do + # USERDATA_KEY is used by set_user_data + USERDATA_KEY="key"${i} + set_user_data + done +} + +# Function to verify the entry limit +function verify_entry_limit() { + # Allowing the test to fail without exiting, since the next command + # will fail + set +e + mkdir "${NETCONS_PATH}/userdata/key_that_will_fail" 2> /dev/null + ret="$?" + set -e + if [ "$ret" -eq 0 ]; + then + echo "Adding more than ${MAX_USERDATA_ITEMS} entries in userdata should fail, but it didn't" >&2 + ls "${NETCONS_PATH}/userdata/" >&2 + exit "${ksft_fail}" + fi +} + +# ========== # +# Start here # +# ========== # + +modprobe netdevsim 2> /dev/null || true +modprobe netconsole 2> /dev/null || true + +# Check for basic system dependency and exit if not found +check_for_dependencies + +# Remove the namespace, interfaces and netconsole target on exit +trap cleanup EXIT +# Create one namespace and two interfaces +set_network +# Create a dynamic target for netconsole +create_dynamic_target +# populate the maximum number of supported keys in userdata +create_userdata_max_entries +# Verify an additional entry is not allowed +verify_entry_limit +exit "${ksft_pass}" -- 2.50.1 From 25cc469d6d344f5772e9fb6a5cf9d82a690afe68 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 7 Jan 2025 21:13:44 +0100 Subject: [PATCH 13/16] net: phy: micrel: use helper phy_disable_eee Use helper phy_disable_eee() instead of setting phylib-internal bitmap eee_broken_modes directly. Signed-off-by: Heiner Kallweit Link: https://patch.msgid.link/5e19eebe-121e-4a41-b36d-a35631279dd8@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/phy/micrel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index eeb33eb181ac..0fd1cb676cd5 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -2006,7 +2006,7 @@ static int ksz9477_config_init(struct phy_device *phydev) * in this switch shall be regarded as broken. */ if (phydev->dev_flags & MICREL_NO_EEE) - linkmode_fill(phydev->eee_broken_modes); + phy_disable_eee(phydev); return kszphy_config_init(phydev); } -- 2.50.1 From 9007d911f6d2a99d3dd1dbf2097de35727cc665a Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Thu, 9 Jan 2025 12:21:17 -0600 Subject: [PATCH 14/16] net: dsa: qca8k: Use of_property_present() for non-boolean properties The use of of_property_read_bool() for non-boolean properties is deprecated in favor of of_property_present() when testing for property presence. Signed-off-by: Rob Herring (Arm) Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/dsa/qca/qca8k-8xxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c index 2d56a8152420..750fc76a6e11 100644 --- a/drivers/net/dsa/qca/qca8k-8xxx.c +++ b/drivers/net/dsa/qca/qca8k-8xxx.c @@ -1019,7 +1019,7 @@ qca8k_setup_mdio_bus(struct qca8k_priv *priv) of_get_phy_mode(port, &mode); - if (of_property_read_bool(port, "phy-handle") && + if (of_property_present(port, "phy-handle") && mode != PHY_INTERFACE_MODE_INTERNAL) external_mdio_mask |= BIT(reg); else -- 2.50.1 From 89aca45f26879dfbbf8374c425c4811f69cfc2df Mon Sep 17 00:00:00 2001 From: Shayne Chen Date: Mon, 7 Oct 2024 21:51:33 +0800 Subject: [PATCH 15/16] wifi: mt76: mt7996: fix invalid interface combinations Setting beacon_int_min_gcd and NL80211_IFTYPE_ADHOC in the same interface combination is invalid, which will trigger the following warning trace and get error returned from wiphy_register(). [ 10.080325] Call trace: [ 10.082761] wiphy_register+0xc4/0x76c [cfg80211] [ 10.087465] ieee80211_register_hw+0x800/0xac4 [mac80211] [ 10.092868] mt76_register_device+0x16c/0x2c0 [mt76] [ 10.097829] mt7996_register_device+0x740/0x844 [mt7996e] Fix this by removing unused adhoc iftype. Fixes: 948f65249868 ("wifi: mt76: mt7996: advertize beacon_int_min_gcd") Reported-by: Frank Wunderlich Signed-off-by: Shayne Chen Tested-By: Frank Wunderlich Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20241007135133.5336-1-shayne.chen@mediatek.com --- drivers/net/wireless/mediatek/mt76/mt7996/init.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c index 5e96973226bb..efa7b0697a40 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c @@ -16,9 +16,6 @@ static const struct ieee80211_iface_limit if_limits[] = { { - .max = 1, - .types = BIT(NL80211_IFTYPE_ADHOC) - }, { .max = 16, .types = BIT(NL80211_IFTYPE_AP) #ifdef CONFIG_MAC80211_MESH -- 2.50.1 From 1be94490b6b8a06ff14cd23fda8714e6ec37cdfb Mon Sep 17 00:00:00 2001 From: =?utf8?q?Alexis=20Lothor=C3=A9?= Date: Mon, 23 Dec 2024 16:46:48 +0100 Subject: [PATCH 16/16] wifi: wilc1000: unregister wiphy only if it has been registered MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit There is a specific error path in probe functions in wilc drivers (both sdio and spi) which can lead to kernel panic, as this one for example when using SPI: Unable to handle kernel paging request at virtual address 9f000000 when read [9f000000] *pgd=00000000 Internal error: Oops: 5 [#1] ARM Modules linked in: wilc1000_spi(+) crc_itu_t crc7 wilc1000 cfg80211 bluetooth ecdh_generic ecc CPU: 0 UID: 0 PID: 106 Comm: modprobe Not tainted 6.13.0-rc3+ #22 Hardware name: Atmel SAMA5 PC is at wiphy_unregister+0x244/0xc40 [cfg80211] LR is at wiphy_unregister+0x1c0/0xc40 [cfg80211] [...] wiphy_unregister [cfg80211] from wilc_netdev_cleanup+0x380/0x494 [wilc1000] wilc_netdev_cleanup [wilc1000] from wilc_bus_probe+0x360/0x834 [wilc1000_spi] wilc_bus_probe [wilc1000_spi] from spi_probe+0x15c/0x1d4 spi_probe from really_probe+0x270/0xb2c really_probe from __driver_probe_device+0x1dc/0x4e8 __driver_probe_device from driver_probe_device+0x5c/0x140 driver_probe_device from __driver_attach+0x220/0x540 __driver_attach from bus_for_each_dev+0x13c/0x1a8 bus_for_each_dev from bus_add_driver+0x2a0/0x6a4 bus_add_driver from driver_register+0x27c/0x51c driver_register from do_one_initcall+0xf8/0x564 do_one_initcall from do_init_module+0x2e4/0x82c do_init_module from load_module+0x59a0/0x70c4 load_module from init_module_from_file+0x100/0x148 init_module_from_file from sys_finit_module+0x2fc/0x924 sys_finit_module from ret_fast_syscall+0x0/0x1c The issue can easily be reproduced, for example by not wiring correctly a wilc device through SPI (and so, make it unresponsive to early SPI commands). It is due to a recent change decoupling wiphy allocation from wiphy registration, however wilc_netdev_cleanup has not been updated accordingly, letting it possibly call wiphy unregister on a wiphy which has never been registered. Fix this crash by moving wiphy_unregister/wiphy_free out of wilc_netdev_cleanup, and by adjusting error paths in both drivers Fixes: fbdf0c5248dc ("wifi: wilc1000: Register wiphy after reading out chipid") Signed-off-by: Alexis Lothoré Reviewed-by: Marek Vasut Signed-off-by: Kalle Valo Link: https://patch.msgid.link/20241223-wilc_fix_probe_error_path-v1-1-91fa7bd8e5b6@bootlin.com --- drivers/net/wireless/microchip/wilc1000/netdev.c | 2 -- drivers/net/wireless/microchip/wilc1000/sdio.c | 9 +++++++-- drivers/net/wireless/microchip/wilc1000/spi.c | 9 +++++++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c index 7e84fc0fd911..af298021e050 100644 --- a/drivers/net/wireless/microchip/wilc1000/netdev.c +++ b/drivers/net/wireless/microchip/wilc1000/netdev.c @@ -925,8 +925,6 @@ void wilc_netdev_cleanup(struct wilc *wilc) wilc_wlan_cfg_deinit(wilc); wlan_deinit_locks(wilc); - wiphy_unregister(wilc->wiphy); - wiphy_free(wilc->wiphy); } EXPORT_SYMBOL_GPL(wilc_netdev_cleanup); diff --git a/drivers/net/wireless/microchip/wilc1000/sdio.c b/drivers/net/wireless/microchip/wilc1000/sdio.c index 5262c8846c13..3751e2ee1ca9 100644 --- a/drivers/net/wireless/microchip/wilc1000/sdio.c +++ b/drivers/net/wireless/microchip/wilc1000/sdio.c @@ -193,7 +193,7 @@ static int wilc_sdio_probe(struct sdio_func *func, ret = wilc_load_mac_from_nv(wilc); if (ret) { pr_err("Can not retrieve MAC address from chip\n"); - goto dispose_irq; + goto unregister_wiphy; } wilc_sdio_deinit(wilc); @@ -202,15 +202,18 @@ static int wilc_sdio_probe(struct sdio_func *func, NL80211_IFTYPE_STATION, false); if (IS_ERR(vif)) { ret = PTR_ERR(vif); - goto dispose_irq; + goto unregister_wiphy; } dev_info(&func->dev, "Driver Initializing success\n"); return 0; +unregister_wiphy: + wiphy_unregister(wilc->wiphy); dispose_irq: irq_dispose_mapping(wilc->dev_irq_num); wilc_netdev_cleanup(wilc); + wiphy_free(wilc->wiphy); free: kfree(sdio_priv->cmd53_buf); kfree(sdio_priv); @@ -222,7 +225,9 @@ static void wilc_sdio_remove(struct sdio_func *func) struct wilc *wilc = sdio_get_drvdata(func); struct wilc_sdio *sdio_priv = wilc->bus_data; + wiphy_unregister(wilc->wiphy); wilc_netdev_cleanup(wilc); + wiphy_free(wilc->wiphy); kfree(sdio_priv->cmd53_buf); kfree(sdio_priv); } diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c index ce2a9cdd6aa7..31219fd0cfb3 100644 --- a/drivers/net/wireless/microchip/wilc1000/spi.c +++ b/drivers/net/wireless/microchip/wilc1000/spi.c @@ -256,7 +256,7 @@ static int wilc_bus_probe(struct spi_device *spi) ret = wilc_load_mac_from_nv(wilc); if (ret) { pr_err("Can not retrieve MAC address from chip\n"); - goto power_down; + goto unregister_wiphy; } wilc_wlan_power(wilc, false); @@ -264,14 +264,17 @@ static int wilc_bus_probe(struct spi_device *spi) NL80211_IFTYPE_STATION, false); if (IS_ERR(vif)) { ret = PTR_ERR(vif); - goto power_down; + goto unregister_wiphy; } return 0; +unregister_wiphy: + wiphy_unregister(wilc->wiphy); power_down: wilc_wlan_power(wilc, false); netdev_cleanup: wilc_netdev_cleanup(wilc); + wiphy_free(wilc->wiphy); free: kfree(spi_priv); return ret; @@ -282,7 +285,9 @@ static void wilc_bus_remove(struct spi_device *spi) struct wilc *wilc = spi_get_drvdata(spi); struct wilc_spi *spi_priv = wilc->bus_data; + wiphy_unregister(wilc->wiphy); wilc_netdev_cleanup(wilc); + wiphy_free(wilc->wiphy); kfree(spi_priv); } -- 2.50.1