mirror of https://gitee.com/openkylin/linux.git
Merge tag 'drm-amdkfd-fixes-2017-09-24' of git://people.freedesktop.org/~gabbayo/linux into drm-fixes
It contains the following fixes: - correct checking of return value - send correct parameter to function (According to the parameter type) - avoid spamming of dmesg log - fix queue wrapping calculations * tag 'drm-amdkfd-fixes-2017-09-24' of git://people.freedesktop.org/~gabbayo/linux: drm/amdkfd: Print event limit messages only once per process drm/amdkfd: Fix kernel-queue wrapping bugs drm/amdkfd: Fix incorrect destroy_mqd parameter drm/amdkfd: check for null dev to avoid a null pointer dereference
This commit is contained in:
commit
f2e295342e
|
@ -892,6 +892,8 @@ static int kfd_ioctl_get_tile_config(struct file *filep,
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
dev = kfd_device_by_id(args->gpu_id);
|
dev = kfd_device_by_id(args->gpu_id);
|
||||||
|
if (!dev)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
dev->kfd2kgd->get_tile_config(dev->kgd, &config);
|
dev->kfd2kgd->get_tile_config(dev->kgd, &config);
|
||||||
|
|
||||||
|
|
|
@ -292,7 +292,10 @@ static int create_signal_event(struct file *devkfd,
|
||||||
struct kfd_event *ev)
|
struct kfd_event *ev)
|
||||||
{
|
{
|
||||||
if (p->signal_event_count == KFD_SIGNAL_EVENT_LIMIT) {
|
if (p->signal_event_count == KFD_SIGNAL_EVENT_LIMIT) {
|
||||||
pr_warn("Signal event wasn't created because limit was reached\n");
|
if (!p->signal_event_limit_reached) {
|
||||||
|
pr_warn("Signal event wasn't created because limit was reached\n");
|
||||||
|
p->signal_event_limit_reached = true;
|
||||||
|
}
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -184,7 +184,7 @@ static void uninitialize(struct kernel_queue *kq)
|
||||||
if (kq->queue->properties.type == KFD_QUEUE_TYPE_HIQ)
|
if (kq->queue->properties.type == KFD_QUEUE_TYPE_HIQ)
|
||||||
kq->mqd->destroy_mqd(kq->mqd,
|
kq->mqd->destroy_mqd(kq->mqd,
|
||||||
kq->queue->mqd,
|
kq->queue->mqd,
|
||||||
false,
|
KFD_PREEMPT_TYPE_WAVEFRONT_RESET,
|
||||||
QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS,
|
QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS,
|
||||||
kq->queue->pipe,
|
kq->queue->pipe,
|
||||||
kq->queue->queue);
|
kq->queue->queue);
|
||||||
|
@ -210,6 +210,11 @@ static int acquire_packet_buffer(struct kernel_queue *kq,
|
||||||
uint32_t wptr, rptr;
|
uint32_t wptr, rptr;
|
||||||
unsigned int *queue_address;
|
unsigned int *queue_address;
|
||||||
|
|
||||||
|
/* When rptr == wptr, the buffer is empty.
|
||||||
|
* When rptr == wptr + 1, the buffer is full.
|
||||||
|
* It is always rptr that advances to the position of wptr, rather than
|
||||||
|
* the opposite. So we can only use up to queue_size_dwords - 1 dwords.
|
||||||
|
*/
|
||||||
rptr = *kq->rptr_kernel;
|
rptr = *kq->rptr_kernel;
|
||||||
wptr = *kq->wptr_kernel;
|
wptr = *kq->wptr_kernel;
|
||||||
queue_address = (unsigned int *)kq->pq_kernel_addr;
|
queue_address = (unsigned int *)kq->pq_kernel_addr;
|
||||||
|
@ -219,11 +224,10 @@ static int acquire_packet_buffer(struct kernel_queue *kq,
|
||||||
pr_debug("wptr: %d\n", wptr);
|
pr_debug("wptr: %d\n", wptr);
|
||||||
pr_debug("queue_address 0x%p\n", queue_address);
|
pr_debug("queue_address 0x%p\n", queue_address);
|
||||||
|
|
||||||
available_size = (rptr - 1 - wptr + queue_size_dwords) %
|
available_size = (rptr + queue_size_dwords - 1 - wptr) %
|
||||||
queue_size_dwords;
|
queue_size_dwords;
|
||||||
|
|
||||||
if (packet_size_in_dwords >= queue_size_dwords ||
|
if (packet_size_in_dwords > available_size) {
|
||||||
packet_size_in_dwords >= available_size) {
|
|
||||||
/*
|
/*
|
||||||
* make sure calling functions know
|
* make sure calling functions know
|
||||||
* acquire_packet_buffer() failed
|
* acquire_packet_buffer() failed
|
||||||
|
@ -233,6 +237,14 @@ static int acquire_packet_buffer(struct kernel_queue *kq,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wptr + packet_size_in_dwords >= queue_size_dwords) {
|
if (wptr + packet_size_in_dwords >= queue_size_dwords) {
|
||||||
|
/* make sure after rolling back to position 0, there is
|
||||||
|
* still enough space.
|
||||||
|
*/
|
||||||
|
if (packet_size_in_dwords >= rptr) {
|
||||||
|
*buffer_ptr = NULL;
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
/* fill nops, roll back and start at position 0 */
|
||||||
while (wptr > 0) {
|
while (wptr > 0) {
|
||||||
queue_address[wptr] = kq->nop_packet;
|
queue_address[wptr] = kq->nop_packet;
|
||||||
wptr = (wptr + 1) % queue_size_dwords;
|
wptr = (wptr + 1) % queue_size_dwords;
|
||||||
|
|
|
@ -521,6 +521,7 @@ struct kfd_process {
|
||||||
struct list_head signal_event_pages;
|
struct list_head signal_event_pages;
|
||||||
u32 next_nonsignal_event_id;
|
u32 next_nonsignal_event_id;
|
||||||
size_t signal_event_count;
|
size_t signal_event_count;
|
||||||
|
bool signal_event_limit_reached;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue