All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
To: dri-devel@lists.freedesktop.org, amd-gfx@lists.freedesktop.org,
	linux-pci@vger.kernel.org, ckoenig.leichtzumerken@gmail.com,
	daniel.vetter@ffwll.ch, Harry.Wentland@amd.com
Cc: ppaalanen@gmail.com, Alexander.Deucher@amd.com,
	gregkh@linuxfoundation.org, helgaas@kernel.org,
	Felix.Kuehling@amd.com,
	Andrey Grodzovsky <andrey.grodzovsky@amd.com>
Subject: [PATCH v5 19/27] drm/amdgpu: Finilise device fences on device remove.
Date: Wed, 28 Apr 2021 11:11:59 -0400	[thread overview]
Message-ID: <20210428151207.1212258-20-andrey.grodzovsky@amd.com> (raw)
In-Reply-To: <20210428151207.1212258-1-andrey.grodzovsky@amd.com>

Make sure all fecens dependent on HW present are force signaled
when handling device removal. This helpes later to scope all HW
accesing code such as IOCTLs in drm_dev_enter/exit and use
drm_dev_unplug as synchronization point past which we know HW
will not be accessed anymore outside of pci remove driver callback.

Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h        |  2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 98 ++++++++++++++++++++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c    |  6 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c  | 12 +--
 4 files changed, 103 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 0db0ba4fba89..df6c5ed676b1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1374,6 +1374,8 @@ void amdgpu_pci_resume(struct pci_dev *pdev);
 bool amdgpu_device_cache_pci_state(struct pci_dev *pdev);
 bool amdgpu_device_load_pci_state(struct pci_dev *pdev);
 
+void amdgpu_finilize_device_fences(struct drm_device *dev);
+
 #include "amdgpu_object.h"
 
 static inline bool amdgpu_is_tmz(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 33e8e9e1d1fe..55afc11c17e6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -3692,15 +3692,12 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
 		amdgpu_virt_fini_data_exchange(adev);
 	}
 
-	/* disable all interrupts */
-	amdgpu_irq_disable_all(adev);
 	if (adev->mode_info.mode_config_initialized){
 		if (!amdgpu_device_has_dc_support(adev))
 			drm_helper_force_disable_all(adev_to_drm(adev));
 		else
 			drm_atomic_helper_shutdown(adev_to_drm(adev));
 	}
-	amdgpu_fence_driver_fini_hw(adev);
 
 	if (adev->pm_sysfs_en)
 		amdgpu_pm_sysfs_fini(adev);
@@ -4567,14 +4564,19 @@ static bool amdgpu_device_lock_adev(struct amdgpu_device *adev,
 	return true;
 }
 
-static void amdgpu_device_unlock_adev(struct amdgpu_device *adev)
+static void amdgpu_device_unlock_adev_imp(struct amdgpu_device *adev, bool skip_in_gpu_reset)
 {
 	amdgpu_vf_error_trans_all(adev);
 	adev->mp1_state = PP_MP1_STATE_NONE;
-	atomic_set(&adev->in_gpu_reset, 0);
+	!skip_in_gpu_reset ? atomic_set(&adev->in_gpu_reset, 0) : 0;
 	up_write(&adev->reset_sem);
 }
 
+static void amdgpu_device_unlock_adev(struct amdgpu_device *adev)
+{
+	amdgpu_device_unlock_adev_imp(adev, false);
+}
+
 /*
  * to lockup a list of amdgpu devices in a hive safely, if not a hive
  * with multiple nodes, it will be similar as amdgpu_device_lock_adev.
@@ -5321,3 +5323,89 @@ bool amdgpu_device_load_pci_state(struct pci_dev *pdev)
 }
 
 
+static void amdgpu_finilize_schedulded_fences(struct amdgpu_ctx_mgr *mgr)
+{
+	struct amdgpu_ctx *ctx;
+	struct idr *idp;
+	uint32_t id, i, j;
+
+	idp = &mgr->ctx_handles;
+
+	idr_for_each_entry(idp, ctx, id) {
+		for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
+			for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
+				struct drm_sched_entity *entity;
+
+				if (!ctx->entities[i][j])
+					continue;
+
+				entity = &ctx->entities[i][j]->entity;
+				drm_sched_entity_kill_jobs(entity);
+			}
+		}
+	}
+}
+
+/**
+ * amdgpu_finilize_device_fences() - Finilize all device fences
+ * @pdev: pointer to PCI device
+ *
+ * Will disable and finilise ISRs and will signal all fences
+ * that might hang if HW is gone
+ */
+void amdgpu_finilize_device_fences(struct drm_device *dev)
+{
+	struct amdgpu_device *adev = drm_to_adev(dev);
+	struct drm_file *file;
+
+	/*
+	 *  Block TDRs from further execution by setting adev->in_gpu_reset
+	 *  instead of holding full reset lock in order to not deadlock
+	 *  further ahead against any thread locking the reset lock when we
+	 *  wait for it's completion
+	 */
+	while (!amdgpu_device_lock_adev(adev, NULL))
+		amdgpu_cancel_all_tdr(adev);
+	amdgpu_device_unlock_adev_imp(adev, true);
+
+
+	/* disable all HW interrupts */
+	amdgpu_irq_disable_all(adev);
+
+	/* stop and flush all in flight HW interrupts handlers */
+	disable_irq(pci_irq_vector(adev->pdev, 0));
+
+	/*
+	 * Stop SW GPU schedulers and force completion on all HW fences. Since
+	 * in the prev. step all ISRs were disabled and completed the
+	 * HW fence array is idle (no insertions or extractions) and so it's
+	 * safe to iterate it bellow.
+	 * After this step all HW fences in the system are signaled. As a result
+	 * also all the scheduler 'finished' fences are also signaled.
+	 */
+	amdgpu_fence_driver_fini_hw(adev);
+
+	/*
+	 * Reject any further jobs to any scheduler entity queue. After this
+	 * step no new insertions and because schedulers are stopped also no
+	 * new extractions.
+	 */
+	down_read(&adev->sched_fence_completion_sem);
+	adev->stop_job_submissions = true;
+	up_read(&adev->sched_fence_completion_sem);
+
+	/*
+	 * Complete all scheduler 'scheduled' fences currently pending.
+	 * It's OK if new contexts and sched entities are concurrently
+	 * still created as they will fail in pushing jobs to SW queues
+	 * and their schedule fences will be signaled with error
+	 */
+	mutex_lock(&adev->ddev.filelist_mutex);
+	list_for_each_entry(file, &adev->ddev.filelist, lhead) {
+		struct amdgpu_fpriv *fpriv = file->driver_priv;
+		amdgpu_finilize_schedulded_fences(&fpriv->ctx_mgr);
+	}
+	mutex_unlock(&adev->ddev.filelist_mutex);
+}
+
+
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index f799c40d7e72..8a19b8dd02ee 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -1249,6 +1249,12 @@ amdgpu_pci_remove(struct pci_dev *pdev)
 {
 	struct drm_device *dev = pci_get_drvdata(pdev);
 
+	/*
+	 * Force completion of all device related fences that might hang us when
+	 * synchronizing SRCU in the following step.
+	 */
+	amdgpu_finilize_device_fences(dev);
+
 	drm_dev_unplug(dev);
 	amdgpu_driver_unload_kms(dev);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
index 2670201e78d3..af592b28cd35 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -526,7 +526,7 @@ int amdgpu_fence_driver_init(struct amdgpu_device *adev)
  */
 void amdgpu_fence_driver_fini_hw(struct amdgpu_device *adev)
 {
-	int i, r;
+	int i;
 
 	for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
 		struct amdgpu_ring *ring = adev->rings[i];
@@ -535,18 +535,10 @@ void amdgpu_fence_driver_fini_hw(struct amdgpu_device *adev)
 			continue;
 
 		/* Stop any new job submissions from sched before flushing the ring */
-		/* TODO Handle amdgpu_job_submit_direct and amdgpu_amdkfd_submit_ib */
 		if (!ring->no_scheduler)
 			drm_sched_fini(&ring->sched);
 
-		/* You can't wait for HW to signal if it's gone */
-		if (!drm_dev_is_unplugged(&adev->ddev))
-			r = amdgpu_fence_wait_empty(ring);
-		else
-			r = -ENODEV;
-		/* no need to trigger GPU reset as we are unloading */
-		if (r)
-			amdgpu_fence_driver_force_completion(ring);
+		amdgpu_fence_driver_force_completion(ring);
 
 		if (ring->fence_drv.irq_src)
 			amdgpu_irq_put(adev, ring->fence_drv.irq_src,
-- 
2.25.1


WARNING: multiple messages have this Message-ID (diff)
From: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
To: dri-devel@lists.freedesktop.org, amd-gfx@lists.freedesktop.org,
	linux-pci@vger.kernel.org, ckoenig.leichtzumerken@gmail.com,
	daniel.vetter@ffwll.ch, Harry.Wentland@amd.com
Cc: gregkh@linuxfoundation.org, Felix.Kuehling@amd.com,
	helgaas@kernel.org, Alexander.Deucher@amd.com
Subject: [PATCH v5 19/27] drm/amdgpu: Finilise device fences on device remove.
Date: Wed, 28 Apr 2021 11:11:59 -0400	[thread overview]
Message-ID: <20210428151207.1212258-20-andrey.grodzovsky@amd.com> (raw)
In-Reply-To: <20210428151207.1212258-1-andrey.grodzovsky@amd.com>

Make sure all fecens dependent on HW present are force signaled
when handling device removal. This helpes later to scope all HW
accesing code such as IOCTLs in drm_dev_enter/exit and use
drm_dev_unplug as synchronization point past which we know HW
will not be accessed anymore outside of pci remove driver callback.

Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h        |  2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 98 ++++++++++++++++++++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c    |  6 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c  | 12 +--
 4 files changed, 103 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 0db0ba4fba89..df6c5ed676b1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1374,6 +1374,8 @@ void amdgpu_pci_resume(struct pci_dev *pdev);
 bool amdgpu_device_cache_pci_state(struct pci_dev *pdev);
 bool amdgpu_device_load_pci_state(struct pci_dev *pdev);
 
+void amdgpu_finilize_device_fences(struct drm_device *dev);
+
 #include "amdgpu_object.h"
 
 static inline bool amdgpu_is_tmz(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 33e8e9e1d1fe..55afc11c17e6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -3692,15 +3692,12 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
 		amdgpu_virt_fini_data_exchange(adev);
 	}
 
-	/* disable all interrupts */
-	amdgpu_irq_disable_all(adev);
 	if (adev->mode_info.mode_config_initialized){
 		if (!amdgpu_device_has_dc_support(adev))
 			drm_helper_force_disable_all(adev_to_drm(adev));
 		else
 			drm_atomic_helper_shutdown(adev_to_drm(adev));
 	}
-	amdgpu_fence_driver_fini_hw(adev);
 
 	if (adev->pm_sysfs_en)
 		amdgpu_pm_sysfs_fini(adev);
@@ -4567,14 +4564,19 @@ static bool amdgpu_device_lock_adev(struct amdgpu_device *adev,
 	return true;
 }
 
-static void amdgpu_device_unlock_adev(struct amdgpu_device *adev)
+static void amdgpu_device_unlock_adev_imp(struct amdgpu_device *adev, bool skip_in_gpu_reset)
 {
 	amdgpu_vf_error_trans_all(adev);
 	adev->mp1_state = PP_MP1_STATE_NONE;
-	atomic_set(&adev->in_gpu_reset, 0);
+	!skip_in_gpu_reset ? atomic_set(&adev->in_gpu_reset, 0) : 0;
 	up_write(&adev->reset_sem);
 }
 
+static void amdgpu_device_unlock_adev(struct amdgpu_device *adev)
+{
+	amdgpu_device_unlock_adev_imp(adev, false);
+}
+
 /*
  * to lockup a list of amdgpu devices in a hive safely, if not a hive
  * with multiple nodes, it will be similar as amdgpu_device_lock_adev.
@@ -5321,3 +5323,89 @@ bool amdgpu_device_load_pci_state(struct pci_dev *pdev)
 }
 
 
+static void amdgpu_finilize_schedulded_fences(struct amdgpu_ctx_mgr *mgr)
+{
+	struct amdgpu_ctx *ctx;
+	struct idr *idp;
+	uint32_t id, i, j;
+
+	idp = &mgr->ctx_handles;
+
+	idr_for_each_entry(idp, ctx, id) {
+		for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
+			for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
+				struct drm_sched_entity *entity;
+
+				if (!ctx->entities[i][j])
+					continue;
+
+				entity = &ctx->entities[i][j]->entity;
+				drm_sched_entity_kill_jobs(entity);
+			}
+		}
+	}
+}
+
+/**
+ * amdgpu_finilize_device_fences() - Finilize all device fences
+ * @pdev: pointer to PCI device
+ *
+ * Will disable and finilise ISRs and will signal all fences
+ * that might hang if HW is gone
+ */
+void amdgpu_finilize_device_fences(struct drm_device *dev)
+{
+	struct amdgpu_device *adev = drm_to_adev(dev);
+	struct drm_file *file;
+
+	/*
+	 *  Block TDRs from further execution by setting adev->in_gpu_reset
+	 *  instead of holding full reset lock in order to not deadlock
+	 *  further ahead against any thread locking the reset lock when we
+	 *  wait for it's completion
+	 */
+	while (!amdgpu_device_lock_adev(adev, NULL))
+		amdgpu_cancel_all_tdr(adev);
+	amdgpu_device_unlock_adev_imp(adev, true);
+
+
+	/* disable all HW interrupts */
+	amdgpu_irq_disable_all(adev);
+
+	/* stop and flush all in flight HW interrupts handlers */
+	disable_irq(pci_irq_vector(adev->pdev, 0));
+
+	/*
+	 * Stop SW GPU schedulers and force completion on all HW fences. Since
+	 * in the prev. step all ISRs were disabled and completed the
+	 * HW fence array is idle (no insertions or extractions) and so it's
+	 * safe to iterate it bellow.
+	 * After this step all HW fences in the system are signaled. As a result
+	 * also all the scheduler 'finished' fences are also signaled.
+	 */
+	amdgpu_fence_driver_fini_hw(adev);
+
+	/*
+	 * Reject any further jobs to any scheduler entity queue. After this
+	 * step no new insertions and because schedulers are stopped also no
+	 * new extractions.
+	 */
+	down_read(&adev->sched_fence_completion_sem);
+	adev->stop_job_submissions = true;
+	up_read(&adev->sched_fence_completion_sem);
+
+	/*
+	 * Complete all scheduler 'scheduled' fences currently pending.
+	 * It's OK if new contexts and sched entities are concurrently
+	 * still created as they will fail in pushing jobs to SW queues
+	 * and their schedule fences will be signaled with error
+	 */
+	mutex_lock(&adev->ddev.filelist_mutex);
+	list_for_each_entry(file, &adev->ddev.filelist, lhead) {
+		struct amdgpu_fpriv *fpriv = file->driver_priv;
+		amdgpu_finilize_schedulded_fences(&fpriv->ctx_mgr);
+	}
+	mutex_unlock(&adev->ddev.filelist_mutex);
+}
+
+
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index f799c40d7e72..8a19b8dd02ee 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -1249,6 +1249,12 @@ amdgpu_pci_remove(struct pci_dev *pdev)
 {
 	struct drm_device *dev = pci_get_drvdata(pdev);
 
+	/*
+	 * Force completion of all device related fences that might hang us when
+	 * synchronizing SRCU in the following step.
+	 */
+	amdgpu_finilize_device_fences(dev);
+
 	drm_dev_unplug(dev);
 	amdgpu_driver_unload_kms(dev);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
index 2670201e78d3..af592b28cd35 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -526,7 +526,7 @@ int amdgpu_fence_driver_init(struct amdgpu_device *adev)
  */
 void amdgpu_fence_driver_fini_hw(struct amdgpu_device *adev)
 {
-	int i, r;
+	int i;
 
 	for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
 		struct amdgpu_ring *ring = adev->rings[i];
@@ -535,18 +535,10 @@ void amdgpu_fence_driver_fini_hw(struct amdgpu_device *adev)
 			continue;
 
 		/* Stop any new job submissions from sched before flushing the ring */
-		/* TODO Handle amdgpu_job_submit_direct and amdgpu_amdkfd_submit_ib */
 		if (!ring->no_scheduler)
 			drm_sched_fini(&ring->sched);
 
-		/* You can't wait for HW to signal if it's gone */
-		if (!drm_dev_is_unplugged(&adev->ddev))
-			r = amdgpu_fence_wait_empty(ring);
-		else
-			r = -ENODEV;
-		/* no need to trigger GPU reset as we are unloading */
-		if (r)
-			amdgpu_fence_driver_force_completion(ring);
+		amdgpu_fence_driver_force_completion(ring);
 
 		if (ring->fence_drv.irq_src)
 			amdgpu_irq_put(adev, ring->fence_drv.irq_src,
-- 
2.25.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

WARNING: multiple messages have this Message-ID (diff)
From: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
To: dri-devel@lists.freedesktop.org, amd-gfx@lists.freedesktop.org,
	linux-pci@vger.kernel.org, ckoenig.leichtzumerken@gmail.com,
	daniel.vetter@ffwll.ch, Harry.Wentland@amd.com
Cc: Andrey Grodzovsky <andrey.grodzovsky@amd.com>,
	gregkh@linuxfoundation.org, Felix.Kuehling@amd.com,
	ppaalanen@gmail.com, helgaas@kernel.org,
	Alexander.Deucher@amd.com
Subject: [PATCH v5 19/27] drm/amdgpu: Finilise device fences on device remove.
Date: Wed, 28 Apr 2021 11:11:59 -0400	[thread overview]
Message-ID: <20210428151207.1212258-20-andrey.grodzovsky@amd.com> (raw)
In-Reply-To: <20210428151207.1212258-1-andrey.grodzovsky@amd.com>

Make sure all fecens dependent on HW present are force signaled
when handling device removal. This helpes later to scope all HW
accesing code such as IOCTLs in drm_dev_enter/exit and use
drm_dev_unplug as synchronization point past which we know HW
will not be accessed anymore outside of pci remove driver callback.

Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h        |  2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 98 ++++++++++++++++++++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c    |  6 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c  | 12 +--
 4 files changed, 103 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 0db0ba4fba89..df6c5ed676b1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1374,6 +1374,8 @@ void amdgpu_pci_resume(struct pci_dev *pdev);
 bool amdgpu_device_cache_pci_state(struct pci_dev *pdev);
 bool amdgpu_device_load_pci_state(struct pci_dev *pdev);
 
+void amdgpu_finilize_device_fences(struct drm_device *dev);
+
 #include "amdgpu_object.h"
 
 static inline bool amdgpu_is_tmz(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 33e8e9e1d1fe..55afc11c17e6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -3692,15 +3692,12 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
 		amdgpu_virt_fini_data_exchange(adev);
 	}
 
-	/* disable all interrupts */
-	amdgpu_irq_disable_all(adev);
 	if (adev->mode_info.mode_config_initialized){
 		if (!amdgpu_device_has_dc_support(adev))
 			drm_helper_force_disable_all(adev_to_drm(adev));
 		else
 			drm_atomic_helper_shutdown(adev_to_drm(adev));
 	}
-	amdgpu_fence_driver_fini_hw(adev);
 
 	if (adev->pm_sysfs_en)
 		amdgpu_pm_sysfs_fini(adev);
@@ -4567,14 +4564,19 @@ static bool amdgpu_device_lock_adev(struct amdgpu_device *adev,
 	return true;
 }
 
-static void amdgpu_device_unlock_adev(struct amdgpu_device *adev)
+static void amdgpu_device_unlock_adev_imp(struct amdgpu_device *adev, bool skip_in_gpu_reset)
 {
 	amdgpu_vf_error_trans_all(adev);
 	adev->mp1_state = PP_MP1_STATE_NONE;
-	atomic_set(&adev->in_gpu_reset, 0);
+	!skip_in_gpu_reset ? atomic_set(&adev->in_gpu_reset, 0) : 0;
 	up_write(&adev->reset_sem);
 }
 
+static void amdgpu_device_unlock_adev(struct amdgpu_device *adev)
+{
+	amdgpu_device_unlock_adev_imp(adev, false);
+}
+
 /*
  * to lockup a list of amdgpu devices in a hive safely, if not a hive
  * with multiple nodes, it will be similar as amdgpu_device_lock_adev.
@@ -5321,3 +5323,89 @@ bool amdgpu_device_load_pci_state(struct pci_dev *pdev)
 }
 
 
+static void amdgpu_finilize_schedulded_fences(struct amdgpu_ctx_mgr *mgr)
+{
+	struct amdgpu_ctx *ctx;
+	struct idr *idp;
+	uint32_t id, i, j;
+
+	idp = &mgr->ctx_handles;
+
+	idr_for_each_entry(idp, ctx, id) {
+		for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
+			for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
+				struct drm_sched_entity *entity;
+
+				if (!ctx->entities[i][j])
+					continue;
+
+				entity = &ctx->entities[i][j]->entity;
+				drm_sched_entity_kill_jobs(entity);
+			}
+		}
+	}
+}
+
+/**
+ * amdgpu_finilize_device_fences() - Finilize all device fences
+ * @pdev: pointer to PCI device
+ *
+ * Will disable and finilise ISRs and will signal all fences
+ * that might hang if HW is gone
+ */
+void amdgpu_finilize_device_fences(struct drm_device *dev)
+{
+	struct amdgpu_device *adev = drm_to_adev(dev);
+	struct drm_file *file;
+
+	/*
+	 *  Block TDRs from further execution by setting adev->in_gpu_reset
+	 *  instead of holding full reset lock in order to not deadlock
+	 *  further ahead against any thread locking the reset lock when we
+	 *  wait for it's completion
+	 */
+	while (!amdgpu_device_lock_adev(adev, NULL))
+		amdgpu_cancel_all_tdr(adev);
+	amdgpu_device_unlock_adev_imp(adev, true);
+
+
+	/* disable all HW interrupts */
+	amdgpu_irq_disable_all(adev);
+
+	/* stop and flush all in flight HW interrupts handlers */
+	disable_irq(pci_irq_vector(adev->pdev, 0));
+
+	/*
+	 * Stop SW GPU schedulers and force completion on all HW fences. Since
+	 * in the prev. step all ISRs were disabled and completed the
+	 * HW fence array is idle (no insertions or extractions) and so it's
+	 * safe to iterate it bellow.
+	 * After this step all HW fences in the system are signaled. As a result
+	 * also all the scheduler 'finished' fences are also signaled.
+	 */
+	amdgpu_fence_driver_fini_hw(adev);
+
+	/*
+	 * Reject any further jobs to any scheduler entity queue. After this
+	 * step no new insertions and because schedulers are stopped also no
+	 * new extractions.
+	 */
+	down_read(&adev->sched_fence_completion_sem);
+	adev->stop_job_submissions = true;
+	up_read(&adev->sched_fence_completion_sem);
+
+	/*
+	 * Complete all scheduler 'scheduled' fences currently pending.
+	 * It's OK if new contexts and sched entities are concurrently
+	 * still created as they will fail in pushing jobs to SW queues
+	 * and their schedule fences will be signaled with error
+	 */
+	mutex_lock(&adev->ddev.filelist_mutex);
+	list_for_each_entry(file, &adev->ddev.filelist, lhead) {
+		struct amdgpu_fpriv *fpriv = file->driver_priv;
+		amdgpu_finilize_schedulded_fences(&fpriv->ctx_mgr);
+	}
+	mutex_unlock(&adev->ddev.filelist_mutex);
+}
+
+
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index f799c40d7e72..8a19b8dd02ee 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -1249,6 +1249,12 @@ amdgpu_pci_remove(struct pci_dev *pdev)
 {
 	struct drm_device *dev = pci_get_drvdata(pdev);
 
+	/*
+	 * Force completion of all device related fences that might hang us when
+	 * synchronizing SRCU in the following step.
+	 */
+	amdgpu_finilize_device_fences(dev);
+
 	drm_dev_unplug(dev);
 	amdgpu_driver_unload_kms(dev);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
index 2670201e78d3..af592b28cd35 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -526,7 +526,7 @@ int amdgpu_fence_driver_init(struct amdgpu_device *adev)
  */
 void amdgpu_fence_driver_fini_hw(struct amdgpu_device *adev)
 {
-	int i, r;
+	int i;
 
 	for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
 		struct amdgpu_ring *ring = adev->rings[i];
@@ -535,18 +535,10 @@ void amdgpu_fence_driver_fini_hw(struct amdgpu_device *adev)
 			continue;
 
 		/* Stop any new job submissions from sched before flushing the ring */
-		/* TODO Handle amdgpu_job_submit_direct and amdgpu_amdkfd_submit_ib */
 		if (!ring->no_scheduler)
 			drm_sched_fini(&ring->sched);
 
-		/* You can't wait for HW to signal if it's gone */
-		if (!drm_dev_is_unplugged(&adev->ddev))
-			r = amdgpu_fence_wait_empty(ring);
-		else
-			r = -ENODEV;
-		/* no need to trigger GPU reset as we are unloading */
-		if (r)
-			amdgpu_fence_driver_force_completion(ring);
+		amdgpu_fence_driver_force_completion(ring);
 
 		if (ring->fence_drv.irq_src)
 			amdgpu_irq_put(adev, ring->fence_drv.irq_src,
-- 
2.25.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

  parent reply	other threads:[~2021-04-28 15:13 UTC|newest]

Thread overview: 244+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-28 15:11 [PATCH v5 00/27] RFC Support hot device unplug in amdgpu Andrey Grodzovsky
2021-04-28 15:11 ` Andrey Grodzovsky
2021-04-28 15:11 ` Andrey Grodzovsky
2021-04-28 15:11 ` [PATCH v5 01/27] drm/ttm: Remap all page faults to per process dummy page Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11 ` [PATCH v5 02/27] drm/ttm: Expose ttm_tt_unpopulate for driver use Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11 ` [PATCH v5 03/27] drm/amdgpu: Split amdgpu_device_fini into early and late Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-29  7:04   ` Christian König
2021-04-29  7:04     ` Christian König
2021-04-29  7:04     ` Christian König
2021-04-30  3:10     ` Alex Deucher
2021-04-30  3:10       ` Alex Deucher
2021-04-30  3:10       ` Alex Deucher
2021-04-30  5:19   ` Lazar, Lijo
2021-04-30  5:19     ` Lazar, Lijo
2021-04-30  5:39     ` Andrey Grodzovsky
2021-04-30  5:39       ` Andrey Grodzovsky
2021-04-30  5:39       ` Andrey Grodzovsky
2021-04-30  5:49       ` Lazar, Lijo
2021-04-30  5:49         ` Lazar, Lijo
2021-04-28 15:11 ` [PATCH v5 04/27] drm/amdkfd: Split kfd suspend from devie exit Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11 ` [PATCH v5 05/27] drm/amdgpu: Add early fini callback Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11 ` [PATCH v5 06/27] drm/amdgpu: Handle IOMMU enabled case Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-29  7:08   ` Christian König
2021-04-29  7:08     ` Christian König
2021-04-29  7:08     ` Christian König
2021-05-03 20:43     ` Andrey Grodzovsky
2021-05-03 20:43       ` Andrey Grodzovsky
2021-05-03 20:43       ` Andrey Grodzovsky
2021-05-04  7:03       ` Christian König
2021-05-04  7:03         ` Christian König
2021-05-04  7:03         ` Christian König
2021-05-04 15:43         ` Andrey Grodzovsky
2021-05-04 15:43           ` Andrey Grodzovsky
2021-05-04 15:43           ` Andrey Grodzovsky
2021-05-05 14:51           ` Andrey Grodzovsky
2021-05-05 14:51             ` Andrey Grodzovsky
2021-05-05 14:51             ` Andrey Grodzovsky
2021-04-30  3:13   ` Alex Deucher
2021-04-30  3:13     ` Alex Deucher
2021-04-30  3:13     ` Alex Deucher
2021-05-03 18:00     ` Andrey Grodzovsky
2021-05-03 18:00       ` Andrey Grodzovsky
2021-05-03 18:00       ` Andrey Grodzovsky
2021-05-04 17:05   ` Felix Kuehling
2021-05-04 17:05     ` Felix Kuehling
2021-05-04 17:05     ` Felix Kuehling
2021-05-05 14:05     ` Andrey Grodzovsky
2021-05-05 14:05       ` Andrey Grodzovsky
2021-05-05 14:05       ` Andrey Grodzovsky
2021-04-28 15:11 ` [PATCH v5 07/27] drm/amdgpu: Remap all page faults to per process dummy page Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-29  7:09   ` Christian König
2021-04-29  7:09     ` Christian König
2021-04-29  7:09     ` Christian König
2021-04-28 15:11 ` [PATCH v5 08/27] PCI: add support for dev_groups to struct pci_device_driver Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 16:53   ` Bjorn Helgaas
2021-04-28 16:53     ` Bjorn Helgaas
2021-04-28 16:53     ` Bjorn Helgaas
2021-04-29 16:53     ` Andrey Grodzovsky
2021-04-29 16:53       ` Andrey Grodzovsky
2021-04-29 16:53       ` Andrey Grodzovsky
2021-04-29 19:23       ` Bjorn Helgaas
2021-04-29 19:23         ` Bjorn Helgaas
2021-04-29 19:23         ` Bjorn Helgaas
2021-04-29 20:36         ` Andrey Grodzovsky
2021-04-29 20:36           ` Andrey Grodzovsky
2021-04-29 20:36           ` Andrey Grodzovsky
2021-04-28 15:11 ` [PATCH v5 09/27] dmr/amdgpu: Move some sysfs attrs creation to default_attr Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 17:23   ` Bjorn Helgaas
2021-04-28 17:23     ` Bjorn Helgaas
2021-04-28 17:23     ` Bjorn Helgaas
2021-04-29  7:11   ` Christian König
2021-04-29  7:11     ` Christian König
2021-04-29  7:11     ` Christian König
2021-04-28 15:11 ` [PATCH v5 10/27] drm/amdgpu: Guard against write accesses after device removal Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-29  7:14   ` Christian König
2021-04-29  7:14     ` Christian König
2021-04-29  7:14     ` Christian König
2021-04-28 15:11 ` [PATCH v5 11/27] drm/sched: Make timeout timer rearm conditional Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11 ` [PATCH v5 12/27] drm/amdgpu: Prevent any job recoveries after device is unplugged Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11 ` [PATCH v5 13/27] drm/amdgpu: When filizing the fence driver. stop scheduler first Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-29  7:15   ` Christian König
2021-04-29  7:15     ` Christian König
2021-04-29  7:15     ` Christian König
2021-04-29 17:12     ` Andrey Grodzovsky
2021-04-29 17:12       ` Andrey Grodzovsky
2021-04-29 17:12       ` Andrey Grodzovsky
2021-04-28 15:11 ` [PATCH v5 14/27] drm/amdgpu: Fix hang on device removal Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11 ` [PATCH v5 15/27] drm/scheduler: Fix hang when sched_entity released Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-29  7:18   ` Christian König
2021-04-29  7:18     ` Christian König
2021-04-29  7:18     ` Christian König
2021-04-29 17:06     ` Andrey Grodzovsky
2021-04-29 17:06       ` Andrey Grodzovsky
2021-04-29 17:06       ` Andrey Grodzovsky
2021-04-30  6:47       ` Christian König
2021-04-30  6:47         ` Christian König
2021-04-30  6:47         ` Christian König
2021-04-30 16:10         ` Andrey Grodzovsky
2021-04-30 16:10           ` Andrey Grodzovsky
2021-04-30 16:10           ` Andrey Grodzovsky
2021-05-05 13:57           ` Andrey Grodzovsky
2021-05-05 13:57             ` Andrey Grodzovsky
2021-05-05 13:57             ` Andrey Grodzovsky
2021-05-07 16:29           ` Daniel Vetter
2021-05-07 16:29             ` Daniel Vetter
2021-05-07 16:29             ` Daniel Vetter
2021-05-07 16:32             ` Andrey Grodzovsky
2021-05-07 16:32               ` Andrey Grodzovsky
2021-05-07 16:32               ` Andrey Grodzovsky
2021-04-28 15:11 ` [PATCH v5 16/27] drm/amdgpu: Unmap all MMIO mappings Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-29  7:19   ` Christian König
2021-04-29  7:19     ` Christian König
2021-04-29  7:19     ` Christian König
2021-04-29 16:55     ` Andrey Grodzovsky
2021-04-29 16:55       ` Andrey Grodzovsky
2021-04-29 16:55       ` Andrey Grodzovsky
2021-04-28 15:11 ` [PATCH v5 17/27] drm/amdgpu: Add rw_sem to pushing job into sched queue Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11 ` [PATCH v5 18/27] drm/sched: Expose drm_sched_entity_kill_jobs Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:11 ` Andrey Grodzovsky [this message]
2021-04-28 15:11   ` [PATCH v5 19/27] drm/amdgpu: Finilise device fences on device remove Andrey Grodzovsky
2021-04-28 15:11   ` Andrey Grodzovsky
2021-04-28 15:20   ` Andrey Grodzovsky
2021-04-28 15:20     ` Andrey Grodzovsky
2021-04-28 15:20     ` Andrey Grodzovsky
2021-04-28 15:12 ` [PATCH v5 20/27] drm: Scope all DRM IOCTLs with drm_dev_enter/exit Andrey Grodzovsky
2021-04-28 15:12   ` Andrey Grodzovsky
2021-04-28 15:12   ` Andrey Grodzovsky
2021-04-29 11:23   ` Daniel Vetter
2021-04-29 11:23     ` Daniel Vetter
2021-04-29 11:23     ` Daniel Vetter
2021-04-29 11:32     ` Daniel Vetter
2021-04-29 11:32       ` Daniel Vetter
2021-04-29 11:32       ` Daniel Vetter
2021-04-29 16:04       ` Andrey Grodzovsky
2021-04-29 16:04         ` Andrey Grodzovsky
2021-04-29 16:04         ` Andrey Grodzovsky
2021-04-29 16:15         ` Felix Kuehling
2021-04-29 16:15           ` Felix Kuehling
2021-04-29 16:15           ` Felix Kuehling
2021-04-29 16:21           ` Andrey Grodzovsky
2021-04-29 16:21             ` Andrey Grodzovsky
2021-04-29 16:21             ` Andrey Grodzovsky
2021-04-29 16:29             ` Felix Kuehling
2021-04-29 16:29               ` Felix Kuehling
2021-04-29 16:29               ` Felix Kuehling
2021-04-29 16:33               ` Andrey Grodzovsky
2021-04-29 16:33                 ` Andrey Grodzovsky
2021-04-29 16:33                 ` Andrey Grodzovsky
2021-04-29 19:05         ` Daniel Vetter
2021-04-29 19:05           ` Daniel Vetter
2021-04-29 19:05           ` Daniel Vetter
2021-04-29 20:34           ` Andrey Grodzovsky
2021-04-29 20:34             ` Andrey Grodzovsky
2021-04-29 20:34             ` Andrey Grodzovsky
2021-04-30 10:25             ` Daniel Vetter
2021-04-30 10:25               ` Daniel Vetter
2021-04-30 10:25               ` Daniel Vetter
2021-04-30 17:27               ` Andrey Grodzovsky
2021-04-30 17:27                 ` Andrey Grodzovsky
2021-04-30 17:27                 ` Andrey Grodzovsky
2021-05-05 13:57                 ` Andrey Grodzovsky
2021-05-05 13:57                   ` Andrey Grodzovsky
2021-05-05 13:57                   ` Andrey Grodzovsky
2021-05-06  9:40                 ` Daniel Vetter
2021-05-06  9:40                   ` Daniel Vetter
2021-05-06  9:40                   ` Daniel Vetter
2021-05-06 16:25                   ` Andrey Grodzovsky
2021-05-06 16:25                     ` Andrey Grodzovsky
2021-05-06 16:25                     ` Andrey Grodzovsky
2021-05-07  9:11                     ` Daniel Vetter
2021-05-07  9:11                       ` Daniel Vetter
2021-05-07  9:11                       ` Daniel Vetter
2021-05-07 15:39                       ` Andrey Grodzovsky
2021-05-07 15:39                         ` Andrey Grodzovsky
2021-05-07 15:39                         ` Andrey Grodzovsky
2021-05-07 16:24                         ` Daniel Vetter
2021-05-07 16:24                           ` Daniel Vetter
2021-05-07 16:24                           ` Daniel Vetter
2021-05-07 18:00                           ` Andrey Grodzovsky
2021-05-07 18:00                             ` Andrey Grodzovsky
2021-05-07 18:00                             ` Andrey Grodzovsky
2021-05-10 15:46                             ` Daniel Vetter
2021-05-10 15:46                               ` Daniel Vetter
2021-05-10 15:46                               ` Daniel Vetter
2021-04-28 15:12 ` [PATCH v5 21/27] drm/amdgpu: Add support for hot-unplug feature at DRM level Andrey Grodzovsky
2021-04-28 15:12   ` Andrey Grodzovsky
2021-04-28 15:12   ` Andrey Grodzovsky
2021-04-28 15:12 ` [PATCH v5 22/27] drm/amd/display: Scope all DM queued work with drm_dev_enter/exit Andrey Grodzovsky
2021-04-28 15:12   ` Andrey Grodzovsky
2021-04-28 15:12   ` Andrey Grodzovsky
2021-04-28 15:12 ` [PATCH v5 23/27] drm/amd/powerplay: Scope all PM " Andrey Grodzovsky
2021-04-28 15:12   ` Andrey Grodzovsky
2021-04-28 15:12   ` Andrey Grodzovsky
2021-04-28 15:12 ` [PATCH v5 24/27] drm/amdkfd: Scope all KFD " Andrey Grodzovsky
2021-04-28 15:12   ` Andrey Grodzovsky
2021-04-28 15:12   ` Andrey Grodzovsky
2021-04-28 15:12 ` [PATCH v5 25/27] drm/amdgpu: Scope all amdgpu " Andrey Grodzovsky
2021-04-28 15:12   ` Andrey Grodzovsky
2021-04-28 15:12   ` Andrey Grodzovsky
2021-04-28 15:12 ` [PATCH v5 26/27] drm/amd/display: Remove superflous drm_mode_config_cleanup Andrey Grodzovsky
2021-04-28 15:12   ` Andrey Grodzovsky
2021-04-28 15:12   ` Andrey Grodzovsky
2021-04-28 15:12 ` [PATCH v5 27/27] drm/amdgpu: Verify DMA opearations from device are done Andrey Grodzovsky
2021-04-28 15:12   ` Andrey Grodzovsky
2021-04-28 15:12   ` Andrey Grodzovsky
2021-04-28 17:07 ` [PATCH v5 00/27] RFC Support hot device unplug in amdgpu Bjorn Helgaas
2021-04-28 17:07   ` Bjorn Helgaas
2021-04-28 17:07   ` Bjorn Helgaas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210428151207.1212258-20-andrey.grodzovsky@amd.com \
    --to=andrey.grodzovsky@amd.com \
    --cc=Alexander.Deucher@amd.com \
    --cc=Felix.Kuehling@amd.com \
    --cc=Harry.Wentland@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=ckoenig.leichtzumerken@gmail.com \
    --cc=daniel.vetter@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=helgaas@kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=ppaalanen@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.