diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdkfd/kfd_priv.h')
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index f21fccebd75b..b6f838f56589 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -35,6 +35,9 @@ #define KFD_SYSFS_FILE_MODE 0444 +#define KFD_MMAP_DOORBELL_MASK 0x8000000000000 +#define KFD_MMAP_EVENTS_MASK 0x4000000000000 + /* * When working with cp scheduler we should assign the HIQ manually or via * the radeon driver to a fixed hqd slot, here are the fixed HIQ hqd slot @@ -71,6 +74,12 @@ extern int max_num_of_queues_per_device; /* Kernel module parameter to specify the scheduling policy */ extern int sched_policy; +/* + * Kernel module parameter to specify whether to send sigterm to HSA process on + * unhandled exception + */ +extern int send_sigterm; + /** * enum kfd_sched_policy * @@ -108,8 +117,16 @@ enum asic_family_type { CHIP_CARRIZO }; +struct kfd_event_interrupt_class { + bool (*interrupt_isr)(struct kfd_dev *dev, + const uint32_t *ih_ring_entry); + void (*interrupt_wq)(struct kfd_dev *dev, + const uint32_t *ih_ring_entry); +}; + struct kfd_device_info { unsigned int asic_family; + const struct kfd_event_interrupt_class *event_interrupt_class; unsigned int max_pasid_bits; size_t ih_ring_entry_size; uint8_t num_of_watch_points; @@ -161,10 +178,23 @@ struct kfd_dev { unsigned int gtt_sa_chunk_size; unsigned int gtt_sa_num_of_chunks; + /* Interrupts */ + void *interrupt_ring; + size_t interrupt_ring_size; + atomic_t interrupt_ring_rptr; + atomic_t interrupt_ring_wptr; + struct work_struct interrupt_work; + spinlock_t interrupt_lock; + /* QCM Device instance */ struct device_queue_manager *dqm; bool init_complete; + /* + * Interrupts of interest to KFD are copied + * from the HW ring into a SW ring. + */ + bool interrupts_active; }; /* KGD2KFD callbacks */ @@ -477,6 +507,15 @@ struct kfd_process { /*Is the user space process 32 bit?*/ bool is_32bit_user_mode; + + /* Event-related data */ + struct mutex event_mutex; + /* All events in process hashed by ID, linked on kfd_event.events. */ + DECLARE_HASHTABLE(events, 4); + struct list_head signal_event_pages; /* struct slot_page_header. + event_pages */ + u32 next_nonsignal_event_id; + size_t signal_event_count; }; /** @@ -501,6 +540,7 @@ void kfd_process_create_wq(void); void kfd_process_destroy_wq(void); struct kfd_process *kfd_create_process(const struct task_struct *); struct kfd_process *kfd_get_process(const struct task_struct *); +struct kfd_process *kfd_lookup_process_by_pasid(unsigned int pasid); struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev, struct kfd_process *p); @@ -555,7 +595,11 @@ struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev); struct kfd_dev *kfd_topology_enum_kfd_devices(uint8_t idx); /* Interrupts */ +int kfd_interrupt_init(struct kfd_dev *dev); +void kfd_interrupt_exit(struct kfd_dev *dev); void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry); +bool enqueue_ih_ring_entry(struct kfd_dev *kfd, const void *ih_ring_entry); +bool interrupt_is_wanted(struct kfd_dev *dev, const uint32_t *ih_ring_entry); /* Power Management */ void kgd2kfd_suspend(struct kfd_dev *kfd); @@ -642,4 +686,35 @@ uint64_t kfd_get_number_elems(struct kfd_dev *kfd); phys_addr_t kfd_get_process_doorbells(struct kfd_dev *dev, struct kfd_process *process); +/* Events */ +extern const struct kfd_event_interrupt_class event_interrupt_class_cik; +extern const struct kfd_device_global_init_class device_global_init_class_cik; + +enum kfd_event_wait_result { + KFD_WAIT_COMPLETE, + KFD_WAIT_TIMEOUT, + KFD_WAIT_ERROR +}; + +void kfd_event_init_process(struct kfd_process *p); +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, + enum kfd_event_wait_result *wait_result); +void kfd_signal_event_interrupt(unsigned int pasid, uint32_t partial_id, + uint32_t valid_id_bits); +void kfd_signal_iommu_event(struct kfd_dev *dev, + unsigned int pasid, unsigned long address, + bool is_write_requested, bool is_execute_requested); +void kfd_signal_hw_exception_event(unsigned int pasid); +int kfd_set_event(struct kfd_process *p, uint32_t event_id); +int kfd_reset_event(struct kfd_process *p, uint32_t event_id); +int kfd_event_create(struct file *devkfd, struct kfd_process *p, + uint32_t event_type, bool auto_reset, uint32_t node_id, + uint32_t *event_id, uint32_t *event_trigger_data, + uint64_t *event_page_offset, uint32_t *event_slot_index); +int kfd_event_destroy(struct kfd_process *p, uint32_t event_id); + #endif |