Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

amdkfd: destroy kfd secondary contexts through fd close

Life cycle of a KFD secondary context(kfd_process) is tied
to the opened file. Therefore this commit destroy a kfd
secondary context when close the fd it belonging to.

This commit extracts the code removing the kfd_process
from the kfd_process_table to a separate function and
call it in kfd_process_notifier_release_internal unconditionally.

Signed-off-by: Zhu Lingshan <lingshan.zhu@amd.com>
Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Zhu Lingshan and committed by
Alex Deucher
65cce2a1 4cd255b9

+31 -20
+7 -2
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
··· 164 164 { 165 165 struct kfd_process *process = filep->private_data; 166 166 167 - if (process) 168 - kfd_unref_process(process); 167 + if (!process) 168 + return 0; 169 + 170 + if (process->context_id != KFD_CONTEXT_ID_PRIMARY) 171 + kfd_process_notifier_release_internal(process); 172 + 173 + kfd_unref_process(process); 169 174 170 175 return 0; 171 176 }
+1
drivers/gpu/drm/amd/amdkfd/kfd_priv.h
··· 1095 1095 1096 1096 int kfd_reserved_mem_mmap(struct kfd_node *dev, struct kfd_process *process, 1097 1097 struct vm_area_struct *vma); 1098 + void kfd_process_notifier_release_internal(struct kfd_process *p); 1098 1099 1099 1100 /* KFD process API for creating and translating handles */ 1100 1101 int kfd_process_device_create_obj_handle(struct kfd_process_device *pdd,
+23 -18
drivers/gpu/drm/amd/amdkfd/kfd_process.c
··· 1231 1231 kfd_unref_process(container_of(mn, struct kfd_process, mmu_notifier)); 1232 1232 } 1233 1233 1234 - static void kfd_process_notifier_release_internal(struct kfd_process *p) 1234 + static void kfd_process_table_remove(struct kfd_process *p) 1235 + { 1236 + mutex_lock(&kfd_processes_mutex); 1237 + /* 1238 + * Do early return if table is empty. 1239 + * 1240 + * This could potentially happen if this function is called concurrently 1241 + * by mmu_notifier and by kfd_cleanup_pocesses. 1242 + * 1243 + */ 1244 + if (hash_empty(kfd_processes_table)) { 1245 + mutex_unlock(&kfd_processes_mutex); 1246 + return; 1247 + } 1248 + hash_del_rcu(&p->kfd_processes); 1249 + mutex_unlock(&kfd_processes_mutex); 1250 + synchronize_srcu(&kfd_processes_srcu); 1251 + } 1252 + 1253 + void kfd_process_notifier_release_internal(struct kfd_process *p) 1235 1254 { 1236 1255 int i; 1237 1256 1257 + kfd_process_table_remove(p); 1238 1258 cancel_delayed_work_sync(&p->eviction_work); 1239 1259 cancel_delayed_work_sync(&p->restore_work); 1240 1260 ··· 1296 1276 srcu_read_unlock(&kfd_processes_srcu, idx); 1297 1277 } 1298 1278 1299 - mmu_notifier_put(&p->mmu_notifier); 1279 + if (p->context_id == KFD_CONTEXT_ID_PRIMARY) 1280 + mmu_notifier_put(&p->mmu_notifier); 1300 1281 } 1301 1282 1302 1283 static void kfd_process_notifier_release(struct mmu_notifier *mn, ··· 1312 1291 p = container_of(mn, struct kfd_process, mmu_notifier); 1313 1292 if (WARN_ON(p->mm != mm)) 1314 1293 return; 1315 - 1316 - mutex_lock(&kfd_processes_mutex); 1317 - /* 1318 - * Do early return if table is empty. 1319 - * 1320 - * This could potentially happen if this function is called concurrently 1321 - * by mmu_notifier and by kfd_cleanup_pocesses. 1322 - * 1323 - */ 1324 - if (hash_empty(kfd_processes_table)) { 1325 - mutex_unlock(&kfd_processes_mutex); 1326 - return; 1327 - } 1328 - hash_del_rcu(&p->kfd_processes); 1329 - mutex_unlock(&kfd_processes_mutex); 1330 - synchronize_srcu(&kfd_processes_srcu); 1331 1294 1332 1295 kfd_process_notifier_release_internal(p); 1333 1296 }