mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-25 11:04:51 +03:00
gpu: nvgpu: Abstract rw_semaphore implementation
Abstract implementation of rw_semaphore. In Linux it's implemented in terms of rw_semaphore. Change deterministic_busy to use the new implementation. JIRA NVGPU-259 Change-Id: Ia9c1b6e397581bff7711c5ab6fb76ef6d23cff87 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1570405 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
c7e0c7e7ce
commit
7685f60d9d
@@ -47,6 +47,7 @@ nvgpu-y := \
|
||||
common/linux/sysfs.o \
|
||||
common/linux/cde.o \
|
||||
common/linux/io.o \
|
||||
common/linux/rwsem.o \
|
||||
common/mm/nvgpu_allocator.o \
|
||||
common/mm/bitmap_allocator.o \
|
||||
common/mm/buddy_allocator.o \
|
||||
|
||||
@@ -44,7 +44,7 @@ static void nvgpu_init_vars(struct gk20a *g)
|
||||
gk20a_init_gr(g);
|
||||
|
||||
init_rwsem(&l->busy_lock);
|
||||
init_rwsem(&g->deterministic_busy);
|
||||
nvgpu_rwsem_init(&g->deterministic_busy);
|
||||
|
||||
nvgpu_spinlock_init(&g->mc_enable_lock);
|
||||
|
||||
|
||||
39
drivers/gpu/nvgpu/common/linux/rwsem.c
Normal file
39
drivers/gpu/nvgpu/common/linux/rwsem.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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.
|
||||
*/
|
||||
|
||||
#include <nvgpu/rwsem.h>
|
||||
|
||||
void nvgpu_rwsem_init(struct nvgpu_rwsem *rwsem)
|
||||
{
|
||||
init_rwsem(&rwsem->rwsem);
|
||||
}
|
||||
|
||||
void nvgpu_rwsem_up_read(struct nvgpu_rwsem *rwsem)
|
||||
{
|
||||
up_read(&rwsem->rwsem);
|
||||
}
|
||||
|
||||
void nvgpu_rwsem_down_read(struct nvgpu_rwsem *rwsem)
|
||||
{
|
||||
down_read(&rwsem->rwsem);
|
||||
}
|
||||
|
||||
void nvgpu_rwsem_up_write(struct nvgpu_rwsem *rwsem)
|
||||
{
|
||||
up_write(&rwsem->rwsem);
|
||||
}
|
||||
|
||||
void nvgpu_rwsem_down_write(struct nvgpu_rwsem *rwsem)
|
||||
{
|
||||
down_write(&rwsem->rwsem);
|
||||
}
|
||||
@@ -602,10 +602,10 @@ unbind:
|
||||
|
||||
/* put back the channel-wide submit ref from init */
|
||||
if (ch->deterministic) {
|
||||
down_read(&g->deterministic_busy);
|
||||
nvgpu_rwsem_down_read(&g->deterministic_busy);
|
||||
ch->deterministic = false;
|
||||
gk20a_idle(g);
|
||||
up_read(&g->deterministic_busy);
|
||||
nvgpu_rwsem_up_read(&g->deterministic_busy);
|
||||
}
|
||||
|
||||
ch->vpr = false;
|
||||
@@ -1268,7 +1268,7 @@ int gk20a_channel_alloc_gpfifo(struct channel_gk20a *c,
|
||||
c->vpr = true;
|
||||
|
||||
if (flags & NVGPU_ALLOC_GPFIFO_EX_FLAGS_DETERMINISTIC) {
|
||||
down_read(&g->deterministic_busy);
|
||||
nvgpu_rwsem_down_read(&g->deterministic_busy);
|
||||
/*
|
||||
* Railgating isn't deterministic; instead of disallowing
|
||||
* railgating globally, take a power refcount for this
|
||||
@@ -1280,12 +1280,12 @@ int gk20a_channel_alloc_gpfifo(struct channel_gk20a *c,
|
||||
*/
|
||||
err = gk20a_busy(g);
|
||||
if (err) {
|
||||
up_read(&g->deterministic_busy);
|
||||
nvgpu_rwsem_up_read(&g->deterministic_busy);
|
||||
return err;
|
||||
}
|
||||
|
||||
c->deterministic = true;
|
||||
up_read(&g->deterministic_busy);
|
||||
nvgpu_rwsem_up_read(&g->deterministic_busy);
|
||||
}
|
||||
|
||||
/* an address space needs to have been bound at this point. */
|
||||
@@ -1397,10 +1397,10 @@ clean_up:
|
||||
memset(&c->gpfifo, 0, sizeof(struct gpfifo_desc));
|
||||
clean_up_idle:
|
||||
if (c->deterministic) {
|
||||
down_read(&g->deterministic_busy);
|
||||
nvgpu_rwsem_down_read(&g->deterministic_busy);
|
||||
gk20a_idle(g);
|
||||
c->deterministic = false;
|
||||
up_read(&g->deterministic_busy);
|
||||
nvgpu_rwsem_up_read(&g->deterministic_busy);
|
||||
}
|
||||
nvgpu_err(g, "fail");
|
||||
return err;
|
||||
@@ -2661,7 +2661,7 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
|
||||
|
||||
/* Grab access to HW to deal with do_idle */
|
||||
if (c->deterministic)
|
||||
down_read(&g->deterministic_busy);
|
||||
nvgpu_rwsem_down_read(&g->deterministic_busy);
|
||||
|
||||
trace_gk20a_channel_submit_gpfifo(g->name,
|
||||
c->chid,
|
||||
@@ -2741,7 +2741,7 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
|
||||
|
||||
/* No hw access beyond this point */
|
||||
if (c->deterministic)
|
||||
up_read(&g->deterministic_busy);
|
||||
nvgpu_rwsem_up_read(&g->deterministic_busy);
|
||||
|
||||
trace_gk20a_channel_submitted_gpfifo(g->name,
|
||||
c->chid,
|
||||
@@ -2765,7 +2765,7 @@ clean_up:
|
||||
gk20a_fence_put(pre_fence);
|
||||
gk20a_fence_put(post_fence);
|
||||
if (c->deterministic)
|
||||
up_read(&g->deterministic_busy);
|
||||
nvgpu_rwsem_up_read(&g->deterministic_busy);
|
||||
else if (need_deferred_cleanup)
|
||||
gk20a_idle(g);
|
||||
|
||||
@@ -2787,7 +2787,7 @@ void gk20a_channel_deterministic_idle(struct gk20a *g)
|
||||
u32 chid;
|
||||
|
||||
/* Grab exclusive access to the hw to block new submits */
|
||||
down_write(&g->deterministic_busy);
|
||||
nvgpu_rwsem_down_write(&g->deterministic_busy);
|
||||
|
||||
for (chid = 0; chid < f->num_channels; chid++) {
|
||||
struct channel_gk20a *ch = &f->channel[chid];
|
||||
@@ -2845,7 +2845,7 @@ void gk20a_channel_deterministic_unidle(struct gk20a *g)
|
||||
}
|
||||
|
||||
/* Release submits, new deterministic channels and frees */
|
||||
up_write(&g->deterministic_busy);
|
||||
nvgpu_rwsem_up_write(&g->deterministic_busy);
|
||||
}
|
||||
|
||||
int gk20a_init_channel_support(struct gk20a *g, u32 chid)
|
||||
|
||||
@@ -58,6 +58,7 @@ struct nvgpu_mem_sgt;
|
||||
#include <nvgpu/pmu.h>
|
||||
#include <nvgpu/atomic.h>
|
||||
#include <nvgpu/barrier.h>
|
||||
#include <nvgpu/rwsem.h>
|
||||
|
||||
#include "clk_gk20a.h"
|
||||
#include "ce2_gk20a.h"
|
||||
@@ -1082,7 +1083,7 @@ struct gk20a {
|
||||
* for submits and held for channel lifetime but dropped for an ongoing
|
||||
* gk20a_do_idle().
|
||||
*/
|
||||
struct rw_semaphore deterministic_busy;
|
||||
struct nvgpu_rwsem deterministic_busy;
|
||||
|
||||
struct nvgpu_falcon pmu_flcn;
|
||||
struct nvgpu_falcon sec2_flcn;
|
||||
|
||||
26
drivers/gpu/nvgpu/include/nvgpu/linux/rwsem.h
Normal file
26
drivers/gpu/nvgpu/include/nvgpu/linux/rwsem.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __NVGPU_RWSEM_LINUX_H__
|
||||
#define __NVGPU_RWSEM_LINUX_H__
|
||||
|
||||
#include <linux/rwsem.h>
|
||||
|
||||
struct nvgpu_rwsem {
|
||||
struct rw_semaphore rwsem;
|
||||
};
|
||||
|
||||
#endif
|
||||
44
drivers/gpu/nvgpu/include/nvgpu/rwsem.h
Normal file
44
drivers/gpu/nvgpu/include/nvgpu/rwsem.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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 AUTHORS OR COPYRIGHT HOLDERS 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 __NVGPU_RWSEM_H__
|
||||
#define __NVGPU_RWSEM_H__
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <nvgpu/linux/rwsem.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* struct nvgpu_rwsem
|
||||
*
|
||||
* Should be implemented per-OS in a separate library
|
||||
* But implementation should adhere to rw_semaphore implementation
|
||||
* as specified in Linux Documentation
|
||||
*/
|
||||
struct nvgpu_rwsem;
|
||||
|
||||
void nvgpu_rwsem_init(struct nvgpu_rwsem *rwsem);
|
||||
void nvgpu_rwsem_up_read(struct nvgpu_rwsem *rwsem);
|
||||
void nvgpu_rwsem_down_read(struct nvgpu_rwsem *rwsem);
|
||||
void nvgpu_rwsem_up_write(struct nvgpu_rwsem *rwsem);
|
||||
void nvgpu_rwsem_down_write(struct nvgpu_rwsem *rwsem);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user