summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/v3d
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2019-04-02 16:51:44 -0700
committerEric Anholt <[email protected]>2019-04-04 17:30:35 -0700
commite3063a8b2fd7364c9beeb059599a7d4e62c9b4c5 (patch)
tree3d3f04ab0042b3de2ecfd14bf3ec12cd71c94bcf /src/gallium/drivers/v3d
parenta113a42e7369a4e43a1db1c9a7a35a3f7175615e (diff)
v3d: Add support for handling OOM signals from the simulator.
I have v3d allocating enough initial allocation memory that we've been passing tests without it, but to match kernel behavior more it would be good to actually exercise the OOM path.
Diffstat (limited to 'src/gallium/drivers/v3d')
-rw-r--r--src/gallium/drivers/v3d/v3d_context.h1
-rw-r--r--src/gallium/drivers/v3d/v3d_simulator.c50
-rw-r--r--src/gallium/drivers/v3d/v3dx_simulator.c41
3 files changed, 78 insertions, 14 deletions
diff --git a/src/gallium/drivers/v3d/v3d_context.h b/src/gallium/drivers/v3d/v3d_context.h
index de902ece205..3b39d18145d 100644
--- a/src/gallium/drivers/v3d/v3d_context.h
+++ b/src/gallium/drivers/v3d/v3d_context.h
@@ -552,6 +552,7 @@ void v3d_query_init(struct pipe_context *pctx);
void v3d_simulator_init(struct v3d_screen *screen);
void v3d_simulator_destroy(struct v3d_screen *screen);
+uint32_t v3d_simulator_get_spill(uint32_t spill_size);
int v3d_simulator_ioctl(int fd, unsigned long request, void *arg);
void v3d_simulator_open_from_handle(int fd, int handle, uint32_t size);
diff --git a/src/gallium/drivers/v3d/v3d_simulator.c b/src/gallium/drivers/v3d/v3d_simulator.c
index c5ddaa03103..6e2d25e9448 100644
--- a/src/gallium/drivers/v3d/v3d_simulator.c
+++ b/src/gallium/drivers/v3d/v3d_simulator.c
@@ -52,6 +52,7 @@
#include "util/hash_table.h"
#include "util/ralloc.h"
#include "util/set.h"
+#include "util/u_dynarray.h"
#include "util/u_memory.h"
#include "util/u_mm.h"
#include "drm-uapi/i915_drm.h"
@@ -63,6 +64,7 @@
/** Global (across GEM fds) state for the simulator */
static struct v3d_simulator_state {
mtx_t mutex;
+ mtx_t submit_lock;
struct v3d_hw *v3d;
int ver;
@@ -80,6 +82,7 @@ static struct v3d_simulator_state {
/** Mapping from GEM fd to struct v3d_simulator_file * */
struct hash_table *fd_map;
+ struct util_dynarray bin_oom;
int refcount;
} sim_state = {
.mutex = _MTX_INITIALIZER_NP,
@@ -162,7 +165,7 @@ set_gmp_flags(struct v3d_simulator_file *file,
* that also contains the drm_gem_cma_object struct.
*/
static struct v3d_simulator_bo *
-v3d_create_simulator_bo(int fd, int handle, unsigned size)
+v3d_create_simulator_bo(int fd, unsigned size)
{
struct v3d_simulator_file *file = v3d_get_simulator_file_for_fd(fd);
struct v3d_simulator_bo *sim_bo = rzalloc(file,
@@ -170,7 +173,6 @@ v3d_create_simulator_bo(int fd, int handle, unsigned size)
size = align(size, 4096);
sim_bo->file = file;
- sim_bo->handle = handle;
mtx_lock(&sim_state.mutex);
sim_bo->block = u_mmAllocMem(sim_state.heap, size + 4, GMP_ALIGN2, 0);
@@ -187,6 +189,18 @@ v3d_create_simulator_bo(int fd, int handle, unsigned size)
*(uint32_t *)(sim_bo->sim_vaddr + sim_bo->size) = BO_SENTINEL;
+ return sim_bo;
+}
+
+static struct v3d_simulator_bo *
+v3d_create_simulator_bo_for_gem(int fd, int handle, unsigned size)
+{
+ struct v3d_simulator_file *file = v3d_get_simulator_file_for_fd(fd);
+ struct v3d_simulator_bo *sim_bo =
+ v3d_create_simulator_bo(fd, size);
+
+ sim_bo->handle = handle;
+
/* Map the GEM buffer for copy in/out to the simulator. i915 blocks
* dumb mmap on render nodes, so use their ioctl directly if we're on
* one.
@@ -238,6 +252,20 @@ v3d_create_simulator_bo(int fd, int handle, unsigned size)
return sim_bo;
}
+static int bin_fd;
+
+uint32_t
+v3d_simulator_get_spill(uint32_t spill_size)
+{
+ struct v3d_simulator_bo *sim_bo =
+ v3d_create_simulator_bo(bin_fd, spill_size);
+
+ util_dynarray_append(&sim_state.bin_oom, struct v3d_simulator_bo *,
+ sim_bo);
+
+ return sim_bo->block->ofs;
+}
+
static void
v3d_free_simulator_bo(struct v3d_simulator_bo *sim_bo)
{
@@ -331,11 +359,21 @@ v3d_simulator_submit_cl_ioctl(int fd, struct drm_v3d_submit_cl *submit)
if (ret)
return ret;
+ mtx_lock(&sim_state.submit_lock);
+ bin_fd = fd;
if (sim_state.ver >= 41)
v3d41_simulator_submit_cl_ioctl(sim_state.v3d, submit, file->gmp->ofs);
else
v3d33_simulator_submit_cl_ioctl(sim_state.v3d, submit, file->gmp->ofs);
+ util_dynarray_foreach(&sim_state.bin_oom, struct v3d_simulator_bo *,
+ sim_bo) {
+ v3d_free_simulator_bo(*sim_bo);
+ }
+ util_dynarray_clear(&sim_state.bin_oom);
+
+ mtx_unlock(&sim_state.submit_lock);
+
ret = v3d_simulator_unpin_bos(file, submit);
if (ret)
return ret;
@@ -352,7 +390,7 @@ v3d_simulator_submit_cl_ioctl(int fd, struct drm_v3d_submit_cl *submit)
*/
void v3d_simulator_open_from_handle(int fd, int handle, uint32_t size)
{
- v3d_create_simulator_bo(fd, handle, size);
+ v3d_create_simulator_bo_for_gem(fd, handle, size);
}
/**
@@ -391,7 +429,8 @@ v3d_simulator_create_bo_ioctl(int fd, struct drm_v3d_create_bo *args)
if (ret == 0) {
struct v3d_simulator_bo *sim_bo =
- v3d_create_simulator_bo(fd, args->handle, args->size);
+ v3d_create_simulator_bo_for_gem(fd, args->handle,
+ args->size);
args->offset = sim_bo->block->ofs;
}
@@ -548,6 +587,8 @@ v3d_simulator_init_global(const struct v3d_device_info *devinfo)
_mesa_hash_pointer,
_mesa_key_pointer_equal);
+ util_dynarray_init(&sim_state.bin_oom, NULL);
+
if (sim_state.ver >= 41)
v3d41_simulator_init_regs(sim_state.v3d);
else
@@ -589,6 +630,7 @@ v3d_simulator_destroy(struct v3d_screen *screen)
mtx_lock(&sim_state.mutex);
if (!--sim_state.refcount) {
_mesa_hash_table_destroy(sim_state.fd_map, NULL);
+ util_dynarray_fini(&sim_state.bin_oom);
u_mmDestroy(sim_state.heap);
/* No memsetting the struct, because it contains the mutex. */
sim_state.mem = NULL;
diff --git a/src/gallium/drivers/v3d/v3dx_simulator.c b/src/gallium/drivers/v3d/v3dx_simulator.c
index e6db838c0de..c14c41f964a 100644
--- a/src/gallium/drivers/v3d/v3dx_simulator.c
+++ b/src/gallium/drivers/v3d/v3dx_simulator.c
@@ -101,6 +101,21 @@ v3d_invalidate_caches(struct v3d_hw *v3d)
v3d_invalidate_slices(v3d);
}
+static uint32_t g_gmp_ofs;
+static void
+v3d_reload_gmp(struct v3d_hw *v3d)
+{
+ /* Completely reset the GMP. */
+ V3D_WRITE(V3D_GMP_0_CFG,
+ V3D_GMP_0_CFG_PROTENABLE_SET);
+ V3D_WRITE(V3D_GMP_0_TABLE_ADDR, g_gmp_ofs);
+ V3D_WRITE(V3D_GMP_0_CLEAR_LOAD, ~0);
+ while (V3D_READ(V3D_GMP_0_STATUS) &
+ V3D_GMP_0_STATUS_CFG_BUSY_SET) {
+ ;
+ }
+}
+
int
v3dX(simulator_submit_tfu_ioctl)(struct v3d_hw *v3d,
struct drm_v3d_submit_tfu *args)
@@ -167,6 +182,18 @@ v3d_isr(uint32_t hub_status)
/* Check the per-core bits */
if (hub_status & (1 << 0)) {
uint32_t core_status = V3D_READ(V3D_CTL_0_INT_STS);
+ V3D_WRITE(V3D_CTL_0_INT_CLR, core_status);
+
+ if (core_status & V3D_CTL_0_INT_STS_INT_OUTOMEM_SET) {
+ uint32_t size = 256 * 1024;
+ uint32_t offset = v3d_simulator_get_spill(size);
+
+ v3d_reload_gmp(v3d);
+
+ V3D_WRITE(V3D_PTB_0_BPOA, offset);
+ V3D_WRITE(V3D_PTB_0_BPOS, size);
+ return;
+ }
if (core_status & V3D_CTL_0_INT_STS_INT_GMPV_SET) {
fprintf(stderr, "GMP violation at 0x%08x\n",
@@ -198,7 +225,8 @@ v3dX(simulator_init_regs)(struct v3d_hw *v3d)
V3D_WRITE(V3D_CTL_0_MISCCFG, V3D_CTL_1_MISCCFG_OVRTMUOUT_SET);
#endif
- uint32_t core_interrupts = V3D_CTL_0_INT_STS_INT_GMPV_SET;
+ uint32_t core_interrupts = (V3D_CTL_0_INT_STS_INT_GMPV_SET |
+ V3D_CTL_0_INT_STS_INT_OUTOMEM_SET);
V3D_WRITE(V3D_CTL_0_INT_MSK_SET, ~core_interrupts);
V3D_WRITE(V3D_CTL_0_INT_MSK_CLR, core_interrupts);
@@ -211,15 +239,8 @@ v3dX(simulator_submit_cl_ioctl)(struct v3d_hw *v3d,
struct drm_v3d_submit_cl *submit,
uint32_t gmp_ofs)
{
- /* Completely reset the GMP. */
- V3D_WRITE(V3D_GMP_0_CFG,
- V3D_GMP_0_CFG_PROTENABLE_SET);
- V3D_WRITE(V3D_GMP_0_TABLE_ADDR, gmp_ofs);
- V3D_WRITE(V3D_GMP_0_CLEAR_LOAD, ~0);
- while (V3D_READ(V3D_GMP_0_STATUS) &
- V3D_GMP_0_STATUS_CFG_BUSY_SET) {
- ;
- }
+ g_gmp_ofs = gmp_ofs;
+ v3d_reload_gmp(v3d);
v3d_invalidate_caches(v3d);