Files
linux-nvgpu/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.h
Lauri Peltonen e204224b26 gpu: nvgpu: Add semaphore based gk20a_channel_sync
Add semaphore implementation of the gk20a_channel_sync interface.

Each channel has one semaphore pool, which is mapped as read-write to
the channel vm. We allocate one or two semaphores from the pool for each
submit.

The first semaphore is only needed if we need to wait for an opaque sync
fd. In that case, we allocate the semaphore, and ask GPU to wait for
it's value to become 1 (semaphore acquire method).  We also queue a
kernel work that waits on the fence fd, and subsequently releases the
semaphore (sets its value to 1) so that the command buffer can proceed.

The second semaphore is used on every submit, and is used for work
completion tracking. The GPU sets its value to 1 when the command buffer
has been processed.

The channel jobs need to hold references to both semaphores so that
their backing semaphore pool slots are not reused while the job is in
flight. Therefore gk20a_channel_fence will keep a reference to the
semaphore that it represents (channel fences are stored in the job
structure). This means that we must diligently close and dup the
gk20a_channel_fence objects to avoid leaking semaphores.

Bug 1450122
Bug 1445450

Change-Id: Ib61091a1b7632fa36efe0289011040ef7c4ae8f8
Signed-off-by: Lauri Peltonen <lpeltonen@nvidia.com>
Reviewed-on: http://git-master/r/374844
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
2015-03-18 12:10:08 -07:00

117 lines
3.9 KiB
C

/*
* drivers/video/tegra/host/gk20a/channel_sync_gk20a.h
*
* GK20A Channel Synchronization Abstraction
*
* Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#ifndef _GK20A_CHANNEL_SYNC_H_
#define _GK20A_CHANNEL_SYNC_H_
#include <linux/types.h>
struct gk20a_channel_sync;
struct priv_cmd_entry;
struct channel_gk20a;
struct gk20a_semaphore;
struct gk20a_channel_fence {
bool valid;
bool wfi; /* was issued with preceding wfi */
u32 thresh; /* syncpoint fences only */
struct gk20a_semaphore *semaphore; /* semaphore fences only */
};
struct gk20a_channel_sync {
/* CPU wait for a fence returned by incr_syncpt() or incr_fd(). */
int (*wait_cpu)(struct gk20a_channel_sync *s,
struct gk20a_channel_fence *fence,
int timeout);
/* Test whether a fence returned by incr_syncpt() or incr_fd() is
* expired. */
bool (*is_expired)(struct gk20a_channel_sync *s,
struct gk20a_channel_fence *fence);
/* Generate a gpu wait cmdbuf from syncpoint. */
int (*wait_syncpt)(struct gk20a_channel_sync *s, u32 id, u32 thresh,
struct priv_cmd_entry **entry,
struct gk20a_channel_fence *fence);
/* Generate a gpu wait cmdbuf from sync fd. */
int (*wait_fd)(struct gk20a_channel_sync *s, int fd,
struct priv_cmd_entry **entry,
struct gk20a_channel_fence *fence);
/* Increment syncpoint/semaphore.
* Returns
* - a gpu cmdbuf that performs the increment when executed,
* - a fence that can be passed to wait_cpu() and is_expired().
*/
int (*incr)(struct gk20a_channel_sync *s,
struct priv_cmd_entry **entry,
struct gk20a_channel_fence *fence);
/* Increment syncpoint/semaphore, preceded by a wfi.
* Returns
* - a gpu cmdbuf that performs the increment when executed,
* - a fence that can be passed to wait_cpu() and is_expired().
*/
int (*incr_wfi)(struct gk20a_channel_sync *s,
struct priv_cmd_entry **entry,
struct gk20a_channel_fence *fence);
/* Increment syncpoint, so that the returned fence represents
* work completion (may need wfi) and can be returned to user space.
* Returns
* - a gpu cmdbuf that performs the increment when executed,
* - a fence that can be passed to wait_cpu() and is_expired(),
* - a syncpoint id/value pair that can be returned to user space.
*/
int (*incr_user_syncpt)(struct gk20a_channel_sync *s,
struct priv_cmd_entry **entry,
struct gk20a_channel_fence *fence,
bool wfi,
u32 *id, u32 *thresh);
/* Increment syncpoint/semaphore, so that the returned fence represents
* work completion (may need wfi) and can be returned to user space.
* Returns
* - a gpu cmdbuf that performs the increment when executed,
* - a fence that can be passed to wait_cpu() and is_expired(),
* - a sync fd that can be returned to user space.
*/
int (*incr_user_fd)(struct gk20a_channel_sync *s,
int wait_fence_fd,
struct priv_cmd_entry **entry,
struct gk20a_channel_fence *fence,
bool wfi,
int *fd);
/* Reset the channel syncpoint/semaphore. */
void (*set_min_eq_max)(struct gk20a_channel_sync *s);
/* flag to set sync destroy aggressiveness */
bool aggressive_destroy;
/* Free the resources allocated by gk20a_channel_sync_create. */
void (*destroy)(struct gk20a_channel_sync *s);
};
struct gk20a_channel_sync *gk20a_channel_sync_create(struct channel_gk20a *c);
void gk20a_channel_fence_close(struct gk20a_channel_fence *f);
void gk20a_channel_fence_dup(struct gk20a_channel_fence *from,
struct gk20a_channel_fence *to);
#endif