From 3ade063ea2f958ae110b0f9ac7f5ef69abe70db1 Mon Sep 17 00:00:00 2001 From: Niklas Schnelle Date: Mon, 28 Mar 2022 12:18:01 +0200 Subject: [PATCH] zpcictl: Fix race of SCLP reset and Linux recovery MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently "zpcictl --reset DDDD:BB:FF.F" issues an SCLP call with SCLP_ERRNOTIFY_AQ_RESET followed by a Linux driven device reset via the recover sysfs attribute. The latter was introduced with commit bc0d40c5803d ("zpcictl: Initiate recover after reset") because the firmware driven reset leaves the device in the error state. Now with the addition of transparent PCI recovery however the situation has changed as Linux will not leave the device in the error state after the reset but will instead initiate its automatic recovery flow. With that however the two mechanisms, automatic PCI recovery and the zpcictl triggered recovery attribute handler will race against each other. In practice this is harmless as the automatic recovery is serialized with the recover attribute and whichever wins the race will do the reset. The losing side will detect that the original device was removed and will refrain from causing a double reset. Letting both mechanisms race against each other is not predictable behavior though so instead of SCLP_ERRNOTIFY_AQ_RESET issue a SCLP_ERRNOTIFY_AQ_REPORT_ERROR that will report a device error to the Support Element but not cause a reset and then predictably reset via the recover sysfs attribute. If instead a firmware driven reset followed by the automatic recovery flow is desired the new "--reset-fw" option may be used. Reviewed-by: Jan Höppner Signed-off-by: Niklas Schnelle Signed-off-by: Jan Höppner --- zpcictl/zpcictl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zpcictl/zpcictl.c b/zpcictl/zpcictl.c index cb02e332..2c4f2068 100644 --- a/zpcictl/zpcictl.c +++ b/zpcictl/zpcictl.c @@ -337,7 +337,7 @@ static void sclp_issue_action(struct zpci_device *pdev, int action) */ static void sclp_reset_device(struct zpci_device *pdev) { - sclp_issue_action(pdev, SCLP_ERRNOTIFY_AQ_RESET); + sclp_issue_action(pdev, SCLP_ERRNOTIFY_AQ_REPORT_ERR); sysfs_write_value(pdev, "recover", 1); }