All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andres Rodriguez <andresx7-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
Cc: Andres Rodriguez <andresx7-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Subject: [PATCH 19/22] drm/amdgpu: add framework for HW specific priority settings
Date: Tue, 28 Feb 2017 17:14:46 -0500	[thread overview]
Message-ID: <1488320089-22035-20-git-send-email-andresx7@gmail.com> (raw)
In-Reply-To: <1488320089-22035-1-git-send-email-andresx7-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Add an initial framework for changing the HW priorities of rings. The
framework allows requesting priority changes for the lifetime of an
amdgpu_job. After the job completes the priority will decay to the next
lowest priority for which a request is still valid.

A new ring function set_priority() can now be populated to take care of
the HW specific programming sequence for priority changes.

Signed-off-by: Andres Rodriguez <andresx7@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h      |  4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c   |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.c  | 10 ++++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 71 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 11 +++++
 5 files changed, 94 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 366f6d3..0676495 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -636,21 +636,21 @@ struct amdgpu_flip_work {
 struct amdgpu_ib {
 	struct amdgpu_sa_bo		*sa_bo;
 	uint32_t			length_dw;
 	uint64_t			gpu_addr;
 	uint32_t			*ptr;
 	uint32_t			flags;
 };
 
 extern const struct amd_sched_backend_ops amdgpu_sched_ops;
 
-int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
+int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, int priority,
 		     struct amdgpu_job **job, struct amdgpu_vm *vm);
 int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
 			     struct amdgpu_job **job);
 
 void amdgpu_job_free_resources(struct amdgpu_job *job);
 void amdgpu_job_free(struct amdgpu_job *job);
 int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring,
 		      struct amd_sched_entity *entity, void *owner,
 		      struct dma_fence **f);
 
@@ -990,20 +990,22 @@ struct amdgpu_cs_parser {
 #define AMDGPU_VM_DOMAIN                    (1 << 3) /* bit set means in virtual memory context */
 
 struct amdgpu_job {
 	struct amd_sched_job    base;
 	struct amdgpu_device	*adev;
 	struct amdgpu_vm	*vm;
 	struct amdgpu_ring	*ring;
 	struct amdgpu_sync	sync;
 	struct amdgpu_ib	*ibs;
 	struct dma_fence	*fence; /* the hw fence */
+	struct dma_fence_cb	cb;
+	int			priority;
 	uint32_t		preamble_status;
 	uint32_t		num_ibs;
 	void			*owner;
 	uint64_t		fence_ctx; /* the fence_context this job uses */
 	bool                    vm_needs_flush;
 	unsigned		vm_id;
 	uint64_t		vm_pd_addr;
 	uint32_t		gds_base, gds_size;
 	uint32_t		gws_base, gws_size;
 	uint32_t		oa_base, oa_size;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 605d40e..19ce202 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -179,21 +179,21 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
 
 		case AMDGPU_CHUNK_ID_DEPENDENCIES:
 			break;
 
 		default:
 			ret = -EINVAL;
 			goto free_partial_kdata;
 		}
 	}
 
-	ret = amdgpu_job_alloc(p->adev, num_ibs, &p->job, vm);
+	ret = amdgpu_job_alloc(p->adev, num_ibs, p->ctx->priority, &p->job, vm);
 	if (ret)
 		goto free_all_kdata;
 
 	if (p->uf_entry.robj)
 		p->job->uf_addr = uf_offset;
 	kfree(chunk_array);
 	return 0;
 
 free_all_kdata:
 	i = p->nchunks - 1;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index 86a1242..45b3c90 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -32,50 +32,51 @@ static void amdgpu_job_timedout(struct amd_sched_job *s_job)
 {
 	struct amdgpu_job *job = container_of(s_job, struct amdgpu_job, base);
 
 	DRM_ERROR("ring %s timeout, last signaled seq=%u, last emitted seq=%u\n",
 		  job->base.sched->name,
 		  atomic_read(&job->ring->fence_drv.last_seq),
 		  job->ring->fence_drv.sync_seq);
 	amdgpu_gpu_reset(job->adev);
 }
 
-int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
+int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, int priority,
 		     struct amdgpu_job **job, struct amdgpu_vm *vm)
 {
 	size_t size = sizeof(struct amdgpu_job);
 
 	if (num_ibs == 0)
 		return -EINVAL;
 
 	size += sizeof(struct amdgpu_ib) * num_ibs;
 
 	*job = kzalloc(size, GFP_KERNEL);
 	if (!*job)
 		return -ENOMEM;
 
 	(*job)->adev = adev;
 	(*job)->vm = vm;
+	(*job)->priority = priority;
 	(*job)->ibs = (void *)&(*job)[1];
 	(*job)->num_ibs = num_ibs;
 
 	amdgpu_sync_create(&(*job)->sync);
 
 	return 0;
 }
 
 int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
 			     struct amdgpu_job **job)
 {
 	int r;
 
-	r = amdgpu_job_alloc(adev, 1, job, NULL);
+	r = amdgpu_job_alloc(adev, 1, AMDGPU_CTX_PRIORITY_NORMAL, job, NULL);
 	if (r)
 		return r;
 
 	r = amdgpu_ib_get(adev, NULL, size, &(*job)->ibs[0]);
 	if (r)
 		kfree(*job);
 
 	return r;
 }
 
@@ -170,20 +171,25 @@ static struct dma_fence *amdgpu_job_run(struct amd_sched_job *sched_job)
 	BUG_ON(amdgpu_sync_peek_fence(&job->sync, NULL));
 
 	trace_amdgpu_sched_run_job(job);
 	r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs, job, &fence);
 	if (r)
 		DRM_ERROR("Error scheduling IBs (%d)\n", r);
 
 	/* if gpu reset, hw fence will be replaced here */
 	dma_fence_put(job->fence);
 	job->fence = dma_fence_get(fence);
+
+	r = amdgpu_ring_elevate_priority(job->ring, job->priority, job);
+	if (r)
+		DRM_ERROR("Failed to set job priority (%d)\n", r);
+
 	amdgpu_job_free_resources(job);
 	return fence;
 }
 
 const struct amd_sched_backend_ops amdgpu_sched_ops = {
 	.dependency = amdgpu_job_dependency,
 	.run_job = amdgpu_job_run,
 	.timedout_job = amdgpu_job_timedout,
 	.free_job = amdgpu_job_free_cb
 };
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
index 80cb051..12bc7a9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -192,20 +192,89 @@ void amdgpu_ring_commit(struct amdgpu_ring *ring)
  * Reset the driver's copy of the wptr (all asics).
  */
 void amdgpu_ring_undo(struct amdgpu_ring *ring)
 {
 	ring->wptr = ring->wptr_old;
 
 	if (ring->funcs->end_use)
 		ring->funcs->end_use(ring);
 }
 
+static void amdgpu_ring_restore_priority_cb(struct dma_fence *f,
+					    struct dma_fence_cb *cb)
+{
+	int i;
+	struct amdgpu_job *cb_job =
+		container_of(cb, struct amdgpu_job, cb);
+	struct amdgpu_ring *ring = cb_job->ring;
+
+	spin_lock(&ring->priority_lock);
+
+	/* remove ourselves from the list if necessary */
+	if (cb_job == ring->last_job[cb_job->priority])
+		ring->last_job[cb_job->priority] = NULL;
+
+	/* something higher prio is executing, no need to decay */
+	if (ring->priority > cb_job->priority)
+		goto out_unlock;
+
+	/* decay priority to the next level with a job available */
+	for (i = cb_job->priority; i >= 0; i--) {
+		if (i == AMDGPU_CTX_PRIORITY_NORMAL || ring->last_job[i]) {
+			ring->priority = i;
+			if (ring->funcs->set_priority)
+				ring->funcs->set_priority(ring, i);
+
+			break;
+		}
+	}
+
+out_unlock:
+	spin_unlock(&ring->priority_lock);
+}
+
+/**
+ * amdgpu_ring_elevate_priority - change the ring's priority
+ *
+ * @ring: amdgpu_ring structure holding the information
+ * @priority: target priority
+ * @job: priority should remain elevated for the duration of this job
+ *
+ * Use HW specific mechanism's to elevate the ring's priority while @job
+ * is executing. Once @job finishes executing, the ring will reset back
+ * to normal priority.
+ * Returns 0 on success, error otherwise
+ */
+int amdgpu_ring_elevate_priority(struct amdgpu_ring *ring, int priority,
+				 struct amdgpu_job *job)
+{
+	if (priority < 0 || priority >= AMDGPU_CTX_PRIORITY_NUM)
+		return -EINVAL;
+
+	spin_lock(&ring->priority_lock);
+	ring->last_job[priority] = job;
+
+	if (priority <= ring->priority)
+		goto out_unlock;
+
+	ring->priority = priority;
+	if (ring->funcs->set_priority)
+		ring->funcs->set_priority(ring, priority);
+
+	dma_fence_add_callback(job->fence, &job->cb,
+			       amdgpu_ring_restore_priority_cb);
+
+out_unlock:
+	spin_unlock(&ring->priority_lock);
+	return 0;
+}
+
 /**
  * amdgpu_ring_init - init driver ring struct.
  *
  * @adev: amdgpu_device pointer
  * @ring: amdgpu_ring structure holding ring information
  * @max_ndw: maximum number of dw for ring alloc
  * @nop: nop packet for this ring
  *
  * Initialize the driver information for the selected ring (all asics).
  * Returns 0 on success, error on failure.
@@ -275,20 +344,22 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
 					    (void **)&ring->ring);
 		if (r) {
 			dev_err(adev->dev, "(%d) ring create failed\n", r);
 			return r;
 		}
 		memset((void *)ring->ring, 0, ring->ring_size);
 	}
 	ring->ptr_mask = (ring->ring_size / 4) - 1;
 	ring->max_dw = max_dw;
 	ring->hw_ip = hw_ip;
+	ring->priority = AMDGPU_CTX_PRIORITY_NORMAL;
+	spin_lock_init(&ring->priority_lock);
 	INIT_LIST_HEAD(&ring->lru_list);
 	amdgpu_ring_lru_touch(adev, ring);
 
 	if (amdgpu_debugfs_ring_init(adev, ring)) {
 		DRM_ERROR("Failed to register debugfs file for rings !\n");
 	}
 	return 0;
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
index ecdd87c..befc29f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
@@ -17,20 +17,21 @@
  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  *
  * Authors: Christian König
  */
 #ifndef __AMDGPU_RING_H__
 #define __AMDGPU_RING_H__
 
+#include <drm/amdgpu_drm.h>
 #include "gpu_scheduler.h"
 
 /* max number of rings */
 #define AMDGPU_MAX_RINGS		16
 #define AMDGPU_MAX_GFX_RINGS		1
 #define AMDGPU_MAX_COMPUTE_RINGS	8
 #define AMDGPU_MAX_VCE_RINGS		3
 
 /* some special values for the owner field */
 #define AMDGPU_FENCE_OWNER_UNDEFINED	((void*)0ul)
@@ -130,20 +131,22 @@ struct amdgpu_ring_funcs {
 	void (*pad_ib)(struct amdgpu_ring *ring, struct amdgpu_ib *ib);
 	unsigned (*init_cond_exec)(struct amdgpu_ring *ring);
 	void (*patch_cond_exec)(struct amdgpu_ring *ring, unsigned offset);
 	/* note usage for clock and power gating */
 	void (*begin_use)(struct amdgpu_ring *ring);
 	void (*end_use)(struct amdgpu_ring *ring);
 	void (*emit_switch_buffer) (struct amdgpu_ring *ring);
 	void (*emit_cntxcntl) (struct amdgpu_ring *ring, uint32_t flags);
 	void (*emit_rreg)(struct amdgpu_ring *ring, uint32_t reg);
 	void (*emit_wreg)(struct amdgpu_ring *ring, uint32_t reg, uint32_t val);
+	/* priority functions */
+	void (*set_priority) (struct amdgpu_ring *ring, int priority);
 };
 
 struct amdgpu_ring {
 	struct amdgpu_device		*adev;
 	const struct amdgpu_ring_funcs	*funcs;
 	struct amdgpu_fence_driver	fence_drv;
 	struct amd_gpu_scheduler	sched;
 	struct list_head		lru_list;
 
 	struct amdgpu_bo	*ring_obj;
@@ -165,31 +168,39 @@ struct amdgpu_ring {
 	struct amdgpu_bo	*mqd_obj;
 	u32			doorbell_index;
 	bool			use_doorbell;
 	unsigned		wptr_offs;
 	unsigned		fence_offs;
 	uint64_t		current_ctx;
 	char			name[16];
 	unsigned		cond_exe_offs;
 	u64			cond_exe_gpu_addr;
 	volatile u32		*cond_exe_cpu_addr;
+
+	spinlock_t		priority_lock;
+	/* protected by priority_lock */
+	struct amdgpu_job 	*last_job[AMDGPU_CTX_PRIORITY_NUM];
+	int			priority;
+
 #if defined(CONFIG_DEBUG_FS)
 	struct dentry *ent;
 #endif
 };
 
 int amdgpu_ring_is_valid_index(struct amdgpu_device *adev,
 			       int hw_ip, int ring);
 int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned ndw);
 void amdgpu_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count);
 void amdgpu_ring_generic_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib);
 void amdgpu_ring_commit(struct amdgpu_ring *ring);
 void amdgpu_ring_undo(struct amdgpu_ring *ring);
+int amdgpu_ring_elevate_priority(struct amdgpu_ring *ring, int priority,
+				 struct amdgpu_job *job);
 int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
 		     int hw_ip, unsigned ring_size,
 		     struct amdgpu_irq_src *irq_src, unsigned irq_type);
 void amdgpu_ring_fini(struct amdgpu_ring *ring);
 int amdgpu_ring_lru_get(struct amdgpu_device *adev, int hw_ip,
 			struct amdgpu_ring **ring);
 void amdgpu_ring_lru_touch(struct amdgpu_device *adev, struct amdgpu_ring *ring);
 
 #endif
-- 
2.7.4

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

  parent reply	other threads:[~2017-02-28 22:14 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-28 22:14 Add support for high priority scheduling in amdgpu Andres Rodriguez
     [not found] ` <1488320089-22035-1-git-send-email-andresx7-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-02-28 22:14   ` [PATCH 01/22] drm/amdgpu: refactor MQD/HQD initialization Andres Rodriguez
2017-02-28 22:14   ` [PATCH 02/22] drm/amdgpu: doorbell registers need only be set once v2 Andres Rodriguez
2017-02-28 22:14   ` [PATCH 03/22] drm/amdgpu: detect timeout error when deactivating hqd Andres Rodriguez
2017-02-28 22:14   ` [PATCH 04/22] drm/amdgpu: remove duplicate definition of cik_mqd Andres Rodriguez
2017-02-28 22:14   ` [PATCH 05/22] drm/amdgpu: unify MQD programming sequence for kfd and amdgpu Andres Rodriguez
2017-02-28 22:14   ` [PATCH 06/22] drm/amdgpu: rename rdev to adev Andres Rodriguez
2017-02-28 22:14   ` [PATCH 07/22] drm/amdgpu: take ownership of per-pipe configuration Andres Rodriguez
2017-02-28 22:14   ` [PATCH 08/22] drm/radeon: take ownership of pipe initialization Andres Rodriguez
2017-02-28 22:14   ` [PATCH 09/22] drm/amdgpu: allow split of queues with kfd at queue granularity Andres Rodriguez
2017-02-28 22:14   ` [PATCH 10/22] drm/amdgpu: teach amdgpu how to enable interrupts for any pipe Andres Rodriguez
2017-02-28 22:14   ` [PATCH 11/22] drm/amdkfd: allow split HQD on per-queue granularity v3 Andres Rodriguez
2017-02-28 22:14   ` [PATCH 12/22] drm/amdgpu: remove duplicate magic constants from amdgpu_amdkfd_gfx*.c Andres Rodriguez
2017-02-28 22:14   ` [PATCH 13/22] drm/amdgpu: allocate queues horizontally across pipes Andres Rodriguez
2017-02-28 22:14   ` [PATCH 14/22] drm/amdgpu: new queue policy, take first 2 queues of each pipe Andres Rodriguez
2017-02-28 22:14   ` [PATCH 15/22] drm/amdgpu: add hw_ip member to amdgpu_ring Andres Rodriguez
     [not found]     ` <1488320089-22035-16-git-send-email-andresx7-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-03-01 15:33       ` Alex Deucher
2017-02-28 22:14   ` [PATCH 16/22] drm/amdgpu: add a mechanism to untie user ring ids from kernel ring ids Andres Rodriguez
2017-02-28 22:14   ` [PATCH 17/22] drm/amdgpu: implement lru amdgpu_queue_mgr policy for compute Andres Rodriguez
2017-02-28 22:14   ` [PATCH 18/22] drm/amdgpu: add flag for high priority contexts v4 Andres Rodriguez
     [not found]     ` <1488320089-22035-19-git-send-email-andresx7-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-03-01  1:13       ` Emil Velikov
     [not found]         ` <CACvgo51=1-8dHmC8MOmbCijDv3vpD4dTC6hibQMe5bYB9zsB4Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-03-02  3:52           ` Andres Rodriguez
     [not found]             ` <782283a5-3871-0827-ed2c-9069a6dc6734-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-03-03 14:48               ` Emil Velikov
2017-03-01  6:52       ` zhoucm1
     [not found]         ` <58B66FB8.8050300-5C7GfCeVMHo@public.gmane.org>
2017-03-01  7:09           ` zhoucm1
     [not found]             ` <58B673C0.4070006-5C7GfCeVMHo@public.gmane.org>
2017-03-01 11:51               ` Emil Velikov
2017-02-28 22:14   ` Andres Rodriguez [this message]
     [not found]     ` <1488320089-22035-20-git-send-email-andresx7-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-03-01  7:27       ` [PATCH 19/22] drm/amdgpu: add framework for HW specific priority settings zhoucm1
     [not found]         ` <58B677DD.4070408-5C7GfCeVMHo@public.gmane.org>
2017-03-01 15:49           ` Alex Deucher
     [not found]             ` <CADnq5_NhLAOsR7tHhRZRzA12j_-5MWFEXfWeGqKmSifHp_5jKg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-03-01 17:44               ` Andres Rodriguez
     [not found]                 ` <f0de5e4f-bf94-9222-cc9e-1d535c228b0a-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-03-02  6:45                   ` Andres Rodriguez
2017-02-28 22:14   ` [PATCH 20/22] drm/amdgpu: implement ring set_priority for gfx_v8 compute Andres Rodriguez
2017-02-28 22:14   ` [PATCH 21/22] drm/amdgpu: condense mqd programming sequence Andres Rodriguez
2017-02-28 22:14   ` [PATCH 22/22] drm/amdgpu: workaround tonga HW bug in HQD " Andres Rodriguez
2017-03-01 11:42   ` Add support for high priority scheduling in amdgpu Christian König
     [not found]     ` <25194b1a-4756-e1ad-f597-17063a14eb4c-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
2017-03-01 17:13       ` Andres Rodriguez
     [not found]         ` <ddeb4a53-ec4f-9a87-9323-897c571b1634-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-03-01 17:24           ` Andres Rodriguez
     [not found]             ` <4c908b1f-fcb2-7d89-026a-76fd3f4f1f22-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-03-02 11:00               ` Christian König
2017-03-01 16:14   ` Bridgman, John
     [not found]     ` <BN6PR12MB1348B8F1F537321557D522AFE8290-/b2+HYfkarQX0pEhCR5T8QdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
2017-03-01 16:37       ` Andres Rodriguez

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=1488320089-22035-20-git-send-email-andresx7@gmail.com \
    --to=andresx7-re5jqeeqqe8avxtiumwx3w@public.gmane.org \
    --cc=amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    /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.