All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] drm/amd: Add CU-masking ioctl definition to kfd_ioctl.h
@ 2018-07-14 23:05 Felix Kuehling
       [not found] ` <1531609559-30402-1-git-send-email-Felix.Kuehling-5C7GfCeVMHo@public.gmane.org>
  0 siblings, 1 reply; 4+ messages in thread
From: Felix Kuehling @ 2018-07-14 23:05 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	oded.gabbay-Re5JQEeQqe8AvxtiuMwx3w
  Cc: Felix Kuehling

Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
---
 include/uapi/linux/kfd_ioctl.h | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h
index 88d17c3..01674b5 100644
--- a/include/uapi/linux/kfd_ioctl.h
+++ b/include/uapi/linux/kfd_ioctl.h
@@ -76,6 +76,12 @@ struct kfd_ioctl_update_queue_args {
 	__u32 queue_priority;	/* to KFD */
 };
 
+struct kfd_ioctl_set_cu_mask_args {
+	__u32 queue_id;		/* to KFD */
+	__u32 num_cu_mask;		/* to KFD */
+	__u64 cu_mask_ptr;		/* to KFD */
+};
+
 /* For kfd_ioctl_set_memory_policy_args.default_policy and alternate_policy */
 #define KFD_IOC_CACHE_POLICY_COHERENT 0
 #define KFD_IOC_CACHE_POLICY_NONCOHERENT 1
@@ -466,7 +472,10 @@ struct kfd_ioctl_unmap_memory_from_gpu_args {
 #define AMDKFD_IOC_UNMAP_MEMORY_FROM_GPU	\
 		AMDKFD_IOWR(0x19, struct kfd_ioctl_unmap_memory_from_gpu_args)
 
+#define AMDKFD_IOC_SET_CU_MASK		\
+		AMDKFD_IOW(0x1A, struct kfd_ioctl_set_cu_mask_args)
+
 #define AMDKFD_COMMAND_START		0x01
-#define AMDKFD_COMMAND_END		0x1A
+#define AMDKFD_COMMAND_END		0x1B
 
 #endif
-- 
2.7.4

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

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] drm/amdkfd: Add CU-masking ioctl to KFD
       [not found] ` <1531609559-30402-1-git-send-email-Felix.Kuehling-5C7GfCeVMHo@public.gmane.org>
@ 2018-07-14 23:05   ` Felix Kuehling
       [not found]     ` <1531609559-30402-2-git-send-email-Felix.Kuehling-5C7GfCeVMHo@public.gmane.org>
  2018-07-28  9:19   ` [PATCH 1/2] drm/amd: Add CU-masking ioctl definition to kfd_ioctl.h Oded Gabbay
  1 sibling, 1 reply; 4+ messages in thread
From: Felix Kuehling @ 2018-07-14 23:05 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	oded.gabbay-Re5JQEeQqe8AvxtiuMwx3w
  Cc: Eric Huang, Felix Kuehling, Flora Cui, Kent Russell

CU-masking allows a KFD client to control the set of CUs used by a
user mode queue for executing compute dispatches. This can be used
for optimizing the partitioning of the GPU and minimize conflicts
between concurrent tasks.

Signed-off-by: Flora Cui <flora.cui@amd.com>
Signed-off-by: Kent Russell <kent.russell@amd.com>
Signed-off-by: Eric Huang <JinHuiEric.Huang@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
---
 drivers/gpu/drm/amd/amdkfd/kfd_chardev.c           | 58 ++++++++++++++++++++++
 drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c      |  1 +
 drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c       | 41 ++++++++++++++-
 drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h       |  4 ++
 drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c   | 27 ++++++++++
 drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c    | 27 ++++++++++
 drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c    | 27 ++++++++++
 drivers/gpu/drm/amd/amdkfd/kfd_priv.h              |  5 ++
 .../gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 30 +++++++++++
 9 files changed, 219 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index 21d0989..063c941 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -392,6 +392,61 @@ static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p,
 	return retval;
 }
 
+static int kfd_ioctl_set_cu_mask(struct file *filp, struct kfd_process *p,
+					void *data)
+{
+	int retval;
+	const int max_num_cus = 1024;
+	struct kfd_ioctl_set_cu_mask_args *args = data;
+	struct queue_properties properties;
+	uint32_t __user *cu_mask_ptr = (uint32_t __user *)args->cu_mask_ptr;
+	size_t cu_mask_size = sizeof(uint32_t) * (args->num_cu_mask / 32);
+
+	if ((args->num_cu_mask % 32) != 0) {
+		pr_debug("num_cu_mask 0x%x must be a multiple of 32",
+				args->num_cu_mask);
+		return -EINVAL;
+	}
+
+	properties.cu_mask_count = args->num_cu_mask;
+	if (properties.cu_mask_count == 0) {
+		pr_debug("CU mask cannot be 0");
+		return -EINVAL;
+	}
+
+	/* To prevent an unreasonably large CU mask size, set an arbitrary
+	 * limit of max_num_cus bits.  We can then just drop any CU mask bits
+	 * past max_num_cus bits and just use the first max_num_cus bits.
+	 */
+	if (properties.cu_mask_count > max_num_cus) {
+		pr_debug("CU mask cannot be greater than 1024 bits");
+		properties.cu_mask_count = max_num_cus;
+		cu_mask_size = sizeof(uint32_t) * (max_num_cus/32);
+	}
+
+	properties.cu_mask = kzalloc(cu_mask_size, GFP_KERNEL);
+	if (!properties.cu_mask)
+		return -ENOMEM;
+
+	retval = copy_from_user(properties.cu_mask, cu_mask_ptr, cu_mask_size);
+	if (retval) {
+		pr_debug("Could not copy CU mask from userspace");
+		kfree(properties.cu_mask);
+		return -EFAULT;
+	}
+
+	mutex_lock(&p->mutex);
+
+	retval = pqm_set_cu_mask(&p->pqm, args->queue_id, &properties);
+
+	mutex_unlock(&p->mutex);
+
+	if (retval)
+		kfree(properties.cu_mask);
+
+	return retval;
+}
+
 static int kfd_ioctl_set_memory_policy(struct file *filep,
 					struct kfd_process *p, void *data)
 {
@@ -1561,6 +1616,9 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
 	AMDKFD_IOCTL_DEF(AMDKFD_IOC_UNMAP_MEMORY_FROM_GPU,
 			kfd_ioctl_unmap_memory_from_gpu, 0),
 
+	AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_CU_MASK,
+			kfd_ioctl_set_cu_mask, 0),
+
 };
 
 #define AMDKFD_CORE_IOCTL_COUNT	ARRAY_SIZE(amdkfd_ioctls)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
index 2c8897e..9f84b4d 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
@@ -123,6 +123,7 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
 	prop.write_ptr = (uint32_t *) kq->wptr_gpu_addr;
 	prop.eop_ring_buffer_address = kq->eop_gpu_addr;
 	prop.eop_ring_buffer_size = PAGE_SIZE;
+	prop.cu_mask = NULL;
 
 	if (init_queue(&kq->queue, &prop) != 0)
 		goto err_init_queue;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
index 4b8eb50..3bc25ab 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
@@ -21,7 +21,7 @@
  *
  */
 
-#include "kfd_priv.h"
+#include "kfd_mqd_manager.h"
 
 struct mqd_manager *mqd_manager_init(enum KFD_MQD_TYPE type,
 					struct kfd_dev *dev)
@@ -48,3 +48,42 @@ struct mqd_manager *mqd_manager_init(enum KFD_MQD_TYPE type,
 
 	return NULL;
 }
+
+void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm,
+		const uint32_t *cu_mask, uint32_t cu_mask_count,
+		uint32_t *se_mask)
+{
+	struct kfd_cu_info cu_info;
+	uint32_t cu_per_sh[4] = {0};
+	int i, se, cu = 0;
+
+	mm->dev->kfd2kgd->get_cu_info(mm->dev->kgd, &cu_info);
+
+	if (cu_mask_count > cu_info.cu_active_number)
+		cu_mask_count = cu_info.cu_active_number;
+
+	for (se = 0; se < cu_info.num_shader_engines; se++)
+		for (i = 0; i < 4; i++)
+			cu_per_sh[se] += hweight32(cu_info.cu_bitmap[se][i]);
+
+	/* Symmetrically map cu_mask to all SEs:
+	 * cu_mask[0] bit0 -> se_mask[0] bit0;
+	 * cu_mask[0] bit1 -> se_mask[1] bit0;
+	 * ... (if # SE is 4)
+	 * cu_mask[0] bit4 -> se_mask[0] bit1;
+	 * ...
+	 */
+	se = 0;
+	for (i = 0; i < cu_mask_count; i++) {
+		if (cu_mask[i / 32] & (1 << (i % 32)))
+			se_mask[se] |= 1 << cu;
+
+		do {
+			se++;
+			if (se == cu_info.num_shader_engines) {
+				se = 0;
+				cu++;
+			}
+		} while (cu >= cu_per_sh[se] && cu < 32);
+	}
+}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
index 8972bcf..4e84052 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
@@ -93,4 +93,8 @@ struct mqd_manager {
 	struct kfd_dev	*dev;
 };
 
+void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm,
+		const uint32_t *cu_mask, uint32_t cu_mask_count,
+		uint32_t *se_mask);
+
 #endif /* KFD_MQD_MANAGER_H_ */
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
index 4872574..4724316 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
@@ -41,6 +41,31 @@ static inline struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd)
 	return (struct cik_sdma_rlc_registers *)mqd;
 }
 
+static void update_cu_mask(struct mqd_manager *mm, void *mqd,
+			struct queue_properties *q)
+{
+	struct cik_mqd *m;
+	uint32_t se_mask[4] = {0}; /* 4 is the max # of SEs */
+
+	if (q->cu_mask_count == 0)
+		return;
+
+	mqd_symmetrically_map_cu_mask(mm,
+		q->cu_mask, q->cu_mask_count, se_mask);
+
+	m = get_mqd(mqd);
+	m->compute_static_thread_mgmt_se0 = se_mask[0];
+	m->compute_static_thread_mgmt_se1 = se_mask[1];
+	m->compute_static_thread_mgmt_se2 = se_mask[2];
+	m->compute_static_thread_mgmt_se3 = se_mask[3];
+
+	pr_debug("Update cu mask to %#x %#x %#x %#x\n",
+		m->compute_static_thread_mgmt_se0,
+		m->compute_static_thread_mgmt_se1,
+		m->compute_static_thread_mgmt_se2,
+		m->compute_static_thread_mgmt_se3);
+}
+
 static int init_mqd(struct mqd_manager *mm, void **mqd,
 		struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
 		struct queue_properties *q)
@@ -196,6 +221,8 @@ static int __update_mqd(struct mqd_manager *mm, void *mqd,
 	if (q->format == KFD_QUEUE_FORMAT_AQL)
 		m->cp_hqd_pq_control |= NO_UPDATE_RPTR;
 
+	update_cu_mask(mm, mqd, q);
+
 	q->is_active = (q->queue_size > 0 &&
 			q->queue_address != 0 &&
 			q->queue_percent > 0 &&
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
index ad5c9f8..f5fc367 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
@@ -41,6 +41,31 @@ static inline struct v9_sdma_mqd *get_sdma_mqd(void *mqd)
 	return (struct v9_sdma_mqd *)mqd;
 }
 
+static void update_cu_mask(struct mqd_manager *mm, void *mqd,
+			struct queue_properties *q)
+{
+	struct v9_mqd *m;
+	uint32_t se_mask[4] = {0}; /* 4 is the max # of SEs */
+
+	if (q->cu_mask_count == 0)
+		return;
+
+	mqd_symmetrically_map_cu_mask(mm,
+		q->cu_mask, q->cu_mask_count, se_mask);
+
+	m = get_mqd(mqd);
+	m->compute_static_thread_mgmt_se0 = se_mask[0];
+	m->compute_static_thread_mgmt_se1 = se_mask[1];
+	m->compute_static_thread_mgmt_se2 = se_mask[2];
+	m->compute_static_thread_mgmt_se3 = se_mask[3];
+
+	pr_debug("update cu mask to %#x %#x %#x %#x\n",
+		m->compute_static_thread_mgmt_se0,
+		m->compute_static_thread_mgmt_se1,
+		m->compute_static_thread_mgmt_se2,
+		m->compute_static_thread_mgmt_se3);
+}
+
 static int init_mqd(struct mqd_manager *mm, void **mqd,
 			struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
 			struct queue_properties *q)
@@ -198,6 +223,8 @@ static int update_mqd(struct mqd_manager *mm, void *mqd,
 	if (mm->dev->cwsr_enabled && q->ctx_save_restore_area_address)
 		m->cp_hqd_ctx_save_control = 0;
 
+	update_cu_mask(mm, mqd, q);
+
 	q->is_active = (q->queue_size > 0 &&
 			q->queue_address != 0 &&
 			q->queue_percent > 0 &&
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
index 89e4242..b81fda3 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
@@ -43,6 +43,31 @@ static inline struct vi_sdma_mqd *get_sdma_mqd(void *mqd)
 	return (struct vi_sdma_mqd *)mqd;
 }
 
+static void update_cu_mask(struct mqd_manager *mm, void *mqd,
+			struct queue_properties *q)
+{
+	struct vi_mqd *m;
+	uint32_t se_mask[4] = {0}; /* 4 is the max # of SEs */
+
+	if (q->cu_mask_count == 0)
+		return;
+
+	mqd_symmetrically_map_cu_mask(mm,
+		q->cu_mask, q->cu_mask_count, se_mask);
+
+	m = get_mqd(mqd);
+	m->compute_static_thread_mgmt_se0 = se_mask[0];
+	m->compute_static_thread_mgmt_se1 = se_mask[1];
+	m->compute_static_thread_mgmt_se2 = se_mask[2];
+	m->compute_static_thread_mgmt_se3 = se_mask[3];
+
+	pr_debug("Update cu mask to %#x %#x %#x %#x\n",
+		m->compute_static_thread_mgmt_se0,
+		m->compute_static_thread_mgmt_se1,
+		m->compute_static_thread_mgmt_se2,
+		m->compute_static_thread_mgmt_se3);
+}
+
 static int init_mqd(struct mqd_manager *mm, void **mqd,
 			struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
 			struct queue_properties *q)
@@ -196,6 +221,8 @@ static int __update_mqd(struct mqd_manager *mm, void *mqd,
 			atc_bit << CP_HQD_CTX_SAVE_CONTROL__ATC__SHIFT |
 			mtype << CP_HQD_CTX_SAVE_CONTROL__MTYPE__SHIFT;
 
+	update_cu_mask(mm, mqd, q);
+
 	q->is_active = (q->queue_size > 0 &&
 			q->queue_address != 0 &&
 			q->queue_percent > 0 &&
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index ca83254..f971710 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -422,6 +422,9 @@ struct queue_properties {
 	uint32_t ctl_stack_size;
 	uint64_t tba_addr;
 	uint64_t tma_addr;
+	/* Relevant for CU */
+	uint32_t cu_mask_count; /* Must be a multiple of 32 */
+	uint32_t *cu_mask;
 };
 
 /**
@@ -872,6 +875,8 @@ int pqm_create_queue(struct process_queue_manager *pqm,
 int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid);
 int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid,
 			struct queue_properties *p);
+int pqm_set_cu_mask(struct process_queue_manager *pqm, unsigned int qid,
+			struct queue_properties *p);
 struct kernel_queue *pqm_get_kernel_queue(struct process_queue_manager *pqm,
 						unsigned int qid);
 
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
index eb4e5fb..c8cad9c 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
@@ -325,6 +325,8 @@ int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid)
 			if (retval != -ETIME)
 				goto err_destroy_queue;
 		}
+		kfree(pqn->q->properties.cu_mask);
+		pqn->q->properties.cu_mask = NULL;
 		uninit_queue(pqn->q);
 	}
 
@@ -365,6 +367,34 @@ int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid,
 	return 0;
 }
 
+int pqm_set_cu_mask(struct process_queue_manager *pqm, unsigned int qid,
+			struct queue_properties *p)
+{
+	int retval;
+	struct process_queue_node *pqn;
+
+	pqn = get_queue_by_qid(pqm, qid);
+	if (!pqn) {
+		pr_debug("No queue %d exists for update operation\n", qid);
+		return -EFAULT;
+	}
+
+	/* Free the old CU mask memory if it is already allocated, then
+	 * allocate memory for the new CU mask.
+	 */
+	kfree(pqn->q->properties.cu_mask);
+
+	pqn->q->properties.cu_mask_count = p->cu_mask_count;
+	pqn->q->properties.cu_mask = p->cu_mask;
+
+	retval = pqn->q->device->dqm->ops.update_queue(pqn->q->device->dqm,
+							pqn->q);
+	if (retval != 0)
+		return retval;
+
+	return 0;
+}
+
 struct kernel_queue *pqm_get_kernel_queue(
 					struct process_queue_manager *pqm,
 					unsigned int qid)
-- 
2.7.4

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

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] drm/amd: Add CU-masking ioctl definition to kfd_ioctl.h
       [not found] ` <1531609559-30402-1-git-send-email-Felix.Kuehling-5C7GfCeVMHo@public.gmane.org>
  2018-07-14 23:05   ` [PATCH 2/2] drm/amdkfd: Add CU-masking ioctl to KFD Felix Kuehling
@ 2018-07-28  9:19   ` Oded Gabbay
  1 sibling, 0 replies; 4+ messages in thread
From: Oded Gabbay @ 2018-07-28  9:19 UTC (permalink / raw)
  To: Kuehling, Felix; +Cc: amd-gfx list

On Sun, Jul 15, 2018 at 2:06 AM Felix Kuehling <Felix.Kuehling@amd.com> wrote:
>
> Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
> ---
>  include/uapi/linux/kfd_ioctl.h | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h
> index 88d17c3..01674b5 100644
> --- a/include/uapi/linux/kfd_ioctl.h
> +++ b/include/uapi/linux/kfd_ioctl.h
> @@ -76,6 +76,12 @@ struct kfd_ioctl_update_queue_args {
>         __u32 queue_priority;   /* to KFD */
>  };
>
> +struct kfd_ioctl_set_cu_mask_args {
> +       __u32 queue_id;         /* to KFD */
> +       __u32 num_cu_mask;              /* to KFD */
> +       __u64 cu_mask_ptr;              /* to KFD */
> +};
> +
>  /* For kfd_ioctl_set_memory_policy_args.default_policy and alternate_policy */
>  #define KFD_IOC_CACHE_POLICY_COHERENT 0
>  #define KFD_IOC_CACHE_POLICY_NONCOHERENT 1
> @@ -466,7 +472,10 @@ struct kfd_ioctl_unmap_memory_from_gpu_args {
>  #define AMDKFD_IOC_UNMAP_MEMORY_FROM_GPU       \
>                 AMDKFD_IOWR(0x19, struct kfd_ioctl_unmap_memory_from_gpu_args)
>
> +#define AMDKFD_IOC_SET_CU_MASK         \
> +               AMDKFD_IOW(0x1A, struct kfd_ioctl_set_cu_mask_args)
> +
>  #define AMDKFD_COMMAND_START           0x01
> -#define AMDKFD_COMMAND_END             0x1A
> +#define AMDKFD_COMMAND_END             0x1B
>
>  #endif
> --
> 2.7.4
>


This patch is:
Acked-by: Oded Gabbay <oded.gabbay@gmail.com>
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 2/2] drm/amdkfd: Add CU-masking ioctl to KFD
       [not found]     ` <1531609559-30402-2-git-send-email-Felix.Kuehling-5C7GfCeVMHo@public.gmane.org>
@ 2018-07-28  9:19       ` Oded Gabbay
  0 siblings, 0 replies; 4+ messages in thread
From: Oded Gabbay @ 2018-07-28  9:19 UTC (permalink / raw)
  To: Kuehling, Felix
  Cc: JinHuiEric.Huang-5C7GfCeVMHo, flora.cui-5C7GfCeVMHo,
	Kent Russell, amd-gfx list

On Sun, Jul 15, 2018 at 2:06 AM Felix Kuehling <Felix.Kuehling@amd.com> wrote:
>
> CU-masking allows a KFD client to control the set of CUs used by a
> user mode queue for executing compute dispatches. This can be used
> for optimizing the partitioning of the GPU and minimize conflicts
> between concurrent tasks.
>
> Signed-off-by: Flora Cui <flora.cui@amd.com>
> Signed-off-by: Kent Russell <kent.russell@amd.com>
> Signed-off-by: Eric Huang <JinHuiEric.Huang@amd.com>
> Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
> ---
>  drivers/gpu/drm/amd/amdkfd/kfd_chardev.c           | 58 ++++++++++++++++++++++
>  drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c      |  1 +
>  drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c       | 41 ++++++++++++++-
>  drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h       |  4 ++
>  drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c   | 27 ++++++++++
>  drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c    | 27 ++++++++++
>  drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c    | 27 ++++++++++
>  drivers/gpu/drm/amd/amdkfd/kfd_priv.h              |  5 ++
>  .../gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 30 +++++++++++
>  9 files changed, 219 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
> index 21d0989..063c941 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
> @@ -392,6 +392,61 @@ static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p,
>         return retval;
>  }
>
> +static int kfd_ioctl_set_cu_mask(struct file *filp, struct kfd_process *p,
> +                                       void *data)
> +{
> +       int retval;
> +       const int max_num_cus = 1024;
> +       struct kfd_ioctl_set_cu_mask_args *args = data;
> +       struct queue_properties properties;
> +       uint32_t __user *cu_mask_ptr = (uint32_t __user *)args->cu_mask_ptr;
> +       size_t cu_mask_size = sizeof(uint32_t) * (args->num_cu_mask / 32);
> +
> +       if ((args->num_cu_mask % 32) != 0) {
> +               pr_debug("num_cu_mask 0x%x must be a multiple of 32",
> +                               args->num_cu_mask);
> +               return -EINVAL;
> +       }
> +
> +       properties.cu_mask_count = args->num_cu_mask;
> +       if (properties.cu_mask_count == 0) {
> +               pr_debug("CU mask cannot be 0");
> +               return -EINVAL;
> +       }
> +
> +       /* To prevent an unreasonably large CU mask size, set an arbitrary
> +        * limit of max_num_cus bits.  We can then just drop any CU mask bits
> +        * past max_num_cus bits and just use the first max_num_cus bits.
> +        */
> +       if (properties.cu_mask_count > max_num_cus) {
> +               pr_debug("CU mask cannot be greater than 1024 bits");
> +               properties.cu_mask_count = max_num_cus;
> +               cu_mask_size = sizeof(uint32_t) * (max_num_cus/32);
> +       }
> +
> +       properties.cu_mask = kzalloc(cu_mask_size, GFP_KERNEL);
> +       if (!properties.cu_mask)
> +               return -ENOMEM;
> +
> +       retval = copy_from_user(properties.cu_mask, cu_mask_ptr, cu_mask_size);
> +       if (retval) {
> +               pr_debug("Could not copy CU mask from userspace");
> +               kfree(properties.cu_mask);
> +               return -EFAULT;
> +       }
> +
> +       mutex_lock(&p->mutex);
> +
> +       retval = pqm_set_cu_mask(&p->pqm, args->queue_id, &properties);
> +
> +       mutex_unlock(&p->mutex);
> +
> +       if (retval)
> +               kfree(properties.cu_mask);
> +
> +       return retval;
> +}
> +
>  static int kfd_ioctl_set_memory_policy(struct file *filep,
>                                         struct kfd_process *p, void *data)
>  {
> @@ -1561,6 +1616,9 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
>         AMDKFD_IOCTL_DEF(AMDKFD_IOC_UNMAP_MEMORY_FROM_GPU,
>                         kfd_ioctl_unmap_memory_from_gpu, 0),
>
> +       AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_CU_MASK,
> +                       kfd_ioctl_set_cu_mask, 0),
> +
>  };
>
>  #define AMDKFD_CORE_IOCTL_COUNT        ARRAY_SIZE(amdkfd_ioctls)
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
> index 2c8897e..9f84b4d 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
> @@ -123,6 +123,7 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
>         prop.write_ptr = (uint32_t *) kq->wptr_gpu_addr;
>         prop.eop_ring_buffer_address = kq->eop_gpu_addr;
>         prop.eop_ring_buffer_size = PAGE_SIZE;
> +       prop.cu_mask = NULL;
>
>         if (init_queue(&kq->queue, &prop) != 0)
>                 goto err_init_queue;
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
> index 4b8eb50..3bc25ab 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
> @@ -21,7 +21,7 @@
>   *
>   */
>
> -#include "kfd_priv.h"
> +#include "kfd_mqd_manager.h"
>
>  struct mqd_manager *mqd_manager_init(enum KFD_MQD_TYPE type,
>                                         struct kfd_dev *dev)
> @@ -48,3 +48,42 @@ struct mqd_manager *mqd_manager_init(enum KFD_MQD_TYPE type,
>
>         return NULL;
>  }
> +
> +void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm,
> +               const uint32_t *cu_mask, uint32_t cu_mask_count,
> +               uint32_t *se_mask)
> +{
> +       struct kfd_cu_info cu_info;
> +       uint32_t cu_per_sh[4] = {0};
> +       int i, se, cu = 0;
> +
> +       mm->dev->kfd2kgd->get_cu_info(mm->dev->kgd, &cu_info);
> +
> +       if (cu_mask_count > cu_info.cu_active_number)
> +               cu_mask_count = cu_info.cu_active_number;
> +
> +       for (se = 0; se < cu_info.num_shader_engines; se++)
> +               for (i = 0; i < 4; i++)
> +                       cu_per_sh[se] += hweight32(cu_info.cu_bitmap[se][i]);
> +
> +       /* Symmetrically map cu_mask to all SEs:
> +        * cu_mask[0] bit0 -> se_mask[0] bit0;
> +        * cu_mask[0] bit1 -> se_mask[1] bit0;
> +        * ... (if # SE is 4)
> +        * cu_mask[0] bit4 -> se_mask[0] bit1;
> +        * ...
> +        */
> +       se = 0;
> +       for (i = 0; i < cu_mask_count; i++) {
> +               if (cu_mask[i / 32] & (1 << (i % 32)))
> +                       se_mask[se] |= 1 << cu;
> +
> +               do {
> +                       se++;
> +                       if (se == cu_info.num_shader_engines) {
> +                               se = 0;
> +                               cu++;
> +                       }
> +               } while (cu >= cu_per_sh[se] && cu < 32);
> +       }
> +}
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
> index 8972bcf..4e84052 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
> @@ -93,4 +93,8 @@ struct mqd_manager {
>         struct kfd_dev  *dev;
>  };
>
> +void mqd_symmetrically_map_cu_mask(struct mqd_manager *mm,
> +               const uint32_t *cu_mask, uint32_t cu_mask_count,
> +               uint32_t *se_mask);
> +
>  #endif /* KFD_MQD_MANAGER_H_ */
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
> index 4872574..4724316 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
> @@ -41,6 +41,31 @@ static inline struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd)
>         return (struct cik_sdma_rlc_registers *)mqd;
>  }
>
> +static void update_cu_mask(struct mqd_manager *mm, void *mqd,
> +                       struct queue_properties *q)
> +{
> +       struct cik_mqd *m;
> +       uint32_t se_mask[4] = {0}; /* 4 is the max # of SEs */
> +
> +       if (q->cu_mask_count == 0)
> +               return;
> +
> +       mqd_symmetrically_map_cu_mask(mm,
> +               q->cu_mask, q->cu_mask_count, se_mask);
> +
> +       m = get_mqd(mqd);
> +       m->compute_static_thread_mgmt_se0 = se_mask[0];
> +       m->compute_static_thread_mgmt_se1 = se_mask[1];
> +       m->compute_static_thread_mgmt_se2 = se_mask[2];
> +       m->compute_static_thread_mgmt_se3 = se_mask[3];
> +
> +       pr_debug("Update cu mask to %#x %#x %#x %#x\n",
> +               m->compute_static_thread_mgmt_se0,
> +               m->compute_static_thread_mgmt_se1,
> +               m->compute_static_thread_mgmt_se2,
> +               m->compute_static_thread_mgmt_se3);
> +}
> +
>  static int init_mqd(struct mqd_manager *mm, void **mqd,
>                 struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
>                 struct queue_properties *q)
> @@ -196,6 +221,8 @@ static int __update_mqd(struct mqd_manager *mm, void *mqd,
>         if (q->format == KFD_QUEUE_FORMAT_AQL)
>                 m->cp_hqd_pq_control |= NO_UPDATE_RPTR;
>
> +       update_cu_mask(mm, mqd, q);
> +
>         q->is_active = (q->queue_size > 0 &&
>                         q->queue_address != 0 &&
>                         q->queue_percent > 0 &&
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
> index ad5c9f8..f5fc367 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
> @@ -41,6 +41,31 @@ static inline struct v9_sdma_mqd *get_sdma_mqd(void *mqd)
>         return (struct v9_sdma_mqd *)mqd;
>  }
>
> +static void update_cu_mask(struct mqd_manager *mm, void *mqd,
> +                       struct queue_properties *q)
> +{
> +       struct v9_mqd *m;
> +       uint32_t se_mask[4] = {0}; /* 4 is the max # of SEs */
> +
> +       if (q->cu_mask_count == 0)
> +               return;
> +
> +       mqd_symmetrically_map_cu_mask(mm,
> +               q->cu_mask, q->cu_mask_count, se_mask);
> +
> +       m = get_mqd(mqd);
> +       m->compute_static_thread_mgmt_se0 = se_mask[0];
> +       m->compute_static_thread_mgmt_se1 = se_mask[1];
> +       m->compute_static_thread_mgmt_se2 = se_mask[2];
> +       m->compute_static_thread_mgmt_se3 = se_mask[3];
> +
> +       pr_debug("update cu mask to %#x %#x %#x %#x\n",
> +               m->compute_static_thread_mgmt_se0,
> +               m->compute_static_thread_mgmt_se1,
> +               m->compute_static_thread_mgmt_se2,
> +               m->compute_static_thread_mgmt_se3);
> +}
> +
>  static int init_mqd(struct mqd_manager *mm, void **mqd,
>                         struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
>                         struct queue_properties *q)
> @@ -198,6 +223,8 @@ static int update_mqd(struct mqd_manager *mm, void *mqd,
>         if (mm->dev->cwsr_enabled && q->ctx_save_restore_area_address)
>                 m->cp_hqd_ctx_save_control = 0;
>
> +       update_cu_mask(mm, mqd, q);
> +
>         q->is_active = (q->queue_size > 0 &&
>                         q->queue_address != 0 &&
>                         q->queue_percent > 0 &&
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
> index 89e4242..b81fda3 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
> @@ -43,6 +43,31 @@ static inline struct vi_sdma_mqd *get_sdma_mqd(void *mqd)
>         return (struct vi_sdma_mqd *)mqd;
>  }
>
> +static void update_cu_mask(struct mqd_manager *mm, void *mqd,
> +                       struct queue_properties *q)
> +{
> +       struct vi_mqd *m;
> +       uint32_t se_mask[4] = {0}; /* 4 is the max # of SEs */
> +
> +       if (q->cu_mask_count == 0)
> +               return;
> +
> +       mqd_symmetrically_map_cu_mask(mm,
> +               q->cu_mask, q->cu_mask_count, se_mask);
> +
> +       m = get_mqd(mqd);
> +       m->compute_static_thread_mgmt_se0 = se_mask[0];
> +       m->compute_static_thread_mgmt_se1 = se_mask[1];
> +       m->compute_static_thread_mgmt_se2 = se_mask[2];
> +       m->compute_static_thread_mgmt_se3 = se_mask[3];
> +
> +       pr_debug("Update cu mask to %#x %#x %#x %#x\n",
> +               m->compute_static_thread_mgmt_se0,
> +               m->compute_static_thread_mgmt_se1,
> +               m->compute_static_thread_mgmt_se2,
> +               m->compute_static_thread_mgmt_se3);
> +}
> +
>  static int init_mqd(struct mqd_manager *mm, void **mqd,
>                         struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
>                         struct queue_properties *q)
> @@ -196,6 +221,8 @@ static int __update_mqd(struct mqd_manager *mm, void *mqd,
>                         atc_bit << CP_HQD_CTX_SAVE_CONTROL__ATC__SHIFT |
>                         mtype << CP_HQD_CTX_SAVE_CONTROL__MTYPE__SHIFT;
>
> +       update_cu_mask(mm, mqd, q);
> +
>         q->is_active = (q->queue_size > 0 &&
>                         q->queue_address != 0 &&
>                         q->queue_percent > 0 &&
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
> index ca83254..f971710 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
> @@ -422,6 +422,9 @@ struct queue_properties {
>         uint32_t ctl_stack_size;
>         uint64_t tba_addr;
>         uint64_t tma_addr;
> +       /* Relevant for CU */
> +       uint32_t cu_mask_count; /* Must be a multiple of 32 */
> +       uint32_t *cu_mask;
>  };
>
>  /**
> @@ -872,6 +875,8 @@ int pqm_create_queue(struct process_queue_manager *pqm,
>  int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid);
>  int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid,
>                         struct queue_properties *p);
> +int pqm_set_cu_mask(struct process_queue_manager *pqm, unsigned int qid,
> +                       struct queue_properties *p);
>  struct kernel_queue *pqm_get_kernel_queue(struct process_queue_manager *pqm,
>                                                 unsigned int qid);
>
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
> index eb4e5fb..c8cad9c 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
> @@ -325,6 +325,8 @@ int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid)
>                         if (retval != -ETIME)
>                                 goto err_destroy_queue;
>                 }
> +               kfree(pqn->q->properties.cu_mask);
> +               pqn->q->properties.cu_mask = NULL;
>                 uninit_queue(pqn->q);
>         }
>
> @@ -365,6 +367,34 @@ int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid,
>         return 0;
>  }
>
> +int pqm_set_cu_mask(struct process_queue_manager *pqm, unsigned int qid,
> +                       struct queue_properties *p)
> +{
> +       int retval;
> +       struct process_queue_node *pqn;
> +
> +       pqn = get_queue_by_qid(pqm, qid);
> +       if (!pqn) {
> +               pr_debug("No queue %d exists for update operation\n", qid);
> +               return -EFAULT;
> +       }
> +
> +       /* Free the old CU mask memory if it is already allocated, then
> +        * allocate memory for the new CU mask.
> +        */
> +       kfree(pqn->q->properties.cu_mask);
> +
> +       pqn->q->properties.cu_mask_count = p->cu_mask_count;
> +       pqn->q->properties.cu_mask = p->cu_mask;
> +
> +       retval = pqn->q->device->dqm->ops.update_queue(pqn->q->device->dqm,
> +                                                       pqn->q);
> +       if (retval != 0)
> +               return retval;
> +
> +       return 0;
> +}
> +
>  struct kernel_queue *pqm_get_kernel_queue(
>                                         struct process_queue_manager *pqm,
>                                         unsigned int qid)
> --
> 2.7.4
>


This patch is:
Acked-by: Oded Gabbay <oded.gabbay@gmail.com>
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-07-28  9:19 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-14 23:05 [PATCH 1/2] drm/amd: Add CU-masking ioctl definition to kfd_ioctl.h Felix Kuehling
     [not found] ` <1531609559-30402-1-git-send-email-Felix.Kuehling-5C7GfCeVMHo@public.gmane.org>
2018-07-14 23:05   ` [PATCH 2/2] drm/amdkfd: Add CU-masking ioctl to KFD Felix Kuehling
     [not found]     ` <1531609559-30402-2-git-send-email-Felix.Kuehling-5C7GfCeVMHo@public.gmane.org>
2018-07-28  9:19       ` Oded Gabbay
2018-07-28  9:19   ` [PATCH 1/2] drm/amd: Add CU-masking ioctl definition to kfd_ioctl.h Oded Gabbay

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.