Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f3a39818 authored by Andrew Lewycky's avatar Andrew Lewycky Committed by Oded Gabbay
Browse files

drm/amdkfd: Add the events module



This patch adds the events module (kfd_events.c) and the interrupt
handle module for Kaveri (cik_event_interrupt.c).

The patch updates the interrupt_is_wanted(), so that it now calls the
interrupt isr function specific for the device that received the
interrupt. That function(implemented in cik_event_interrupt.c)
returns whether this interrupt is of interest to us or not.

The patch also updates the interrupt_wq(), so that it now calls the
device's specific wq function, which checks the interrupt source
and tries to signal relevant events.

v2:

Increase limit of signal events to 4096 per process
Remove bitfields from struct cik_ih_ring_entry
Rename radeon_kfd_event_mmap to kfd_event_mmap
Add debug prints to allocate_free_slot and allocate_signal_page
Make allocate_event_notification_slot return a correct value
Add warning prints to create_signal_event
Remove error print from IOCTL path
Reformatted debug prints in kfd_event_mmap
Map correct size (as received from mmap) in kfd_event_mmap

v3:

Reduce limit of signal events back to 256 per process
Fix allocation of kernel memory for signal events

Signed-off-by: default avatarAndrew Lewycky <Andrew.Lewycky@amd.com>
Signed-off-by: default avatarOded Gabbay <oded.gabbay@gmail.com>
parent 29a5d3eb
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -12,6 +12,6 @@ amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \
		kfd_kernel_queue_vi.o kfd_packet_manager.o \
		kfd_kernel_queue_vi.o kfd_packet_manager.o \
		kfd_process_queue_manager.o kfd_device_queue_manager.o \
		kfd_process_queue_manager.o kfd_device_queue_manager.o \
		kfd_device_queue_manager_cik.o kfd_device_queue_manager_vi.o \
		kfd_device_queue_manager_cik.o kfd_device_queue_manager_vi.o \
		kfd_interrupt.o
		kfd_interrupt.o kfd_events.o cik_event_interrupt.o


obj-$(CONFIG_HSA_AMD)	+= amdkfd.o
obj-$(CONFIG_HSA_AMD)	+= amdkfd.o
+63 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright 2014 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include "kfd_priv.h"
#include "kfd_events.h"
#include "cik_int.h"

static bool cik_event_interrupt_isr(struct kfd_dev *dev,
					const uint32_t *ih_ring_entry)
{
	unsigned int pasid;
	const struct cik_ih_ring_entry *ihre =
			(const struct cik_ih_ring_entry *)ih_ring_entry;

	pasid = (ihre->ring_id & 0xffff0000) >> 16;

	/* Do not process in ISR, just request it to be forwarded to WQ. */
	return (pasid != 0) &&
		(ihre->source_id == CIK_INTSRC_CP_END_OF_PIPE ||
		ihre->source_id == CIK_INTSRC_SQ_INTERRUPT_MSG);
}

static void cik_event_interrupt_wq(struct kfd_dev *dev,
					const uint32_t *ih_ring_entry)
{
	unsigned int pasid;
	const struct cik_ih_ring_entry *ihre =
			(const struct cik_ih_ring_entry *)ih_ring_entry;

	pasid = (ihre->ring_id & 0xffff0000) >> 16;

	if (pasid == 0)
		return;

	if (ihre->source_id == CIK_INTSRC_CP_END_OF_PIPE)
		kfd_signal_event_interrupt(pasid, 0, 0);
	else if (ihre->source_id == CIK_INTSRC_SQ_INTERRUPT_MSG)
		kfd_signal_event_interrupt(pasid, ihre->data & 0xFF, 8);
}

const struct kfd_event_interrupt_class event_interrupt_class_cik = {
	.interrupt_isr = cik_event_interrupt_isr,
	.interrupt_wq = cik_event_interrupt_wq,
};
+40 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright 2014 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef HSA_RADEON_CIK_INT_H_INCLUDED
#define HSA_RADEON_CIK_INT_H_INCLUDED

#include <linux/types.h>

struct cik_ih_ring_entry {
	uint32_t source_id;
	uint32_t data;
	uint32_t ring_id;
	uint32_t reserved;
};

#define CIK_INTSRC_DEQUEUE_COMPLETE	0xC6
#define CIK_INTSRC_CP_END_OF_PIPE	0xB5
#define CIK_INTSRC_SQ_INTERRUPT_MSG	0xEF

#endif
+14 −2
Original line number Original line Diff line number Diff line
@@ -289,8 +289,10 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,


	args->queue_id = queue_id;
	args->queue_id = queue_id;



	/* Return gpu_id as doorbell offset for mmap usage */
	/* Return gpu_id as doorbell offset for mmap usage */
	args->doorbell_offset = args->gpu_id << PAGE_SHIFT;
	args->doorbell_offset = (KFD_MMAP_DOORBELL_MASK | args->gpu_id);
	args->doorbell_offset <<= PAGE_SHIFT;


	mutex_unlock(&p->mutex);
	mutex_unlock(&p->mutex);


@@ -684,5 +686,15 @@ static int kfd_mmap(struct file *filp, struct vm_area_struct *vma)
	if (IS_ERR(process))
	if (IS_ERR(process))
		return PTR_ERR(process);
		return PTR_ERR(process);


	if ((vma->vm_pgoff & KFD_MMAP_DOORBELL_MASK) ==
			KFD_MMAP_DOORBELL_MASK) {
		vma->vm_pgoff = vma->vm_pgoff ^ KFD_MMAP_DOORBELL_MASK;
		return kfd_doorbell_mmap(process, vma);
		return kfd_doorbell_mmap(process, vma);
	} else if ((vma->vm_pgoff & KFD_MMAP_EVENTS_MASK) ==
			KFD_MMAP_EVENTS_MASK) {
		vma->vm_pgoff = vma->vm_pgoff ^ KFD_MMAP_EVENTS_MASK;
		return kfd_event_mmap(process, vma);
	}

	return -EFAULT;
}
}
+1 −0
Original line number Original line Diff line number Diff line
@@ -34,6 +34,7 @@ static const struct kfd_device_info kaveri_device_info = {
	.asic_family = CHIP_KAVERI,
	.asic_family = CHIP_KAVERI,
	.max_pasid_bits = 16,
	.max_pasid_bits = 16,
	.ih_ring_entry_size = 4 * sizeof(uint32_t),
	.ih_ring_entry_size = 4 * sizeof(uint32_t),
	.event_interrupt_class = &event_interrupt_class_cik,
	.mqd_size_aligned = MQD_SIZE_ALIGNED
	.mqd_size_aligned = MQD_SIZE_ALIGNED
};
};


Loading