---
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 5 +
drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c | 113 +++++++++++++++++++----
drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 4 +-
drivers/gpu/drm/amd/amdkfd/kfd_process.c | 5 +-
4 files changed, 104 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index ab9e53dc8deb..2635218188cc 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -3303,6 +3303,11 @@ static int kfd_ioctl_create_process(struct file *filep,
struct kfd_process *p, v
}
filep->private_data = process;
+ ret = kfd_debugfs_add_process(process);
+ if (ret)
+ pr_warn("Failed to create debugfs entry for the kfd_process, ret =
%d\n",
+ ret);
+
mutex_unlock(&kfd_processes_mutex);
ret = kfd_create_process_sysfs(process);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c
b/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c
index 9bde2c64540f..02673f01b448 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c
@@ -33,6 +33,7 @@ static struct list_head procs;
struct debugfs_proc_entry {
struct list_head list;
struct dentry *proc_dentry;
+ struct kfd_process *process;
pid_t pid;
};
@@ -140,34 +141,97 @@ static const struct file_operations kfd_debugfs_pasid_fops = {
.read = kfd_debugfs_pasid_read,
};
-void kfd_debugfs_add_process(struct kfd_process *p)
+/* This helper locates the debugfs entry of a kfd process */
+static struct debugfs_proc_entry *kfd_debugfs_find_process_entry(struct
kfd_process *p)
{
+ struct debugfs_proc_entry *entry;
+
+ list_for_each_entry(entry, &procs, list) {
+ if (entry->process == p)
+ return entry;
+ }
+
+ return NULL;
+}
+
+/* This helper creates pasid file of a kfd process under debugfs */
+static void kfd_debugfs_create_pasid_files(struct kfd_process *p,
+ struct dentry *dir)
+{
+ char name[MAX_DEBUGFS_FILENAME_LEN];
+ struct kfd_process_device *pdd;
int i;
+
+ /* create pasid file for each GPU */
+ for (i = 0; i < p->n_pdds; i++) {
+ pdd = p->pdds[i];
+ snprintf(name, MAX_DEBUGFS_FILENAME_LEN, "pasid_%u",
pdd->dev->id);
+ debugfs_create_file((const char *)name, S_IFREG | 0444,
+ dir, pdd, &kfd_debugfs_pasid_fops);
+ }
+}
+
+int kfd_debugfs_add_process(struct kfd_process *p)
+{
+ struct debugfs_proc_entry *primary_entry;
char name[MAX_DEBUGFS_FILENAME_LEN];
+ struct kfd_process *primary_process;
struct debugfs_proc_entry *entry;
+ int ret;
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (!entry)
- return;
+ return -ENOMEM;
- list_add(&entry->list, &procs);
+ entry->process = p;
entry->pid = p->lead_thread->pid;
- snprintf(name, MAX_DEBUGFS_FILENAME_LEN, "%d",
- (int)entry->pid);
- entry->proc_dentry = debugfs_create_dir(name, debugfs_proc);
- /* Create debugfs files for each GPU:
- * - proc/<pid>/pasid_<gpuid>
- */
- for (i = 0; i < p->n_pdds; i++) {
- struct kfd_process_device *pdd = p->pdds[i];
+ if (p->context_id == KFD_CONTEXT_ID_PRIMARY) {
+ snprintf(name, MAX_DEBUGFS_FILENAME_LEN, "%d",
+ (int)entry->pid);
+ entry->proc_dentry = debugfs_create_dir(name, debugfs_proc);
+ } else {
+ primary_process = kfd_lookup_process_by_mm(p->lead_thread->mm);
+ if (!primary_process) {
+ ret = -ESRCH;
+ goto err_free_entry;
+ }
- snprintf(name, MAX_DEBUGFS_FILENAME_LEN, "pasid_%u",
- pdd->dev->id);
- debugfs_create_file((const char *)name, S_IFREG | 0444,
- entry->proc_dentry, pdd,
- &kfd_debugfs_pasid_fops);
+ primary_entry = kfd_debugfs_find_process_entry(primary_process);
+ kfd_unref_process(primary_process);
+ if (!primary_entry) {
+ pr_warn("Failed to find the primary debugfs entry for pid
%d\n",
+ entry->pid);
+ ret = -ENOENT;
+ goto err_free_entry;
+ }
+
+ snprintf(name, MAX_DEBUGFS_FILENAME_LEN, "context_%u",
+ p->context_id);
+ entry->proc_dentry = debugfs_create_dir(name,
+
primary_entry->proc_dentry);
}
+ if (IS_ERR_OR_NULL(entry->proc_dentry)) {
+ ret = entry->proc_dentry ? PTR_ERR(entry->proc_dentry) :
-ENOMEM;
+ goto err_free_entry;
+ }
+
+ list_add(&entry->list, &procs);
+ kfd_debugfs_create_pasid_files(p, entry->proc_dentry);
+
+ return 0;
+
+err_free_entry:
+ kfree(entry);
+ return ret;
+}
+
+/* This helper removes a debugfs entry and its sub-entries */
+static void kfd_debugfs_remove_entry(struct debugfs_proc_entry *entry)
+{
+ debugfs_remove(entry->proc_dentry);
+ list_del(&entry->list);
+ kfree(entry);
}
void kfd_debugfs_remove_process(struct kfd_process *p)
@@ -175,13 +239,22 @@ void kfd_debugfs_remove_process(struct kfd_process *p)
struct debugfs_proc_entry *entry, *next;
mutex_lock(&kfd_processes_mutex);
+ if (p->context_id == KFD_CONTEXT_ID_PRIMARY) {
+ /* remove entries of secondary contexts */
+ list_for_each_entry_safe(entry, next, &procs, list) {
+ if (entry->pid != p->lead_thread->pid || entry->process
== p)
+ continue;
+
+ kfd_debugfs_remove_entry(entry);
+ }
+ }
+
list_for_each_entry_safe(entry, next, &procs, list) {
- if (entry->pid != p->lead_thread->pid)
+ if (entry->process != p)
continue;
- debugfs_remove_recursive(entry->proc_dentry);
- list_del(&entry->list);
- kfree(entry);
+ kfd_debugfs_remove_entry(entry);
}
+
mutex_unlock(&kfd_processes_mutex);
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index ad4897f094a2..365c6289b05d 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -1649,14 +1649,14 @@ int kfd_debugfs_hang_hws(struct kfd_node *dev);
int pm_debugfs_hang_hws(struct packet_manager *pm);
int dqm_debugfs_hang_hws(struct device_queue_manager *dqm);
-void kfd_debugfs_add_process(struct kfd_process *p);
+int kfd_debugfs_add_process(struct kfd_process *p);
void kfd_debugfs_remove_process(struct kfd_process *p);
#else
static inline void kfd_debugfs_init(void) {}
static inline void kfd_debugfs_fini(void) {}
-static inline void kfd_debugfs_add_process(struct kfd_process *p) {}
+static inline int kfd_debugfs_add_process(struct kfd_process *p) { return 0; }
static inline void kfd_debugfs_remove_process(struct kfd_process *p) {}
#endif
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
index 8e701dcda8ec..a87878aee0f1 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -1002,7 +1002,10 @@ struct kfd_process *kfd_create_process(struct
task_struct *thread)
if (ret)
pr_warn("Failed to create sysfs entry for the
kfd_process");
- kfd_debugfs_add_process(process);
+ ret = kfd_debugfs_add_process(process);
+ if (ret)
+ pr_warn("Failed to create debugfs entry for the kfd_process,
ret = %d\n",
+ ret);
init_waitqueue_head(&process->wait_irq_drain);
}