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

Commit 91d9f985 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-amdkfd-next-2015-05-19' of git://people.freedesktop.org/~gabbayo/linux into drm-next

- Add the interrupts & events modules, including new IOCTLs to create and wait
  on events. The HSA RT open source stack is mainly using events to know when
  a dispatched work has been completed. In addition, this module is
  a pre-requisite for the next module I'm going to upstream - debugger support

  This module also handles H/W exceptions, such as memory exception received
  through the IOMMUv2 H/W and Bad Opcode exception receieved from the GPU.

- Adding a new kernel module parameter to let the user decide whether he wants
  to receive a SIGTERM when a memory exception occurs inside the GPU kernel and
  the HSA application doesn't wait on an appropriate event, or if he just want
  to receive notification about this event in dmesg. The default is the latter.

- Additional improvements for SDMA code

- Update my email address in Maintainers file.

* tag 'drm-amdkfd-next-2015-05-19' of git://people.freedesktop.org/~gabbayo/linux:
  drm/amdkfd: change driver version to 0.7.2
  drm/amdkfd: Implement events IOCTLs
  drm/amdkfd: Add module parameter of send_sigterm
  drm/amdkfd: Add bad opcode exception handling
  drm/amdkfd: Add memory exception handling
  drm/amdkfd: Add the events module
  drm/amdkfd: add events IOCTL set definitions
  drm/amdkfd: Add interrupt handling module
  drm/radeon: Add init interrupt kfd->kgd interface
  MAINTAINERS: update amdkfd Oded's email address
  drm/amdkfd: make the sdma vm init to be asic specific
  drm/amdkfd: Use new struct for asic specific ops
  drm/amdkfd: reformat some debug prints
  drm/amdkfd: Remove unessary void pointer cast
parents 9c37bf2d 7591cd2c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -631,7 +631,7 @@ F: drivers/iommu/amd_iommu*.[ch]
F:	include/linux/amd-iommu.h

AMD KFD
M:	Oded Gabbay <oded.gabbay@amd.com>
M:	Oded Gabbay <oded.gabbay@gmail.com>
L:	dri-devel@lists.freedesktop.org
T:	git git://people.freedesktop.org/~gabbayo/linux.git
S:	Supported
+1 −0
Original line number Diff line number Diff line
@@ -12,5 +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_process_queue_manager.o kfd_device_queue_manager.o \
		kfd_device_queue_manager_cik.o kfd_device_queue_manager_vi.o \
		kfd_interrupt.o kfd_events.o cik_event_interrupt.o

obj-$(CONFIG_HSA_AMD)	+= amdkfd.o
+66 −0
Original line number 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 ||
		ihre->source_id == CIK_INTSRC_CP_BAD_OPCODE);
}

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);
	else if (ihre->source_id == CIK_INTSRC_CP_BAD_OPCODE)
		kfd_signal_hw_exception_event(pasid);
}

const struct kfd_event_interrupt_class event_interrupt_class_cik = {
	.interrupt_isr = cik_event_interrupt_isr,
	.interrupt_wq = cik_event_interrupt_wq,
};
+41 −0
Original line number 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_CP_BAD_OPCODE	0xB7
#define CIK_INTSRC_SQ_INTERRUPT_MSG	0xEF

#endif
+85 −2
Original line number 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;


	/* 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);

@@ -514,6 +516,62 @@ static int kfd_ioctl_get_process_apertures(struct file *filp,
	return 0;
}

static int kfd_ioctl_create_event(struct file *filp, struct kfd_process *p,
					void *data)
{
	struct kfd_ioctl_create_event_args *args = data;
	int err;

	err = kfd_event_create(filp, p, args->event_type,
				args->auto_reset != 0, args->node_id,
				&args->event_id, &args->event_trigger_data,
				&args->event_page_offset,
				&args->event_slot_index);

	return err;
}

static int kfd_ioctl_destroy_event(struct file *filp, struct kfd_process *p,
					void *data)
{
	struct kfd_ioctl_destroy_event_args *args = data;

	return kfd_event_destroy(p, args->event_id);
}

static int kfd_ioctl_set_event(struct file *filp, struct kfd_process *p,
				void *data)
{
	struct kfd_ioctl_set_event_args *args = data;

	return kfd_set_event(p, args->event_id);
}

static int kfd_ioctl_reset_event(struct file *filp, struct kfd_process *p,
				void *data)
{
	struct kfd_ioctl_reset_event_args *args = data;

	return kfd_reset_event(p, args->event_id);
}

static int kfd_ioctl_wait_events(struct file *filp, struct kfd_process *p,
				void *data)
{
	struct kfd_ioctl_wait_events_args *args = data;
	enum kfd_event_wait_result wait_result;
	int err;

	err = kfd_wait_on_events(p, args->num_events,
			(void __user *)args->events_ptr,
			(args->wait_for_all != 0),
			args->timeout, &wait_result);

	args->wait_result = wait_result;

	return err;
}

#define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \
	[_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl}

@@ -539,6 +597,21 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {

	AMDKFD_IOCTL_DEF(AMDKFD_IOC_UPDATE_QUEUE,
			kfd_ioctl_update_queue, 0),

	AMDKFD_IOCTL_DEF(AMDKFD_IOC_CREATE_EVENT,
			kfd_ioctl_create_event, 0),

	AMDKFD_IOCTL_DEF(AMDKFD_IOC_DESTROY_EVENT,
			kfd_ioctl_destroy_event, 0),

	AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_EVENT,
			kfd_ioctl_set_event, 0),

	AMDKFD_IOCTL_DEF(AMDKFD_IOC_RESET_EVENT,
			kfd_ioctl_reset_event, 0),

	AMDKFD_IOCTL_DEF(AMDKFD_IOC_WAIT_EVENTS,
			kfd_ioctl_wait_events, 0),
};

#define AMDKFD_CORE_IOCTL_COUNT	ARRAY_SIZE(amdkfd_ioctls)
@@ -639,5 +712,15 @@ static int kfd_mmap(struct file *filp, struct vm_area_struct *vma)
	if (IS_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);
	} 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;
}
Loading