diff --git a/s390-tools-01-opticsmon-Fix-runaway-loop-in-on_link_change.patch b/s390-tools-01-opticsmon-Fix-runaway-loop-in-on_link_change.patch new file mode 100644 index 0000000..1433eb5 --- /dev/null +++ b/s390-tools-01-opticsmon-Fix-runaway-loop-in-on_link_change.patch @@ -0,0 +1,64 @@ +From dff965465ca9d9c4edaf0f90eadd9a6de335b354 Mon Sep 17 00:00:00 2001 +From: Niklas Schnelle +Date: Fri, 6 Dec 2024 15:28:08 +0100 +Subject: [PATCH] opticsmon: Fix runaway loop in on_link_change() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When on_link_change() gets called with a netdev that would be monitored +but hasn't entered zpci_list yet, reloads is 1 after the loops and +a reload occurs. Then the netdev is found in the list and reloads +becomes -1 which incorrectly triggers more reloads until underflow. +Fix this by returning once the device is found. Also just check for +reloads being larger than zero. + +Fixes: c34adb9cabee ("opticsmon: Introduce opticsmon tool") +Reviewed-by: Halil Pasic +Signed-off-by: Niklas Schnelle +Signed-off-by: Jan Höppner +--- + opticsmon/opticsmon.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/opticsmon/opticsmon.c b/opticsmon/opticsmon.c +index c2f355e2..50dd8d7f 100644 +--- a/opticsmon/opticsmon.c ++++ b/opticsmon/opticsmon.c +@@ -280,16 +280,15 @@ void on_link_change(struct zpci_netdev *netdev, void *arg) + if (!ctx->zpci_list || util_list_is_empty(ctx->zpci_list)) + zpci_list_reload(&ctx->zpci_list); + +-reload: ++find: + util_list_iterate(ctx->zpci_list, zdev) { + for (i = 0; i < zdev->num_netdevs; i++) { + if (!strcmp(zdev->netdevs[i].name, netdev->name)) { +- reloads--; + /* Skip data collection if operational state is + * unchanged + */ + if (zdev->netdevs[i].operstate == netdev->operstate) +- continue; ++ return; + /* Update operation state for VFs even though + * they are skipped just for a consistent view + */ +@@ -297,14 +296,15 @@ void on_link_change(struct zpci_netdev *netdev, void *arg) + /* Only collect optics data for PFs */ + if (!zpci_is_vf(zdev)) + dump_adapter_data(ctx, zdev); ++ return; + } + } + } + /* Might be a new device, reload list of devices and retry */ +- if (reloads) { ++ if (reloads > 0) { + zpci_list_reload(&ctx->zpci_list); + reloads--; +- goto reload; ++ goto find; + } + } + diff --git a/s390-tools-02-libzpci-opticsmon-Refactor-on_link_change-using-new.patch b/s390-tools-02-libzpci-opticsmon-Refactor-on_link_change-using-new.patch new file mode 100644 index 0000000..7c711cc --- /dev/null +++ b/s390-tools-02-libzpci-opticsmon-Refactor-on_link_change-using-new.patch @@ -0,0 +1,129 @@ +From cf5560a100b5552e2eeeaac9c60a88ae77233530 Mon Sep 17 00:00:00 2001 +From: Niklas Schnelle +Date: Mon, 9 Dec 2024 15:08:03 +0100 +Subject: [PATCH] libzpci: opticsmon: Refactor on_link_change() using new + zpci_find_by_netdev() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Finding a PCI device given the name of a netdev seems generally useful +so pull this out into a new zpci_find_by_netdev() function in libzpci +and use this to simplify on_link_change() removing the need for +backwards goto. + +Reviewed-by: Halil Pasic +Reviewed-by: Jan Höppner +Signed-off-by: Niklas Schnelle +Signed-off-by: Jan Höppner +--- + include/lib/pci_list.h | 3 +++ + libzpci/pci_list.c | 31 +++++++++++++++++++++++++++++++ + opticsmon/opticsmon.c | 27 +++++++++++---------------- + 3 files changed, 45 insertions(+), 16 deletions(-) + +diff --git a/include/lib/pci_list.h b/include/lib/pci_list.h +index 829ec244..5b2918bc 100644 +--- a/include/lib/pci_list.h ++++ b/include/lib/pci_list.h +@@ -93,4 +93,7 @@ const char *zpci_pft_str(struct zpci_dev *zdev); + const char *zpci_operstate_str(operstate_t state); + operstate_t zpci_operstate_from_str(const char *oper_str); + ++struct zpci_dev *zpci_find_by_netdev(struct util_list *zpci_list, char *netdev_name, ++ struct zpci_netdev **netdev); ++ + #endif /* LIB_ZPCI_PCI_LIST_H */ +diff --git a/libzpci/pci_list.c b/libzpci/pci_list.c +index 10f64e89..e0d56e44 100644 +--- a/libzpci/pci_list.c ++++ b/libzpci/pci_list.c +@@ -356,3 +356,34 @@ void zpci_free_dev_list(struct util_list *zpci_list) + } + util_list_free(zpci_list); + } ++ ++/** ++ * Find a PCI device given the name of a netdev ++ * ++ * This function allows finding a PCI device when only the name of one ++ * of its netdevs is known. ++ * ++ * @param[in] zpci_list The device list to search ++ * @param[in] netdev_name The name of the netdev ++ * @param[out] netdev Pointer to store the netdev or NULL if ++ * only the PCI device is needed ++ * ++ * @return The PCI device if one is found NULL otherwise ++ */ ++struct zpci_dev *zpci_find_by_netdev(struct util_list *zpci_list, char *netdev_name, ++ struct zpci_netdev **netdev) ++{ ++ struct zpci_dev *zdev = NULL; ++ int i; ++ ++ util_list_iterate(zpci_list, zdev) { ++ for (i = 0; i < zdev->num_netdevs; i++) { ++ if (!strcmp(zdev->netdevs[i].name, netdev_name)) { ++ if (netdev) ++ *netdev = &zdev->netdevs[i]; ++ return zdev; ++ } ++ } ++ } ++ return NULL; ++} +diff --git a/opticsmon/opticsmon.c b/opticsmon/opticsmon.c +index 50dd8d7f..7ecaa125 100644 +--- a/opticsmon/opticsmon.c ++++ b/opticsmon/opticsmon.c +@@ -274,38 +274,33 @@ static int oneshot_mode(struct opticsmon_ctx *ctx) + void on_link_change(struct zpci_netdev *netdev, void *arg) + { + struct opticsmon_ctx *ctx = arg; +- struct zpci_dev *zdev; +- int i, reloads = 1; +- +- if (!ctx->zpci_list || util_list_is_empty(ctx->zpci_list)) +- zpci_list_reload(&ctx->zpci_list); ++ struct zpci_netdev *found_netdev; ++ struct zpci_dev *zdev = NULL; ++ int reloads = 1; + +-find: +- util_list_iterate(ctx->zpci_list, zdev) { +- for (i = 0; i < zdev->num_netdevs; i++) { +- if (!strcmp(zdev->netdevs[i].name, netdev->name)) { ++ do { ++ if (ctx->zpci_list) { ++ zdev = zpci_find_by_netdev(ctx->zpci_list, netdev->name, &found_netdev); ++ if (zdev) { + /* Skip data collection if operational state is + * unchanged + */ +- if (zdev->netdevs[i].operstate == netdev->operstate) ++ if (found_netdev->operstate == netdev->operstate) + return; + /* Update operation state for VFs even though + * they are skipped just for a consistent view + */ +- zdev->netdevs[i].operstate = netdev->operstate; ++ found_netdev->operstate = netdev->operstate; + /* Only collect optics data for PFs */ + if (!zpci_is_vf(zdev)) + dump_adapter_data(ctx, zdev); + return; + } + } +- } +- /* Might be a new device, reload list of devices and retry */ +- if (reloads > 0) { ++ /* Could be uninitalized list or a new device, retry after reload */ + zpci_list_reload(&ctx->zpci_list); + reloads--; +- goto find; +- } ++ } while (reloads > 0); + } + + #define MAX_EVENTS 8 diff --git a/s390-tools.changes b/s390-tools.changes index 0a3740a..c11f5d4 100644 --- a/s390-tools.changes +++ b/s390-tools.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Tue Dec 31 09:59:27 UTC 2024 - Nikolay Gueorguiev + +- Applied patches (jsc#PED-9591, jsc#PED-10303) + * s390-tools-01-opticsmon-Fix-runaway-loop-in-on_link_change.patch + * s390-tools-02-libzpci-opticsmon-Refactor-on_link_change-using-new.patch + ------------------------------------------------------------------- Mon Dec 9 09:49:52 UTC 2024 - Nikolay Gueorguiev diff --git a/s390-tools.spec b/s390-tools.spec index 676fbe7..2dd4d14 100644 --- a/s390-tools.spec +++ b/s390-tools.spec @@ -156,6 +156,9 @@ Patch913: s390-tools-sles15sp6-kdump-initrd-59-zfcp-compat-rules.patch Patch914: s390-tools-01-zipl_helper.device-mapper-add-missed-step-in-logical.patch Patch915: s390-tools-02-zipl-src-fix-imprecise-check-that-file-is-on-specifi.patch ### +Patch916: s390-tools-01-opticsmon-Fix-runaway-loop-in-on_link_change.patch +Patch917: s390-tools-02-libzpci-opticsmon-Refactor-on_link_change-using-new.patch +### Patch920: s390-tools-slfo-01-parse-ipl-device-for-activation.patch ###