From nobody Sat Feb 7 05:44:24 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 149F532C85; Fri, 5 Jul 2024 18:15:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.16 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720203323; cv=none; b=mGS8eBfI62VD5XD5XtDdrxJyz4aBRvBp9VFgQj0IISy/2GZoH/TvbZOaMXGJ0/R9PyMylClri+0X07bqh7se/57pS0XE/Nm3BXVCPqMU3OJ5muIIRG5XCE+uJW0GoqaBGsRSxLG7a7rLAiaWm7NcBNzZ4lgeELD6rN2FMwL1KxQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720203323; c=relaxed/simple; bh=eAqcbvZBW12oKX8Ej57NmOzehI48/9qfpOiRlYOqkyo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=LMU5YtdEA/6n2Kd8zW8XB/d3R3H4Y9egn3hEiKMcb60p5yXi+J5n+s4puuy14dAmwRUSeawViD1KYcIfvas1/KwtfYSldAgHjlPReEhYlQXHFwcPXw2aIE6+M9w0foWCjMaRsaMiAYB21M0YFJB76M6FND3vqI6wesn9dtx6XDg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=j/SuDYcs; arc=none smtp.client-ip=192.198.163.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="j/SuDYcs" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1720203322; x=1751739322; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=eAqcbvZBW12oKX8Ej57NmOzehI48/9qfpOiRlYOqkyo=; b=j/SuDYcsO2q85htFsCEyuppRXSTqZxd/RKHeXQ8sr30q4qnluza4ZjXb Dt4A8wX+ze/KtQkMXF3lgOVu4VKRHRqjfxUUudbRNhV/nMWBieAYjV9jt rE1Gh8ciDIh1yy6UlgskYj/V5IopS6EWj3jlIIMddo3JzFgNQHqiwijPx KfdZJDyPDd2QbdajIdO1FUEQbFUludZJBRtNTt5ygnzfyCioT8S5AxBr8 4yjG26pRumbA4py3sNYxLZ/soBI4Rw2pkz9mybuQq4n8/ZkqKezK2WQTn qz6JiV5W1xHxI+WeBhLdCpiT3P0se7xny9qZ8dlQ9qEgksut9drIM7rSJ Q==; X-CSE-ConnectionGUID: NHK4YA7GQtu8esjwe5nrqA== X-CSE-MsgGUID: YAi93fDvTtuHqmzleFLPHA== X-IronPort-AV: E=McAfee;i="6700,10204,11123"; a="12410718" X-IronPort-AV: E=Sophos;i="6.09,185,1716274800"; d="scan'208";a="12410718" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa110.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2024 11:15:19 -0700 X-CSE-ConnectionGUID: 1oUP/byjTs+eIA28nhFi1w== X-CSE-MsgGUID: IUYhmJCRS/Wal4Btkfhi1g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,185,1716274800"; d="scan'208";a="47672694" Received: from fyu1.sc.intel.com ([172.25.103.126]) by orviesa008.jf.intel.com with ESMTP; 05 Jul 2024 11:15:19 -0700 From: Fenghua Yu To: "Vinod Koul" , "Dave Jiang" Cc: dmaengine@vger.kernel.org, "linux-kernel" , Fenghua Yu Subject: [PATCH 1/5] dmaengine: idxd: Add idxd_pci_probe_alloc() helper Date: Fri, 5 Jul 2024 11:15:14 -0700 Message-Id: <20240705181519.4067507-2-fenghua.yu@intel.com> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20240705181519.4067507-1-fenghua.yu@intel.com> References: <20240705181519.4067507-1-fenghua.yu@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add the idxd_pci_probe_alloc() helper to probe IDXD PCI device with or without allocating and setting idxd software values. The idxd_pci_probe() function is refactored to call this helper and always probe the IDXD device with allocating and setting the software values. This helper will be called later in the Function Level Reset (FLR) process without modifying the idxd software data. Signed-off-by: Fenghua Yu --- drivers/dma/idxd/idxd.h | 2 + drivers/dma/idxd/init.c | 102 ++++++++++++++++++++++++---------------- 2 files changed, 64 insertions(+), 40 deletions(-) diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index 868b724a3b75..03f099518ec1 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -745,6 +745,8 @@ void idxd_unmask_error_interrupts(struct idxd_device *i= dxd); =20 /* device control */ int idxd_device_drv_probe(struct idxd_dev *idxd_dev); +int idxd_pci_probe_alloc(struct idxd_device *idxd, struct pci_dev *pdev, + const struct pci_device_id *id); void idxd_device_drv_remove(struct idxd_dev *idxd_dev); int idxd_drv_enable_wq(struct idxd_wq *wq); void idxd_drv_disable_wq(struct idxd_wq *wq); diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index a7295943fa22..068103b40223 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -716,67 +716,84 @@ static void idxd_cleanup(struct idxd_device *idxd) idxd_disable_sva(idxd->pdev); } =20 -static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id= *id) +/* + * Probe idxd PCI device. + * If idxd is not given, need to allocate idxd and set up its data. + * + * If idxd is given, idxd was allocated and setup already. Just need to + * configure device without re-allocating and re-configuring idxd data. + * This is useful for recovering from FLR. + */ +int idxd_pci_probe_alloc(struct idxd_device *idxd, struct pci_dev *pdev, + const struct pci_device_id *id) { - struct device *dev =3D &pdev->dev; - struct idxd_device *idxd; - struct idxd_driver_data *data =3D (struct idxd_driver_data *)id->driver_d= ata; + bool alloc_idxd =3D idxd ? false : true; + struct idxd_driver_data *data; + struct device *dev; int rc; =20 + pdev =3D idxd ? idxd->pdev : pdev; + dev =3D &pdev->dev; + data =3D id ? (struct idxd_driver_data *)id->driver_data : NULL; rc =3D pci_enable_device(pdev); if (rc) return rc; =20 - dev_dbg(dev, "Alloc IDXD context\n"); - idxd =3D idxd_alloc(pdev, data); - if (!idxd) { - rc =3D -ENOMEM; - goto err_idxd_alloc; - } + if (alloc_idxd) { + dev_dbg(dev, "Alloc IDXD context\n"); + idxd =3D idxd_alloc(pdev, data); + if (!idxd) { + rc =3D -ENOMEM; + goto err_idxd_alloc; + } =20 - dev_dbg(dev, "Mapping BARs\n"); - idxd->reg_base =3D pci_iomap(pdev, IDXD_MMIO_BAR, 0); - if (!idxd->reg_base) { - rc =3D -ENOMEM; - goto err_iomap; - } + dev_dbg(dev, "Mapping BARs\n"); + idxd->reg_base =3D pci_iomap(pdev, IDXD_MMIO_BAR, 0); + if (!idxd->reg_base) { + rc =3D -ENOMEM; + goto err_iomap; + } =20 - dev_dbg(dev, "Set DMA masks\n"); - rc =3D dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); - if (rc) - goto err; + dev_dbg(dev, "Set DMA masks\n"); + rc =3D dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); + if (rc) + goto err; + } =20 dev_dbg(dev, "Set PCI master\n"); pci_set_master(pdev); pci_set_drvdata(pdev, idxd); =20 - idxd->hw.version =3D ioread32(idxd->reg_base + IDXD_VER_OFFSET); - rc =3D idxd_probe(idxd); - if (rc) { - dev_err(dev, "Intel(R) IDXD DMA Engine init failed\n"); - goto err; - } + if (alloc_idxd) { + idxd->hw.version =3D ioread32(idxd->reg_base + IDXD_VER_OFFSET); + rc =3D idxd_probe(idxd); + if (rc) { + dev_err(dev, "Intel(R) IDXD DMA Engine init failed\n"); + goto err; + } =20 - if (data->load_device_defaults) { - rc =3D data->load_device_defaults(idxd); - if (rc) - dev_warn(dev, "IDXD loading device defaults failed\n"); - } + if (data->load_device_defaults) { + rc =3D data->load_device_defaults(idxd); + if (rc) + dev_warn(dev, "IDXD loading device defaults failed\n"); + } =20 - rc =3D idxd_register_devices(idxd); - if (rc) { - dev_err(dev, "IDXD sysfs setup failed\n"); - goto err_dev_register; - } + rc =3D idxd_register_devices(idxd); + if (rc) { + dev_err(dev, "IDXD sysfs setup failed\n"); + goto err_dev_register; + } =20 - rc =3D idxd_device_init_debugfs(idxd); - if (rc) - dev_warn(dev, "IDXD debugfs failed to setup\n"); + rc =3D idxd_device_init_debugfs(idxd); + if (rc) + dev_warn(dev, "IDXD debugfs failed to setup\n"); + } =20 dev_info(&pdev->dev, "Intel(R) Accelerator Device (v%x)\n", idxd->hw.version); =20 - idxd->user_submission_safe =3D data->user_submission_safe; + if (data) + idxd->user_submission_safe =3D data->user_submission_safe; =20 return 0; =20 @@ -791,6 +808,11 @@ static int idxd_pci_probe(struct pci_dev *pdev, const = struct pci_device_id *id) return rc; } =20 +static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id= *id) +{ + return idxd_pci_probe_alloc(NULL, pdev, id); +} + void idxd_wqs_quiesce(struct idxd_device *idxd) { struct idxd_wq *wq; --=20 2.37.1 From nobody Sat Feb 7 05:44:24 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 75E6713AD28; Fri, 5 Jul 2024 18:15:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.16 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720203324; cv=none; b=mU4hiKqTLvggHdSkxEdlDGw0nepFg0a6lmzzZP4juzxNnUL7MUhpdJ5DHoJEYZco6I3eNTwlfuOPs6W3SLpz9GM4uma9Yim6h5f45gIaOoVizzo/s1/4PjYxauPbGO46u08APic1fUN2WzQGypW6swqqc0nD/Ds79PShxXxDhjw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720203324; c=relaxed/simple; bh=siTPzKLH0RjHwMR3sXWKjqOAmHVFayQ8o6rC3wLhP8k=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=J/3L/alQDVGDYjqNW/rKjzyh5pmOfZ1dny/OdbJ1gLNC+X4Goix0B6xHQNOqREn8vyBYwwbLgvdG2hpjxqXk4rV96ZE4SPV6+kwUXUgkmdXh5jyMyQaelMPmd8IoX9UcjrPBuJGFb3s435b00PKXn43bgnNVINd3Qb2XMeWPyeI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=FfvuT8Hv; arc=none smtp.client-ip=192.198.163.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="FfvuT8Hv" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1720203322; x=1751739322; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=siTPzKLH0RjHwMR3sXWKjqOAmHVFayQ8o6rC3wLhP8k=; b=FfvuT8Hvx+AQRGjjcQ23nsXoiTgfJQULG/CDyjMmOarX25aLpVh07wwe 8tE8+rUsu67bqiUz33bxqyBFRH1Jvw0VHRXWd8EDyA87GLnSYu9aDN740 sQJ1TyFojbJez7KIZI/rMVIKURgkgChIU3BSnMdvujsR9TSNFI4baK7Ms vEwQhax8+LRLJYis5lNcd29or78bY2Z2Uu6xTKbf/dIgx7YSLDdv96Efc Gnubtsd8nNXwQ2vcEcpDfeA1W9t++hho/FCXZrCDHc/YYGgswB5Ae6oo0 bzOQ3yNc21KlJcTfy9TFaCtM2Sh3bbCB1Fahe9sAfk4rsXs953kcScCce g==; X-CSE-ConnectionGUID: pMik5CFkTu+vT6L+Czk/Dg== X-CSE-MsgGUID: C6QFCzZxTNChd1bbLbQcqg== X-IronPort-AV: E=McAfee;i="6700,10204,11123"; a="12410719" X-IronPort-AV: E=Sophos;i="6.09,185,1716274800"; d="scan'208";a="12410719" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa110.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2024 11:15:20 -0700 X-CSE-ConnectionGUID: EssZeeqmR36L1o7F+8zh7g== X-CSE-MsgGUID: GJwn3zD6QNytjnDEz2reeQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,185,1716274800"; d="scan'208";a="47672697" Received: from fyu1.sc.intel.com ([172.25.103.126]) by orviesa008.jf.intel.com with ESMTP; 05 Jul 2024 11:15:19 -0700 From: Fenghua Yu To: "Vinod Koul" , "Dave Jiang" Cc: dmaengine@vger.kernel.org, "linux-kernel" , Fenghua Yu Subject: [PATCH 2/5] dmaengine: idxd: Binding and unbinding IDXD device and driver Date: Fri, 5 Jul 2024 11:15:15 -0700 Message-Id: <20240705181519.4067507-3-fenghua.yu@intel.com> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20240705181519.4067507-1-fenghua.yu@intel.com> References: <20240705181519.4067507-1-fenghua.yu@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add idxd_bind() and idxd_unbind() helpers to bind and unbind the IDXD device and driver. These helpers will be called during Function Level Reset (FLR) processing. Signed-off-by: Fenghua Yu --- drivers/dma/idxd/init.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index 068103b40223..a6d8097b2dcf 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -716,6 +716,39 @@ static void idxd_cleanup(struct idxd_device *idxd) idxd_disable_sva(idxd->pdev); } =20 +/* + * Attach IDXD device to IDXD driver. + */ +static int idxd_bind(struct device_driver *drv, const char *buf) +{ + const struct bus_type *bus =3D drv->bus; + struct device *dev; + int err =3D -ENODEV; + + dev =3D bus_find_device_by_name(bus, NULL, buf); + if (dev) + err =3D device_driver_attach(drv, dev); + + put_device(dev); + + return err; +} + +/* + * Detach IDXD device from driver. + */ +static void idxd_unbind(struct device_driver *drv, const char *buf) +{ + const struct bus_type *bus =3D drv->bus; + struct device *dev; + + dev =3D bus_find_device_by_name(bus, NULL, buf); + if (dev && dev->driver =3D=3D drv) + device_release_driver(dev); + + put_device(dev); +} + /* * Probe idxd PCI device. * If idxd is not given, need to allocate idxd and set up its data. --=20 2.37.1 From nobody Sat Feb 7 05:44:24 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0956D15FCE9; Fri, 5 Jul 2024 18:15:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.16 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720203325; cv=none; b=fRVCaO80WLtDd50hvAvr6VzSzSUwS+ZQuaqRfYu+QV7tgrTMSNXgweqlCmKJ6Zh4yeBGFpeNwjcCQl/eI5jl47NqTn0FILoBq5CXV79zYlnl64bTz862dXNuIOz4wvu0hytFpxmnuBVmzuYT3zDFj/+WUWrA6XAynVSa+w0EHrA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720203325; c=relaxed/simple; bh=EZlEkzR6k7XGgV0+ZMZDFuYvwsVONhRSZrAAjdocq2w=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=rl0hv6Nxin4actcQX5D9dISMDs1PseR6ryA0U2igV/Yu5ciqlkZQzSjfNJchTttZm2txcXitzFVY3matibCauFfbhVHDz1zLTsDqOChjmP06EECFraJaj6JDgSfkxK/V0VgFPX6XSgGfQXXDMrHS6w8HGmpHiCTEUutgFCRoOOE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=hLhon7mq; arc=none smtp.client-ip=192.198.163.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="hLhon7mq" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1720203324; x=1751739324; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=EZlEkzR6k7XGgV0+ZMZDFuYvwsVONhRSZrAAjdocq2w=; b=hLhon7mqiHb1MbYklHoVOOVlE+m+UP0b5u9AIdZcRNJrrf5lukXN5xgo ufp2qHlsSsjbRNwzYKPujv6EyMD17XeF5S90AR49ATqf8HUGITqD3xJ0m SeWvlDo1YxDMyua7Gwlzo6sngfva+gTvCO/jYLscunxcrdHmTOsikeCdK zH22LGYDpLyy+VX4TViNNi3IfiEz4hotOMDiwFCYNtC5Vh7K8C4Oqlu96 kwwaE1s1kA0kHrIYNAAfhot9mjNGvhRRtpgEYE5kBZeEieKST3QLMx6kU 786Q4vHaIfWx/kskhNdPAw9IvGQiPpaqsrhtKio6EvsMCK9uUHbBBhDJN A==; X-CSE-ConnectionGUID: 9ahph7IQRx2FIuatQ0acWg== X-CSE-MsgGUID: kiBCil7vS2GCkD4uuAZ7cg== X-IronPort-AV: E=McAfee;i="6700,10204,11123"; a="12410721" X-IronPort-AV: E=Sophos;i="6.09,185,1716274800"; d="scan'208";a="12410721" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa110.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2024 11:15:20 -0700 X-CSE-ConnectionGUID: KRlqnAzuSy6VRy9sDfsRbg== X-CSE-MsgGUID: jzgzzgnqSByvc/wcDMhiUw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,185,1716274800"; d="scan'208";a="47672701" Received: from fyu1.sc.intel.com ([172.25.103.126]) by orviesa008.jf.intel.com with ESMTP; 05 Jul 2024 11:15:20 -0700 From: Fenghua Yu To: "Vinod Koul" , "Dave Jiang" Cc: dmaengine@vger.kernel.org, "linux-kernel" , Fenghua Yu Subject: [PATCH 3/5] dmaengine: idxd: Add idxd_device_config_save() and idxd_device_config_restore() helpers Date: Fri, 5 Jul 2024 11:15:16 -0700 Message-Id: <20240705181519.4067507-4-fenghua.yu@intel.com> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20240705181519.4067507-1-fenghua.yu@intel.com> References: <20240705181519.4067507-1-fenghua.yu@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add the helpers to save and restore IDXD device configurations. These helpers will be called during Function Level Reset (FLR) processing. Signed-off-by: Fenghua Yu --- drivers/dma/idxd/idxd.h | 11 ++ drivers/dma/idxd/init.c | 224 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 235 insertions(+) diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index 03f099518ec1..4f3e98720b45 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -377,6 +377,17 @@ struct idxd_device { struct dentry *dbgfs_evl_file; =20 bool user_submission_safe; + + struct idxd_saved_states *idxd_saved; +}; + +struct idxd_saved_states { + struct idxd_device saved_idxd; + struct idxd_evl saved_evl; + struct idxd_engine **saved_engines; + struct idxd_wq **saved_wqs; + struct idxd_group **saved_groups; + unsigned long *saved_wq_enable_map; }; =20 static inline unsigned int evl_ent_size(struct idxd_device *idxd) diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index a6d8097b2dcf..bb03d8cc5d32 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -749,6 +749,230 @@ static void idxd_unbind(struct device_driver *drv, co= nst char *buf) put_device(dev); } =20 +/* Free allocated saved wq enable map after saving wq configs. */ +static void free_saved_wq_enable_map(unsigned long *map) +{ + bitmap_free(map); +} + +DEFINE_FREE(free_saved_wq_enable_map, unsigned long *, if (!IS_ERR_OR_NULL= (_T)) + free_saved_wq_enable_map(_T)) + +#define idxd_free_saved_configs(saved_configs, count) \ + do { \ + int i; \ + \ + for (i =3D 0; i < (count); i++) \ + kfree(saved_configs[i]); \ + } while (0) + +/* + * Save IDXD device configurations including engines, groups, wqs etc. + * The saved configurations can be restored when needed. + */ +static int idxd_device_config_save(struct idxd_device *idxd, + struct idxd_saved_states *idxd_saved) +{ + struct device *dev =3D &idxd->pdev->dev; + int i; + + memcpy(&idxd_saved->saved_idxd, idxd, sizeof(*idxd)); + + if (idxd->evl) { + memcpy(&idxd_saved->saved_evl, idxd->evl, + sizeof(struct idxd_evl)); + } + + struct idxd_group **saved_groups __free(kfree) =3D + kcalloc_node(idxd->max_groups, + sizeof(struct idxd_group *), + GFP_KERNEL, dev_to_node(dev)); + if (!saved_groups) + return -ENOMEM; + + for (i =3D 0; i < idxd->max_groups; i++) { + struct idxd_group *saved_group __free(kfree) =3D + kzalloc_node(sizeof(*saved_group), GFP_KERNEL, + dev_to_node(dev)); + + if (!saved_group) { + idxd_free_saved_configs(saved_groups, i); + + return -ENOMEM; + } + + memcpy(saved_group, idxd->groups[i], sizeof(*saved_group)); + saved_groups[i] =3D no_free_ptr(saved_group); + } + + struct idxd_engine **saved_engines =3D + kcalloc_node(idxd->max_engines, + sizeof(struct idxd_engine *), + GFP_KERNEL, dev_to_node(dev)); + if (!saved_engines) { + /* Free saved groups */ + idxd_free_saved_configs(saved_groups, idxd->max_groups); + + return -ENOMEM; + } + for (i =3D 0; i < idxd->max_engines; i++) { + struct idxd_engine *saved_engine __free(kfree) =3D + kzalloc_node(sizeof(*saved_engine), GFP_KERNEL, + dev_to_node(dev)); + if (!saved_engine) { + /* Free saved groups and engines */ + idxd_free_saved_configs(saved_groups, idxd->max_groups); + idxd_free_saved_configs(saved_engines, i); + + return -ENOMEM; + } + + memcpy(saved_engine, idxd->engines[i], sizeof(*saved_engine)); + saved_engines[i] =3D no_free_ptr(saved_engine); + } + + unsigned long *saved_wq_enable_map __free(free_saved_wq_enable_map) =3D + bitmap_zalloc_node(idxd->max_wqs, GFP_KERNEL, + dev_to_node(dev)); + if (!saved_wq_enable_map) { + /* Free saved groups and engines */ + idxd_free_saved_configs(saved_groups, idxd->max_groups); + idxd_free_saved_configs(saved_engines, idxd->max_engines); + + return -ENOMEM; + } + + bitmap_copy(saved_wq_enable_map, idxd->wq_enable_map, idxd->max_wqs); + + struct idxd_wq **saved_wqs __free(kfree) =3D + kcalloc_node(idxd->max_wqs, sizeof(struct idxd_wq *), + GFP_KERNEL, dev_to_node(dev)); + if (!saved_wqs) { + /* Free saved groups and engines */ + idxd_free_saved_configs(saved_groups, idxd->max_groups); + idxd_free_saved_configs(saved_engines, idxd->max_engines); + + return -ENOMEM; + } + + for (i =3D 0; i < idxd->max_wqs; i++) { + struct idxd_wq *saved_wq __free(kfree) =3D + kzalloc_node(sizeof(*saved_wq), GFP_KERNEL, + dev_to_node(dev)); + struct idxd_wq *wq; + + if (!saved_wq) { + /* Free saved groups, engines, and wqs */ + idxd_free_saved_configs(saved_groups, idxd->max_groups); + idxd_free_saved_configs(saved_engines, + idxd->max_engines); + idxd_free_saved_configs(saved_wqs, i); + + return -ENOMEM; + } + + if (!test_bit(i, saved_wq_enable_map)) + continue; + + wq =3D idxd->wqs[i]; + mutex_lock(&wq->wq_lock); + memcpy(saved_wq, wq, sizeof(*saved_wq)); + saved_wqs[i] =3D no_free_ptr(saved_wq); + mutex_unlock(&wq->wq_lock); + } + + /* Save configurations */ + idxd_saved->saved_groups =3D no_free_ptr(saved_groups); + idxd_saved->saved_engines =3D no_free_ptr(saved_engines); + idxd_saved->saved_wq_enable_map =3D no_free_ptr(saved_wq_enable_map); + idxd_saved->saved_wqs =3D no_free_ptr(saved_wqs); + + return 0; +} + +/* + * Restore IDXD device configurations including engines, groups, wqs etc + * that were saved before. + */ +static void idxd_device_config_restore(struct idxd_device *idxd, + struct idxd_saved_states *idxd_saved) +{ + struct idxd_evl *saved_evl =3D &idxd_saved->saved_evl; + int i; + + idxd->rdbuf_limit =3D idxd_saved->saved_idxd.rdbuf_limit; + + if (saved_evl) + idxd->evl->size =3D saved_evl->size; + + for (i =3D 0; i < idxd->max_groups; i++) { + struct idxd_group *saved_group, *group; + + saved_group =3D idxd_saved->saved_groups[i]; + group =3D idxd->groups[i]; + + group->rdbufs_allowed =3D saved_group->rdbufs_allowed; + group->rdbufs_reserved =3D saved_group->rdbufs_reserved; + group->tc_a =3D saved_group->tc_a; + group->tc_b =3D saved_group->tc_b; + group->use_rdbuf_limit =3D saved_group->use_rdbuf_limit; + + kfree(saved_group); + } + kfree(idxd_saved->saved_groups); + + for (i =3D 0; i < idxd->max_engines; i++) { + struct idxd_engine *saved_engine, *engine; + + saved_engine =3D idxd_saved->saved_engines[i]; + engine =3D idxd->engines[i]; + + engine->group =3D saved_engine->group; + + kfree(saved_engine); + } + kfree(idxd_saved->saved_engines); + + bitmap_copy(idxd->wq_enable_map, idxd_saved->saved_wq_enable_map, + idxd->max_wqs); + bitmap_free(idxd_saved->saved_wq_enable_map); + + for (i =3D 0; i < idxd->max_wqs; i++) { + struct idxd_wq *saved_wq, *wq; + size_t len; + + if (!test_bit(i, idxd->wq_enable_map)) + continue; + + saved_wq =3D idxd_saved->saved_wqs[i]; + wq =3D idxd->wqs[i]; + + mutex_lock(&wq->wq_lock); + + wq->group =3D saved_wq->group; + wq->flags =3D saved_wq->flags; + wq->threshold =3D saved_wq->threshold; + wq->size =3D saved_wq->size; + wq->priority =3D saved_wq->priority; + wq->type =3D saved_wq->type; + len =3D strlen(saved_wq->name) + 1; + strscpy(wq->name, saved_wq->name, len); + wq->max_xfer_bytes =3D saved_wq->max_xfer_bytes; + wq->max_batch_size =3D saved_wq->max_batch_size; + wq->enqcmds_retries =3D saved_wq->enqcmds_retries; + wq->descs =3D saved_wq->descs; + wq->idxd_chan =3D saved_wq->idxd_chan; + len =3D strlen(saved_wq->driver_name) + 1; + strscpy(wq->driver_name, saved_wq->driver_name, len); + + mutex_unlock(&wq->wq_lock); + + kfree(saved_wq); + } + + kfree(idxd_saved->saved_wqs); +} + /* * Probe idxd PCI device. * If idxd is not given, need to allocate idxd and set up its data. --=20 2.37.1 From nobody Sat Feb 7 05:44:24 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 19ED216CD0B; Fri, 5 Jul 2024 18:15:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.16 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720203326; cv=none; b=pMvZw4aMSOaJ/OyFEYvpk1zkPnti9Z6866dkEM1d0qGn9fV+7zs5E2GY5mx5nZ9fV4J7pK40/9zUyY2YUfaew5XvAcLMPXY0EQsz0vvJiYc4VZC6LiDSYGiTp9hxNMTvN2NuciEM6ZQKtiAttcrh9TjLthk4psf/slfR8MIoycg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720203326; c=relaxed/simple; bh=lKegD691mBFS3bQxcyUvsTDpQBfCiZd+eZcTdkQier0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Yr7JTZI6UU5V6XOzPHTAtN/RS4ZbzCDixBZ7s+B3tK/JW9WjDCVAIAz97ZqkQO38kLeohQJPenuFJGUb5IRBWRxEAfShBOkNan28Za2C7fev6gOvSxjULdtl3fZoXRymH+xq3STq+Ck+IBM2oU4Z6a/Ndnj2qsmFDTJ9C6pGKPU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=kIn4JjCe; arc=none smtp.client-ip=192.198.163.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="kIn4JjCe" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1720203324; x=1751739324; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=lKegD691mBFS3bQxcyUvsTDpQBfCiZd+eZcTdkQier0=; b=kIn4JjCehgHwWyqTUphldpuQ0pkKqCX5zKTTqnJaK3JLrqElzj6j/T7e 3l0ndpob8+BXbF8cQl4bvoH2lDkcoHK+X6o5RD97sOai+EhOu4ZRgkM1L BuGLYisrJ3g68gKI1CBQe4in2ckR8euwb27NiwWTl4s1mGH9xOSfS96KS SHKqe/TyY1yz66eTXHQekZlaax5b1Nn78z2Tp14fbTKlowNNcNJ3Hapl+ w4UqOXNn7810Qghp1Y9WS7mw8IccrnygYId/pgCUReQ+rI1Ooyk05qrHg dJVAjLiqHZTS2xbuop6aNWksEnlyzQ9aqeSCNshYWF9LeV6Mkl+c9F/sS Q==; X-CSE-ConnectionGUID: O3qyOHlDS926HCe1WlZXTA== X-CSE-MsgGUID: dpw+tnN3T+SLbeT46iylaw== X-IronPort-AV: E=McAfee;i="6700,10204,11123"; a="12410723" X-IronPort-AV: E=Sophos;i="6.09,185,1716274800"; d="scan'208";a="12410723" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa110.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2024 11:15:20 -0700 X-CSE-ConnectionGUID: VtjISuNQQm2wGiL1j+/GdA== X-CSE-MsgGUID: c9uLm8LlTR+flCT38n4YXw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,185,1716274800"; d="scan'208";a="47672704" Received: from fyu1.sc.intel.com ([172.25.103.126]) by orviesa008.jf.intel.com with ESMTP; 05 Jul 2024 11:15:20 -0700 From: Fenghua Yu To: "Vinod Koul" , "Dave Jiang" Cc: dmaengine@vger.kernel.org, "linux-kernel" , Fenghua Yu Subject: [PATCH 4/5] dmaengine: idxd: Refactor halt handler Date: Fri, 5 Jul 2024 11:15:17 -0700 Message-Id: <20240705181519.4067507-5-fenghua.yu@intel.com> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20240705181519.4067507-1-fenghua.yu@intel.com> References: <20240705181519.4067507-1-fenghua.yu@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Define a halt handling helper idxd_halt(). Refactor the halt interrupt handler to call the helper. This will simplify the Function Level Reset (FLR) code. No functional change. Signed-off-by: Fenghua Yu --- drivers/dma/idxd/irq.c | 63 +++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c index fc049c9c9892..a46e58b756a5 100644 --- a/drivers/dma/idxd/irq.c +++ b/drivers/dma/idxd/irq.c @@ -383,15 +383,43 @@ static void process_evl_entries(struct idxd_device *i= dxd) mutex_unlock(&evl->lock); } =20 +static irqreturn_t idxd_halt(struct idxd_device *idxd) +{ + union gensts_reg gensts; + + gensts.bits =3D ioread32(idxd->reg_base + IDXD_GENSTATS_OFFSET); + if (gensts.state =3D=3D IDXD_DEVICE_STATE_HALT) { + idxd->state =3D IDXD_DEV_HALTED; + if (gensts.reset_type =3D=3D IDXD_DEVICE_RESET_SOFTWARE) { + /* + * If we need a software reset, we will throw the work + * on a system workqueue in order to allow interrupts + * for the device command completions. + */ + INIT_WORK(&idxd->work, idxd_device_reinit); + queue_work(idxd->wq, &idxd->work); + } else { + idxd->state =3D IDXD_DEV_HALTED; + idxd_wqs_quiesce(idxd); + idxd_wqs_unmap_portal(idxd); + idxd_device_clear_state(idxd); + dev_err(&idxd->pdev->dev, + "idxd halted, need %s.\n", + gensts.reset_type =3D=3D IDXD_DEVICE_RESET_FLR ? + "FLR" : "system reset"); + } + } + + return IRQ_HANDLED; +} + irqreturn_t idxd_misc_thread(int vec, void *data) { struct idxd_irq_entry *irq_entry =3D data; struct idxd_device *idxd =3D ie_to_idxd(irq_entry); struct device *dev =3D &idxd->pdev->dev; - union gensts_reg gensts; u32 val =3D 0; int i; - bool err =3D false; u32 cause; =20 cause =3D ioread32(idxd->reg_base + IDXD_INTCAUSE_OFFSET); @@ -401,7 +429,7 @@ irqreturn_t idxd_misc_thread(int vec, void *data) iowrite32(cause, idxd->reg_base + IDXD_INTCAUSE_OFFSET); =20 if (cause & IDXD_INTC_HALT_STATE) - goto halt; + return idxd_halt(idxd); =20 if (cause & IDXD_INTC_ERR) { spin_lock(&idxd->dev_lock); @@ -435,7 +463,6 @@ irqreturn_t idxd_misc_thread(int vec, void *data) for (i =3D 0; i < 4; i++) dev_warn_ratelimited(dev, "err[%d]: %#16.16llx\n", i, idxd->sw_err.bits[i]); - err =3D true; } =20 if (cause & IDXD_INTC_INT_HANDLE_REVOKED) { @@ -480,34 +507,6 @@ irqreturn_t idxd_misc_thread(int vec, void *data) dev_warn_once(dev, "Unexpected interrupt cause bits set: %#x\n", val); =20 - if (!err) - goto out; - -halt: - gensts.bits =3D ioread32(idxd->reg_base + IDXD_GENSTATS_OFFSET); - if (gensts.state =3D=3D IDXD_DEVICE_STATE_HALT) { - idxd->state =3D IDXD_DEV_HALTED; - if (gensts.reset_type =3D=3D IDXD_DEVICE_RESET_SOFTWARE) { - /* - * If we need a software reset, we will throw the work - * on a system workqueue in order to allow interrupts - * for the device command completions. - */ - INIT_WORK(&idxd->work, idxd_device_reinit); - queue_work(idxd->wq, &idxd->work); - } else { - idxd->state =3D IDXD_DEV_HALTED; - idxd_wqs_quiesce(idxd); - idxd_wqs_unmap_portal(idxd); - idxd_device_clear_state(idxd); - dev_err(&idxd->pdev->dev, - "idxd halted, need %s.\n", - gensts.reset_type =3D=3D IDXD_DEVICE_RESET_FLR ? - "FLR" : "system reset"); - } - } - -out: return IRQ_HANDLED; } =20 --=20 2.37.1 From nobody Sat Feb 7 05:44:24 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7DA7C16D9CF; Fri, 5 Jul 2024 18:15:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.16 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720203326; cv=none; b=EOe0J8l8gKQNoJuJM8uqIMXy0mJO7VpNJMm7y0MnwCaBAjjFa8vNPXB3CtpvcIGMor4b1mhVNu35D2lnFfb7ob/PVxfasUp41W3syCxw/Ib67VM9u8mWPjOa7peQnqPu+HhDQiRJqlONiwdJosZGjYE+xWtHcb501ydi2aOs/+U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720203326; c=relaxed/simple; bh=dq/tINiRky6n3K6tZb7sRH+6JZSWm6yHcqMs5idQIJE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=HDWh8kFC0JdDiPu3C1FEq3YNntn4ZUTgQ+60k7eSz/YEPr+ST8jjfvd9qTC4DQ2oMcjIxdNuaADZ/0VDGaAaiDR68k/zfW6e9iXOLRj5ttfMUwUvxThYi1oa3PlxiXLaHaHghP4pcOhyDGxinVJFiNSx5fi0oi/Szc7mbtle7oo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=MDkxbgln; arc=none smtp.client-ip=192.198.163.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="MDkxbgln" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1720203324; x=1751739324; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=dq/tINiRky6n3K6tZb7sRH+6JZSWm6yHcqMs5idQIJE=; b=MDkxbglnXcsnKj62QjpaNFMQKpyxTdrKNDZRqPUlpilsmqnrxSkKaWaG 7ZVtIKzL1X850Io+W7ZhXjiDJeY5p7cDBkRiZWRXvu37ekP+ZlgOA0HGN O/2HL045IcbjQKxH1EMMJO15VSi5ttxuSH927FrSos6m5BWuoChA+q8Gy 0PPRAfcLyXA03S1e7XkCEUw2OqG2Pz5N8XqsQcPY+GT3U+EwI+86k2gHm eXAD57rX/x452fRXQDkInXfmNgCpHlLNLTWGVY32vdIJhSKuN+XeohB3L VZdTyVP64fFtzsxsBl0v430hJaefZ7XmQ8uuf8z82KO5s74GMEiurH9d6 Q==; X-CSE-ConnectionGUID: vaS2101ZS3qCHEBwf9MyjA== X-CSE-MsgGUID: vZm4Sb8oRaCUZ5GKAggRug== X-IronPort-AV: E=McAfee;i="6700,10204,11123"; a="12410725" X-IronPort-AV: E=Sophos;i="6.09,185,1716274800"; d="scan'208";a="12410725" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa110.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2024 11:15:20 -0700 X-CSE-ConnectionGUID: 7cYuRPINRMyv0EsbC0ocDw== X-CSE-MsgGUID: fCO0pt6URF+EG7a2vgCJHA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.09,185,1716274800"; d="scan'208";a="47672707" Received: from fyu1.sc.intel.com ([172.25.103.126]) by orviesa008.jf.intel.com with ESMTP; 05 Jul 2024 11:15:20 -0700 From: Fenghua Yu To: "Vinod Koul" , "Dave Jiang" Cc: dmaengine@vger.kernel.org, "linux-kernel" , Fenghua Yu Subject: [PATCH 5/5] dmaengine: idxd: Enable Function Level Reset (FLR) for halt Date: Fri, 5 Jul 2024 11:15:18 -0700 Message-Id: <20240705181519.4067507-6-fenghua.yu@intel.com> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20240705181519.4067507-1-fenghua.yu@intel.com> References: <20240705181519.4067507-1-fenghua.yu@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When DSA/IAA device hits a fatal error, the device enters a halt state. The driver can reset the device depending on Reset Type required by hardware to recover the device. Supported Reset Types are: 0: Reset Device command 1: Function Level Reset (FLR) 2: Warm reset 3: Cold reset Currently, the driver only supports Reset Type 0. This patch adds support for FLR recovery Type 1. Before issuing a PCIe FLR command, IDXD device and WQ states are saved. After the FLR command execution, the device is recovered to its previous states, allowing the user can continue using the device. Signed-off-by: Fenghua Yu --- drivers/dma/idxd/init.c | 123 ++++++++++++++++++++++++++++++++++++++++ drivers/dma/idxd/irq.c | 28 ++++++++- 2 files changed, 148 insertions(+), 3 deletions(-) diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index bb03d8cc5d32..87f2c6a878c6 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -973,6 +973,118 @@ static void idxd_device_config_restore(struct idxd_de= vice *idxd, kfree(idxd_saved->saved_wqs); } =20 +static void idxd_reset_prepare(struct pci_dev *pdev) +{ + struct idxd_device *idxd =3D pci_get_drvdata(pdev); + struct device *dev =3D &idxd->pdev->dev; + const char *idxd_name; + int rc; + + dev =3D &idxd->pdev->dev; + idxd_name =3D dev_name(idxd_confdev(idxd)); + + struct idxd_saved_states *idxd_saved __free(kfree) =3D + kzalloc_node(sizeof(*idxd_saved), GFP_KERNEL, + dev_to_node(&pdev->dev)); + if (!idxd_saved) { + dev_err(dev, "HALT: no memory\n"); + + return; + } + + /* Save IDXD configurations. */ + rc =3D idxd_device_config_save(idxd, idxd_saved); + if (rc < 0) { + dev_err(dev, "HALT: cannot save %s configs\n", idxd_name); + + return; + } + + idxd->idxd_saved =3D no_free_ptr(idxd_saved); + + /* Save PCI device state. */ + pci_save_state(idxd->pdev); +} + +static void idxd_reset_done(struct pci_dev *pdev) +{ + struct idxd_device *idxd =3D pci_get_drvdata(pdev); + const char *idxd_name; + struct device *dev; + int rc, i; + + if (!idxd->idxd_saved) + return; + + dev =3D &idxd->pdev->dev; + idxd_name =3D dev_name(idxd_confdev(idxd)); + + /* Restore PCI device state. */ + pci_restore_state(idxd->pdev); + + /* Unbind idxd device from driver. */ + idxd_unbind(&idxd_drv.drv, idxd_name); + + /* + * Probe PCI device without allocating or changing + * idxd software data which keeps the same as before FLR. + */ + idxd_pci_probe_alloc(idxd, NULL, NULL); + + /* Restore IDXD configurations. */ + idxd_device_config_restore(idxd, idxd->idxd_saved); + + /* Re-configure IDXD device if allowed. */ + if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) { + rc =3D idxd_device_config(idxd); + if (rc < 0) { + dev_err(dev, "HALT: %s config fails\n", idxd_name); + goto out; + } + } + + /* Bind IDXD device to driver. */ + rc =3D idxd_bind(&idxd_drv.drv, idxd_name); + if (rc < 0) { + dev_err(dev, "HALT: binding %s to driver fails\n", idxd_name); + goto out; + } + + /* Bind enabled wq in the IDXD device to driver. */ + for (i =3D 0; i < idxd->max_wqs; i++) { + if (test_bit(i, idxd->wq_enable_map)) { + struct idxd_wq *wq =3D idxd->wqs[i]; + char wq_name[32]; + + wq->state =3D IDXD_WQ_DISABLED; + sprintf(wq_name, "wq%d.%d", idxd->id, wq->id); + /* + * Bind to user driver depending on wq type. + * + * Currently only support user type WQ. Will support + * kernel type WQ in the future. + */ + if (wq->type =3D=3D IDXD_WQT_USER) + rc =3D idxd_bind(&idxd_user_drv.drv, wq_name); + else + rc =3D -EINVAL; + if (rc < 0) { + clear_bit(i, idxd->wq_enable_map); + dev_err(dev, + "HALT: unable to re-enable wq %s\n", + dev_name(wq_confdev(wq))); + } + } + } +out: + kfree(idxd->idxd_saved); +} + +static const struct pci_error_handlers idxd_error_handler =3D { + .reset_prepare =3D idxd_reset_prepare, + .reset_done =3D idxd_reset_done, +}; + /* * Probe idxd PCI device. * If idxd is not given, need to allocate idxd and set up its data. @@ -1046,6 +1158,16 @@ int idxd_pci_probe_alloc(struct idxd_device *idxd, s= truct pci_dev *pdev, dev_warn(dev, "IDXD debugfs failed to setup\n"); } =20 + if (!alloc_idxd) { + /* Release interrupts in the IDXD device. */ + idxd_cleanup_interrupts(idxd); + + /* Re-enable interrupts in the IDXD device. */ + rc =3D idxd_setup_interrupts(idxd); + if (rc) + dev_warn(dev, "IDXD interrupts failed to setup\n"); + } + dev_info(&pdev->dev, "Intel(R) Accelerator Device (v%x)\n", idxd->hw.version); =20 @@ -1136,6 +1258,7 @@ static struct pci_driver idxd_pci_driver =3D { .probe =3D idxd_pci_probe, .remove =3D idxd_remove, .shutdown =3D idxd_shutdown, + .err_handler =3D &idxd_error_handler, }; =20 static int __init idxd_init_module(void) diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c index a46e58b756a5..1107db3ce0a3 100644 --- a/drivers/dma/idxd/irq.c +++ b/drivers/dma/idxd/irq.c @@ -383,6 +383,20 @@ static void process_evl_entries(struct idxd_device *id= xd) mutex_unlock(&evl->lock); } =20 +static void idxd_device_flr(struct work_struct *work) +{ + struct idxd_device *idxd =3D container_of(work, struct idxd_device, work); + int rc; + + /* + * IDXD device requires a Function Level Reset (FLR). + * pci_reset_function() will reset the device with FLR. + */ + rc =3D pci_reset_function(idxd->pdev); + if (rc) + dev_err(&idxd->pdev->dev, "FLR failed\n"); +} + static irqreturn_t idxd_halt(struct idxd_device *idxd) { union gensts_reg gensts; @@ -398,15 +412,23 @@ static irqreturn_t idxd_halt(struct idxd_device *idxd) */ INIT_WORK(&idxd->work, idxd_device_reinit); queue_work(idxd->wq, &idxd->work); + } else if (gensts.reset_type =3D=3D IDXD_DEVICE_RESET_FLR) { + idxd->state =3D IDXD_DEV_HALTED; + idxd_mask_error_interrupts(idxd); + dev_dbg(&idxd->pdev->dev, + "idxd halted, doing FLR. After FLR, configs are restored\n"); + INIT_WORK(&idxd->work, idxd_device_flr); + queue_work(idxd->wq, &idxd->work); + } else { idxd->state =3D IDXD_DEV_HALTED; idxd_wqs_quiesce(idxd); idxd_wqs_unmap_portal(idxd); idxd_device_clear_state(idxd); dev_err(&idxd->pdev->dev, - "idxd halted, need %s.\n", - gensts.reset_type =3D=3D IDXD_DEVICE_RESET_FLR ? - "FLR" : "system reset"); + "idxd halted, need system reset"); + + return -ENXIO; } } =20 --=20 2.37.1