diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdkfd')
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_device.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_events.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_svm.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 11 |
7 files changed, 34 insertions, 30 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 2b3d8bc8f0aa..dc774ddf3445 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -874,7 +874,7 @@ static int kfd_ioctl_wait_events(struct file *filp, struct kfd_process *p, err = kfd_wait_on_events(p, args->num_events, (void __user *)args->events_ptr, (args->wait_for_all != 0), - args->timeout, &args->wait_result); + &args->timeout, &args->wait_result); return err; } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index f5853835f03a..357298e69495 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -102,13 +102,18 @@ static void kfd_device_info_set_sdma_info(struct kfd_dev *kfd) switch (sdma_version) { case IP_VERSION(6, 0, 0): - case IP_VERSION(6, 0, 1): case IP_VERSION(6, 0, 2): /* Reserve 1 for paging and 1 for gfx */ kfd->device_info.num_reserved_sdma_queues_per_engine = 2; /* BIT(0)=engine-0 queue-0; BIT(1)=engine-1 queue-0; BIT(2)=engine-0 queue-1; ... */ kfd->device_info.reserved_sdma_queues_bitmap = 0xFULL; break; + case IP_VERSION(6, 0, 1): + /* Reserve 1 for paging and 1 for gfx */ + kfd->device_info.num_reserved_sdma_queues_per_engine = 2; + /* BIT(0)=engine-0 queue-0; BIT(1)=engine-0 queue-1; ... */ + kfd->device_info.reserved_sdma_queues_bitmap = 0x3ULL; + break; default: break; } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index 3942a56c28bb..83e3ce9f6049 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -894,7 +894,8 @@ static long user_timeout_to_jiffies(uint32_t user_timeout_ms) return msecs_to_jiffies(user_timeout_ms) + 1; } -static void free_waiters(uint32_t num_events, struct kfd_event_waiter *waiters) +static void free_waiters(uint32_t num_events, struct kfd_event_waiter *waiters, + bool undo_auto_reset) { uint32_t i; @@ -903,6 +904,9 @@ static void free_waiters(uint32_t num_events, struct kfd_event_waiter *waiters) spin_lock(&waiters[i].event->lock); remove_wait_queue(&waiters[i].event->wq, &waiters[i].wait); + if (undo_auto_reset && waiters[i].activated && + waiters[i].event && waiters[i].event->auto_reset) + set_event(waiters[i].event); spin_unlock(&waiters[i].event->lock); } @@ -911,7 +915,7 @@ static void free_waiters(uint32_t num_events, struct kfd_event_waiter *waiters) int kfd_wait_on_events(struct kfd_process *p, uint32_t num_events, void __user *data, - bool all, uint32_t user_timeout_ms, + bool all, uint32_t *user_timeout_ms, uint32_t *wait_result) { struct kfd_event_data __user *events = @@ -920,7 +924,7 @@ int kfd_wait_on_events(struct kfd_process *p, int ret = 0; struct kfd_event_waiter *event_waiters = NULL; - long timeout = user_timeout_to_jiffies(user_timeout_ms); + long timeout = user_timeout_to_jiffies(*user_timeout_ms); event_waiters = alloc_event_waiters(num_events); if (!event_waiters) { @@ -970,15 +974,11 @@ int kfd_wait_on_events(struct kfd_process *p, } if (signal_pending(current)) { - /* - * This is wrong when a nonzero, non-infinite timeout - * is specified. We need to use - * ERESTARTSYS_RESTARTBLOCK, but struct restart_block - * contains a union with data for each user and it's - * in generic kernel code that I don't want to - * touch yet. - */ ret = -ERESTARTSYS; + if (*user_timeout_ms != KFD_EVENT_TIMEOUT_IMMEDIATE && + *user_timeout_ms != KFD_EVENT_TIMEOUT_INFINITE) + *user_timeout_ms = jiffies_to_msecs( + max(0l, timeout-1)); break; } @@ -1019,7 +1019,7 @@ int kfd_wait_on_events(struct kfd_process *p, event_waiters, events); out_unlock: - free_waiters(num_events, event_waiters); + free_waiters(num_events, event_waiters, ret == -ERESTARTSYS); mutex_unlock(&p->event_mutex); out: if (ret) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index d03a3b9c9c5d..bf610e3b683b 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -1317,7 +1317,7 @@ void kfd_event_free_process(struct kfd_process *p); int kfd_event_mmap(struct kfd_process *process, struct vm_area_struct *vma); int kfd_wait_on_events(struct kfd_process *p, uint32_t num_events, void __user *data, - bool all, uint32_t user_timeout_ms, + bool all, uint32_t *user_timeout_ms, uint32_t *wait_result); void kfd_signal_event_interrupt(u32 pasid, uint32_t partial_id, uint32_t valid_id_bits); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c index a67ba8879a56..11074cc8c333 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c @@ -541,7 +541,6 @@ svm_range_vram_node_new(struct amdgpu_device *adev, struct svm_range *prange, kfree(svm_bo); return -ESRCH; } - svm_bo->svms = prange->svms; svm_bo->eviction_fence = amdgpu_amdkfd_fence_create(dma_fence_context_alloc(1), mm, @@ -3273,7 +3272,6 @@ int svm_range_schedule_evict_svm_bo(struct amdgpu_amdkfd_fence *fence) static void svm_range_evict_svm_bo_worker(struct work_struct *work) { struct svm_range_bo *svm_bo; - struct kfd_process *p; struct mm_struct *mm; int r = 0; @@ -3281,13 +3279,12 @@ static void svm_range_evict_svm_bo_worker(struct work_struct *work) if (!svm_bo_ref_unless_zero(svm_bo)) return; /* svm_bo was freed while eviction was pending */ - /* svm_range_bo_release destroys this worker thread. So during - * the lifetime of this thread, kfd_process and mm will be valid. - */ - p = container_of(svm_bo->svms, struct kfd_process, svms); - mm = p->mm; - if (!mm) + if (mmget_not_zero(svm_bo->eviction_fence->mm)) { + mm = svm_bo->eviction_fence->mm; + } else { + svm_range_bo_unref(svm_bo); return; + } mmap_read_lock(mm); spin_lock(&svm_bo->list_lock); @@ -3305,8 +3302,7 @@ static void svm_range_evict_svm_bo_worker(struct work_struct *work) mutex_lock(&prange->migrate_mutex); do { - r = svm_migrate_vram_to_ram(prange, - svm_bo->eviction_fence->mm, + r = svm_migrate_vram_to_ram(prange, mm, KFD_MIGRATE_TRIGGER_TTM_EVICTION); } while (!r && prange->actual_loc && --retries); @@ -3324,6 +3320,7 @@ static void svm_range_evict_svm_bo_worker(struct work_struct *work) } spin_unlock(&svm_bo->list_lock); mmap_read_unlock(mm); + mmput(mm); dma_fence_signal(&svm_bo->eviction_fence->base); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h index 9156b041ef17..cfac13ad06ef 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h @@ -46,7 +46,6 @@ struct svm_range_bo { spinlock_t list_lock; struct amdgpu_amdkfd_fence *eviction_fence; struct work_struct eviction_work; - struct svm_range_list *svms; uint32_t evicting; struct work_struct release_work; }; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 25990bec600d..3f0a4a415907 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -1392,8 +1392,8 @@ static int kfd_build_p2p_node_entry(struct kfd_topology_device *dev, static int kfd_create_indirect_link_prop(struct kfd_topology_device *kdev, int gpu_node) { + struct kfd_iolink_properties *gpu_link, *tmp_link, *cpu_link; struct kfd_iolink_properties *props = NULL, *props2 = NULL; - struct kfd_iolink_properties *gpu_link, *cpu_link; struct kfd_topology_device *cpu_dev; int ret = 0; int i, num_cpu; @@ -1416,16 +1416,19 @@ static int kfd_create_indirect_link_prop(struct kfd_topology_device *kdev, int g continue; /* find CPU <--> CPU links */ + cpu_link = NULL; cpu_dev = kfd_topology_device_by_proximity_domain(i); if (cpu_dev) { - list_for_each_entry(cpu_link, + list_for_each_entry(tmp_link, &cpu_dev->io_link_props, list) { - if (cpu_link->node_to == gpu_link->node_to) + if (tmp_link->node_to == gpu_link->node_to) { + cpu_link = tmp_link; break; + } } } - if (cpu_link->node_to != gpu_link->node_to) + if (!cpu_link) return -ENOMEM; /* CPU <--> CPU <--> GPU, GPU node*/ |