return 0;
}
+/**
+ * amdgpu_mes_alloc_proc_ctx_index - allocate a process context slot
+ *
+ * @mes: MES instance
+ *
+ * Returns 0 on success, -ENOSPC if all slots are used (caller should
+ * fall back to system memory path).
+ */
+int amdgpu_mes_alloc_proc_ctx_index(struct amdgpu_mes *mes,
+ struct amdgpu_usermode_queue *queue)
+{
+ unsigned long bit;
+
+ if (!mes->use_rs64mem || !mes->proc_ctx_bitmap)
+ return -EOPNOTSUPP;
+
+ amdgpu_mes_lock(mes);
+ bit = find_first_zero_bit(mes->proc_ctx_bitmap,
+ mes->proc_ctx_array_size);
+ if (bit >= mes->proc_ctx_array_size) {
+ amdgpu_mes_unlock(mes);
+ return -ENOSPC;
+ }
+ set_bit(bit, mes->proc_ctx_bitmap);
+ queue->proc_ctx_array_index = (uint32_t)bit;
+ amdgpu_mes_unlock(mes);
+
+ return 0;
+}
+
+/**
+ * amdgpu_mes_free_proc_ctx_index - free a process context slot
+ */
+void amdgpu_mes_free_proc_ctx_index(struct amdgpu_mes *mes,
+ struct amdgpu_usermode_queue *queue)
+{
+ if (!mes->use_rs64mem || !mes->proc_ctx_bitmap)
+ return;
+ if (queue->proc_ctx_array_index >= mes->proc_ctx_array_size)
+ return;
+
+ amdgpu_mes_lock(mes);
+ clear_bit(queue->proc_ctx_array_index, mes->proc_ctx_bitmap);
+ amdgpu_mes_unlock(mes);
+}
+
#if defined(CONFIG_DEBUG_FS)
static int amdgpu_debugfs_mes_event_log_show(struct seq_file *m, void *unused)
uint32_t exclusively_scheduled;
uint32_t sh_mem_config_data;
uint32_t vm_cntx_cntl;
+ uint32_t process_context_array_index;
};
struct mes_remove_queue_input {
int amdgpu_mes_rs64mem_init(struct amdgpu_mes *mes);
void amdgpu_mes_rs64mem_fini(struct amdgpu_mes *mes);
int amdgpu_mes_rs64mem_setup_bitmaps(struct amdgpu_mes *mes);
+int amdgpu_mes_alloc_proc_ctx_index(struct amdgpu_mes *mes,
+ struct amdgpu_usermode_queue *queue);
+void amdgpu_mes_free_proc_ctx_index(struct amdgpu_mes *mes,
+ struct amdgpu_usermode_queue *queue);
#endif /* __AMDGPU_MES_H__ */
} va;
u64 va_array[6];
} userq_vas;
+
+ uint32_t proc_ctx_array_index;
};
struct amdgpu_userq_funcs {
struct amdgpu_userq_obj *ctx = &queue->fw_obj;
struct amdgpu_mqd_prop *userq_props = queue->userq_prop;
struct mes_add_queue_input queue_input;
+ struct amdgpu_mes *mes = &adev->mes;
int r;
memset(&queue_input, 0x0, sizeof(struct mes_add_queue_input));
queue_input.doorbell_offset = userq_props->doorbell_index;
queue_input.page_table_base_addr = amdgpu_gmc_pd_addr(queue->vm->root.bo);
queue_input.wptr_mc_addr = queue->wptr_obj.gpu_addr;
-
+ if (mes->use_rs64mem) {
+ amdgpu_mes_alloc_proc_ctx_index(mes, queue);
+ queue_input.process_context_array_index = queue->proc_ctx_array_index;
+ }
amdgpu_mes_lock(&adev->mes);
r = adev->mes.funcs->add_hw_queue(&adev->mes, &queue_input);
amdgpu_mes_unlock(&adev->mes);
struct amdgpu_device *adev = uq_mgr->adev;
struct mes_remove_queue_input queue_input;
struct amdgpu_userq_obj *ctx = &queue->fw_obj;
+ struct amdgpu_mes *mes = &adev->mes;
int r;
memset(&queue_input, 0x0, sizeof(struct mes_remove_queue_input));
amdgpu_mes_lock(&adev->mes);
r = adev->mes.funcs->remove_hw_queue(&adev->mes, &queue_input);
amdgpu_mes_unlock(&adev->mes);
+ if (mes->use_rs64mem)
+ amdgpu_mes_free_proc_ctx_index(mes, queue);
if (r)
DRM_ERROR("Failed to unmap queue in HW, err (%d)\n", r);
return r;
mes_add_queue_pkt.process_va_end = input->process_va_end;
mes_add_queue_pkt.process_quantum = input->process_quantum;
mes_add_queue_pkt.process_context_addr = input->process_context_addr;
+ mes_add_queue_pkt.process_context_array_index = input->process_context_array_index;
mes_add_queue_pkt.gang_quantum = input->gang_quantum;
mes_add_queue_pkt.gang_context_addr = input->gang_context_addr;
mes_add_queue_pkt.inprocess_gang_priority =