From 56abe1e472fe5364bfff2be0796396c35c91edf5 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Thu, 14 Nov 2024 16:40:20 +0100 Subject: [PATCH] panfrost: handle pool-allocation errors Because most pool-allocations happens during rendering, we have the same issue as in the previous commit; we don't have a good way to report the out-of-memory error here. So we do one of two things; we either return a NULL-ish pointer, or we print an error and ignore the call. Reviewed-by: Eric R. Smith Part-of: --- src/gallium/drivers/panfrost/pan_cmdstream.c | 51 ++++++++++++++++++- src/gallium/drivers/panfrost/pan_cmdstream.h | 3 ++ src/gallium/drivers/panfrost/pan_context.c | 20 +++++--- src/gallium/drivers/panfrost/pan_csf.c | 19 +++++-- src/gallium/drivers/panfrost/pan_csf.h | 4 +- src/gallium/drivers/panfrost/pan_fb_preload.c | 44 +++++++++++++++- src/gallium/drivers/panfrost/pan_jm.c | 14 ++++- src/gallium/drivers/panfrost/pan_jm.h | 3 +- src/gallium/drivers/panfrost/pan_job.c | 22 +++++--- src/gallium/drivers/panfrost/pan_mempool.c | 19 +++++-- src/gallium/drivers/panfrost/pan_mempool.h | 8 +-- src/gallium/drivers/panfrost/pan_screen.c | 12 +++-- src/gallium/drivers/panfrost/pan_screen.h | 2 +- src/panfrost/lib/pan_pool.h | 5 +- 14 files changed, 188 insertions(+), 38 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index e795f26f131..d8c02a25ced 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -684,6 +684,9 @@ panfrost_emit_frag_shader_meta(struct panfrost_batch *batch) PAN_DESC_ARRAY(rt_count, BLEND)); #endif + if (!xfer.cpu) + return 0; + mali_ptr blend_shaders[PIPE_MAX_COLOR_BUFS] = {0}; panfrost_get_blend_shaders(batch, blend_shaders); @@ -750,6 +753,9 @@ panfrost_emit_viewport(struct panfrost_batch *batch) #if PAN_ARCH <= 7 struct panfrost_ptr T = pan_pool_alloc_desc(&batch->pool.base, VIEWPORT); + if (!T.cpu) + return 0; + pan_pack(T.cpu, VIEWPORT, cfg) { cfg.scissor_minimum_x = minx; cfg.scissor_minimum_y = miny; @@ -792,8 +798,11 @@ panfrost_emit_depth_stencil(struct panfrost_batch *batch) struct panfrost_ptr T = pan_pool_alloc_desc(&batch->pool.base, DEPTH_STENCIL); - struct mali_depth_stencil_packed dynamic; + if (!T.cpu) + return 0; + + struct mali_depth_stencil_packed dynamic; pan_pack(&dynamic, DEPTH_STENCIL, cfg) { cfg.front_reference_value = ctx->stencil_ref.ref_value[0]; cfg.back_reference_value = ctx->stencil_ref.ref_value[back_enab ? 1 : 0]; @@ -831,6 +840,9 @@ panfrost_emit_blend_valhall(struct panfrost_batch *batch) struct panfrost_ptr T = pan_pool_alloc_desc_array(&batch->pool.base, rt_count, BLEND); + if (!T.cpu) + return 0; + mali_ptr blend_shaders[PIPE_MAX_COLOR_BUFS] = {0}; panfrost_get_blend_shaders(batch, blend_shaders); @@ -857,6 +869,10 @@ panfrost_emit_vertex_buffers(struct panfrost_batch *batch) unsigned buffer_count = util_last_bit(ctx->vb_mask); struct panfrost_ptr T = pan_pool_alloc_desc_array(&batch->pool.base, buffer_count, BUFFER); + + if (!T.cpu) + return 0; + struct mali_buffer_packed *buffers = T.cpu; memset(buffers, 0, sizeof(*buffers) * buffer_count); @@ -1402,6 +1418,9 @@ panfrost_emit_const_buf(struct panfrost_batch *batch, struct panfrost_ptr transfer = pan_pool_alloc_aligned(&batch->pool.base, sys_size, 16); + if (!transfer.cpu) + return 0; + /* Upload sysvals requested by the shader */ uint8_t *sysvals = alloca(sys_size); panfrost_upload_sysvals(batch, sysvals, transfer.gpu, ss, stage); @@ -1422,6 +1441,10 @@ panfrost_emit_const_buf(struct panfrost_batch *batch, ubos = pan_pool_alloc_desc_array(&batch->pool.base, ubo_count + 1, UNIFORM_BUFFER); #endif + + if (!ubos.cpu) + return 0; + memset(ubos.cpu, 0, desc_size * (ubo_count + 1)); if (buffer_count) @@ -1455,6 +1478,9 @@ panfrost_emit_const_buf(struct panfrost_batch *batch, struct panfrost_ptr push_transfer = pan_pool_alloc_aligned(&batch->pool.base, ss->info.push.count * 4, 16); + if (!push_transfer.cpu) + return 0; + uint32_t *push_cpu = (uint32_t *)push_transfer.cpu; *push_constants = push_transfer.gpu; @@ -1480,6 +1506,9 @@ panfrost_emit_const_buf(struct panfrost_batch *batch, ? sysvals : panfrost_map_constant_buffer_cpu(ctx, buf, src.ubo); + if (!mapped_ubo) + return 0; + /* TODO: Is there any benefit to combining ranges */ memcpy(push_cpu + i, (uint8_t *)mapped_ubo + src.offset, 4); } @@ -1651,6 +1680,12 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so, struct panfrost_pool *pool = so->pool ?: &ctx->descs; struct panfrost_ptr payload = pan_pool_alloc_aligned(&pool->base, size, 64); + + if (!payload.cpu) { + mesa_loge("panfrost_create_sampler_view_bo failed"); + return; + } + so->state = panfrost_pool_take_ref(&ctx->descs, payload.gpu); void *tex = (PAN_ARCH >= 6) ? &so->bifrost_descriptor : payload.cpu; @@ -1732,6 +1767,10 @@ panfrost_emit_texture_descriptors(struct panfrost_batch *batch, #if PAN_ARCH >= 6 struct panfrost_ptr T = pan_pool_alloc_desc_array(&batch->pool.base, alloc_count, TEXTURE); + + if (!T.cpu) + return 0; + struct mali_texture_packed *out = (struct mali_texture_packed *)T.cpu; for (int i = 0; i < actual_count; ++i) { @@ -1802,6 +1841,10 @@ panfrost_emit_sampler_descriptors(struct panfrost_batch *batch, struct panfrost_ptr T = pan_pool_alloc_desc_array( &batch->pool.base, ctx->sampler_count[stage], SAMPLER); + + if (!T.cpu) + return 0; + struct mali_sampler_packed *out = (struct mali_sampler_packed *)T.cpu; for (unsigned i = 0; i < ctx->sampler_count[stage]; ++i) { @@ -2524,6 +2567,12 @@ panfrost_emit_varying_descriptor(struct panfrost_batch *batch, unsigned count = util_bitcount(present); struct panfrost_ptr T = pan_pool_alloc_desc_array(&batch->pool.base, count + 1, ATTRIBUTE_BUFFER); + + if (!T.cpu) { + mesa_loge("panfrost_emit_varying_descriptor failed"); + return; + } + struct mali_attribute_buffer_packed *varyings = (struct mali_attribute_buffer_packed *)T.cpu; diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.h b/src/gallium/drivers/panfrost/pan_cmdstream.h index ca8420b7ac0..9ce26ed502b 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.h +++ b/src/gallium/drivers/panfrost/pan_cmdstream.h @@ -281,6 +281,9 @@ panfrost_emit_resources(struct panfrost_batch *batch, */ T = pan_pool_alloc_aligned(&batch->pool.base, nr_tables * pan_size(RESOURCE), 64); + if (!T.cpu) + return 0; + memset(T.cpu, 0, nr_tables * pan_size(RESOURCE)); panfrost_make_resource_table(T, PAN_TABLE_UBO, batch->uniform_buffers[stage], diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index 77c18e65ad8..66f71cf415e 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -1089,11 +1089,13 @@ panfrost_create_context(struct pipe_screen *screen, void *priv, unsigned flags) gallium->stream_uploader = u_upload_create_default(gallium); gallium->const_uploader = gallium->stream_uploader; - panfrost_pool_init(&ctx->descs, ctx, dev, 0, 4096, "Descriptors", true, - false); + if (panfrost_pool_init(&ctx->descs, ctx, dev, 0, 4096, "Descriptors", true, + false) || - panfrost_pool_init(&ctx->shaders, ctx, dev, PAN_BO_EXECUTE, 4096, "Shaders", - true, false); + panfrost_pool_init(&ctx->shaders, ctx, dev, PAN_BO_EXECUTE, 4096, + "Shaders", true, false)) { + goto failed; + } ctx->blitter = util_blitter_create(gallium); @@ -1117,12 +1119,14 @@ panfrost_create_context(struct pipe_screen *screen, void *priv, unsigned flags) ret = pan_screen(screen)->vtbl.context_init(ctx); - if (ret) { - gallium->destroy(gallium); - return NULL; - } + if (ret) + goto failed; return gallium; + +failed: + gallium->destroy(gallium); + return NULL; } void diff --git a/src/gallium/drivers/panfrost/pan_csf.c b/src/gallium/drivers/panfrost/pan_csf.c index 17f69a26d5d..2b010c60f88 100644 --- a/src/gallium/drivers/panfrost/pan_csf.c +++ b/src/gallium/drivers/panfrost/pan_csf.c @@ -211,14 +211,15 @@ alloc_fbd(struct panfrost_batch *batch) PAN_DESC_ARRAY(MAX2(batch->key.nr_cbufs, 1), RENDER_TARGET)); } -void +int GENX(csf_init_batch)(struct panfrost_batch *batch) { struct panfrost_device *dev = pan_device(batch->ctx->base.screen); /* Initialize the CS chunk pool. */ - panfrost_pool_init(&batch->csf.cs_chunk_pool, NULL, dev, 0, 32768, - "CS chunk pool", false, true); + if (panfrost_pool_init(&batch->csf.cs_chunk_pool, NULL, dev, 0, 32768, + "CS chunk pool", false, true)) + return -1; if (dev->debug & PAN_DBG_CS) { /* Load/store tracker if extra checks are enabled. */ @@ -229,6 +230,9 @@ GENX(csf_init_batch)(struct panfrost_batch *batch) /* Allocate and bind the command queue */ struct cs_buffer queue = csf_alloc_cs_buffer(batch); + if (!queue.gpu) + return -1; + const struct cs_builder_conf conf = { .nr_registers = 96, .nr_kernel_registers = 4, @@ -249,8 +253,14 @@ GENX(csf_init_batch)(struct panfrost_batch *batch) cs_set_scoreboard_entry(b, 2, 0); batch->framebuffer = alloc_fbd(batch); + if (!batch->framebuffer.gpu) + return -1; batch->tls = pan_pool_alloc_desc(&batch->pool.base, LOCAL_STORAGE); + if (!batch->tls.cpu) + return -1; + + return 0; } static void @@ -312,6 +322,9 @@ csf_emit_batch_end(struct panfrost_batch *batch) if (dev->debug & PAN_DBG_SYNC) { /* Get the CS state */ batch->csf.cs.state = pan_pool_alloc_aligned(&batch->pool.base, 8, 8); + if (!batch->csf.cs.state.cpu) + return -1; + memset(batch->csf.cs.state.cpu, ~0, 8); cs_move64_to(b, cs_reg64(b, 90), batch->csf.cs.state.gpu); cs_store_state(b, cs_reg64(b, 90), 0, MALI_CS_STATE_ERROR_STATUS, diff --git a/src/gallium/drivers/panfrost/pan_csf.h b/src/gallium/drivers/panfrost/pan_csf.h index b24167a8219..9538e4aa88f 100644 --- a/src/gallium/drivers/panfrost/pan_csf.h +++ b/src/gallium/drivers/panfrost/pan_csf.h @@ -115,7 +115,7 @@ struct pipe_draw_start_count_bias; int GENX(csf_init_context)(struct panfrost_context *ctx); void GENX(csf_cleanup_context)(struct panfrost_context *ctx); -void GENX(csf_init_batch)(struct panfrost_batch *batch); +int GENX(csf_init_batch)(struct panfrost_batch *batch); void GENX(csf_cleanup_batch)(struct panfrost_batch *batch); int GENX(csf_submit_batch)(struct panfrost_batch *batch); @@ -126,7 +126,7 @@ void GENX(csf_emit_fbds)(struct panfrost_batch *batch, struct pan_fb_info *fb, struct pan_tls_info *tls); void GENX(csf_emit_fragment_job)(struct panfrost_batch *batch, const struct pan_fb_info *pfb); -void GENX(csf_emit_batch_end)(struct panfrost_batch *batch); +int GENX(csf_emit_batch_end)(struct panfrost_batch *batch); void GENX(csf_launch_xfb)(struct panfrost_batch *batch, const struct pipe_draw_info *info, unsigned count); void GENX(csf_launch_grid)(struct panfrost_batch *batch, diff --git a/src/gallium/drivers/panfrost/pan_fb_preload.c b/src/gallium/drivers/panfrost/pan_fb_preload.c index 0fc2f3cdf5d..fd30b254c20 100644 --- a/src/gallium/drivers/panfrost/pan_fb_preload.c +++ b/src/gallium/drivers/panfrost/pan_fb_preload.c @@ -733,6 +733,9 @@ pan_preload_get_rsd(struct pan_fb_preload_cache *cache, PAN_DESC_ARRAY(bd_count, BLEND)); #endif + if (!rsd_ptr.cpu) + return 0; + mali_ptr blend_shaders[8] = {0}; const struct pan_preload_shader_data *preload_shader = @@ -821,6 +824,9 @@ pan_preload_emit_varying(struct pan_pool *pool) { struct panfrost_ptr varying = pan_pool_alloc_desc(pool, ATTRIBUTE); + if (!varying.cpu) + return 0; + pan_pack(varying.cpu, ATTRIBUTE, cfg) { cfg.buffer_index = 0; cfg.offset_enable = PAN_ARCH <= 5; @@ -844,6 +850,9 @@ pan_preload_emit_varying_buffer(struct pan_pool *pool, mali_ptr coordinates) #if PAN_ARCH >= 9 struct panfrost_ptr varying_buffer = pan_pool_alloc_desc(pool, BUFFER); + if (!varying_buffer.cpu) + return 0; + pan_pack(varying_buffer.cpu, BUFFER, cfg) { cfg.address = coordinates; cfg.size = 4 * sizeof(float) * 4; @@ -855,6 +864,9 @@ pan_preload_emit_varying_buffer(struct pan_pool *pool, mali_ptr coordinates) struct panfrost_ptr varying_buffer = pan_pool_alloc_desc_array( pool, (padding_buffer ? 2 : 1), ATTRIBUTE_BUFFER); + if (!varying_buffer.cpu) + return 0; + pan_pack(varying_buffer.cpu, ATTRIBUTE_BUFFER, cfg) { cfg.pointer = coordinates; cfg.stride = 4 * sizeof(float); @@ -876,6 +888,9 @@ pan_preload_emit_sampler(struct pan_pool *pool, bool nearest_filter) { struct panfrost_ptr sampler = pan_pool_alloc_desc(pool, SAMPLER); + if (!sampler.cpu) + return 0; + pan_pack(sampler.cpu, SAMPLER, cfg) { cfg.seamless_cube_map = false; cfg.normalized_coordinates = false; @@ -966,6 +981,9 @@ pan_preload_emit_textures(struct pan_pool *pool, const struct pan_fb_info *fb, struct panfrost_ptr textures = pan_pool_alloc_desc_array(pool, tex_count, TEXTURE); + if (!textures.cpu) + return 0; + for (unsigned i = 0; i < tex_count; i++) { void *texture = textures.cpu + (pan_size(TEXTURE) * i); size_t payload_size = @@ -1006,6 +1024,9 @@ pan_preload_emit_zs(struct pan_pool *pool, bool z, bool s) { struct panfrost_ptr zsd = pan_pool_alloc_desc(pool, DEPTH_STENCIL); + if (!zsd.cpu) + return 0; + pan_pack(zsd.cpu, DEPTH_STENCIL, cfg) { cfg.depth_function = MALI_FUNC_ALWAYS; cfg.depth_write_enable = z; @@ -1042,6 +1063,9 @@ pan_preload_emit_viewport(struct pan_pool *pool, uint16_t minx, uint16_t miny, { struct panfrost_ptr vp = pan_pool_alloc_desc(pool, VIEWPORT); + if (!vp.cpu) + return 0; + pan_pack(vp.cpu, VIEWPORT, cfg) { cfg.scissor_minimum_x = minx; cfg.scissor_minimum_y = miny; @@ -1133,6 +1157,12 @@ pan_preload_emit_dcd(struct pan_fb_preload_cache *cache, bool ms = pan_preload_is_ms(&views); struct panfrost_ptr spd = pan_pool_alloc_desc(pool, SHADER_PROGRAM); + + if (!spd.cpu) { + mesa_loge("pan_pool_alloc_desc failed"); + return; + } + pan_pack(spd.cpu, SHADER_PROGRAM, cfg) { cfg.stage = MALI_SHADER_STAGE_FRAGMENT; cfg.fragment_coverage_bitmask_type = MALI_COVERAGE_BITMASK_TYPE_GL; @@ -1144,6 +1174,11 @@ pan_preload_emit_dcd(struct pan_fb_preload_cache *cache, unsigned bd_count = views.rt_count; struct panfrost_ptr blend = pan_pool_alloc_desc_array(pool, bd_count, BLEND); + if (!blend.cpu) { + mesa_loge("pan_pool_alloc_desc_array failed"); + return; + } + if (!zs) { pan_preload_emit_blends(preload_shader, &views, NULL, blend.cpu); } @@ -1198,7 +1233,11 @@ pan_preload_emit_pre_frame_dcd(struct pan_fb_preload_cache *cache, { unsigned dcd_idx = zs ? 1 : 0; pan_preload_fb_alloc_pre_post_dcds(desc_pool, fb); - assert(fb->bifrost.pre_post.dcds.cpu); + if (!fb->bifrost.pre_post.dcds.cpu) { + mesa_loge("pan_preload_fb_alloc_pre_post_dcds failed"); + return; + } + void *dcd = fb->bifrost.pre_post.dcds.cpu + (dcd_idx * pan_size(DRAW)); /* We only use crc_rt to determine whether to force writes for updating @@ -1264,6 +1303,9 @@ pan_preload_emit_tiler_job(struct pan_fb_preload_cache *cache, struct pan_pool * { struct panfrost_ptr job = pan_pool_alloc_desc(desc_pool, TILER_JOB); + if (!job.cpu) + return (struct panfrost_ptr){0}; + pan_preload_emit_dcd(cache, desc_pool, fb, zs, coords, tsd, pan_section_ptr(job.cpu, TILER_JOB, DRAW), false); diff --git a/src/gallium/drivers/panfrost/pan_jm.c b/src/gallium/drivers/panfrost/pan_jm.c index d220efe4b6e..b6f6b204dad 100644 --- a/src/gallium/drivers/panfrost/pan_jm.c +++ b/src/gallium/drivers/panfrost/pan_jm.c @@ -38,7 +38,7 @@ #error "JM helpers are only used for gen < 10" #endif -void +int GENX(jm_init_batch)(struct panfrost_batch *batch) { /* Reserve the framebuffer and local storage descriptors */ @@ -50,6 +50,8 @@ GENX(jm_init_batch)(struct panfrost_batch *batch) &batch->pool.base, PAN_DESC(FRAMEBUFFER), PAN_DESC(ZS_CRC_EXTENSION), PAN_DESC_ARRAY(MAX2(batch->key.nr_cbufs, 1), RENDER_TARGET)); #endif + if (!batch->framebuffer.gpu) + return -1; #if PAN_ARCH >= 6 batch->tls = pan_pool_alloc_desc(&batch->pool.base, LOCAL_STORAGE); @@ -57,6 +59,9 @@ GENX(jm_init_batch)(struct panfrost_batch *batch) /* On Midgard, the TLS is embedded in the FB descriptor */ batch->tls = batch->framebuffer; + if (!batch->tls.cpu) + return -1; + #if PAN_ARCH == 5 struct mali_framebuffer_pointer_packed ptr; @@ -68,6 +73,8 @@ GENX(jm_init_batch)(struct panfrost_batch *batch) batch->tls.gpu = ptr.opaque[0]; #endif #endif + + return 0; } static int @@ -965,6 +972,11 @@ GENX(jm_launch_draw)(struct panfrost_batch *batch, tiler = pan_pool_alloc_desc(&batch->pool.base, TILER_JOB); } + if ((!idvs && !vertex.cpu) || !tiler.cpu) { + mesa_loge("jm_launch_draw failed"); + return; + } + #if PAN_ARCH == 9 assert(idvs && "Memory allocated IDVS required on Valhall"); diff --git a/src/gallium/drivers/panfrost/pan_jm.h b/src/gallium/drivers/panfrost/pan_jm.h index 275dfc86fb1..8269cfb7352 100644 --- a/src/gallium/drivers/panfrost/pan_jm.h +++ b/src/gallium/drivers/panfrost/pan_jm.h @@ -61,7 +61,8 @@ GENX(jm_cleanup_context)(struct panfrost_context *ctx) { } -void GENX(jm_init_batch)(struct panfrost_batch *batch); +int +GENX(jm_init_batch)(struct panfrost_batch *batch); static inline void GENX(jm_cleanup_batch)(struct panfrost_batch *batch) diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c index e96164324cd..aca6a9349b4 100644 --- a/src/gallium/drivers/panfrost/pan_job.c +++ b/src/gallium/drivers/panfrost/pan_job.c @@ -70,7 +70,7 @@ panfrost_batch_add_surface(struct panfrost_batch *batch, } } -static void +static int panfrost_batch_init(struct panfrost_context *ctx, const struct pipe_framebuffer_state *key, struct panfrost_batch *batch) @@ -92,21 +92,23 @@ panfrost_batch_init(struct panfrost_context *ctx, /* Preallocate the main pool, since every batch has at least one job * structure so it will be used */ - panfrost_pool_init(&batch->pool, NULL, dev, 0, 65536, "Batch pool", true, - true); + if (panfrost_pool_init(&batch->pool, NULL, dev, 0, 65536, "Batch pool", + true, true)) + return -1; /* Don't preallocate the invisible pool, since not every batch will use * the pre-allocation, particularly if the varyings are larger than the * preallocation and a reallocation is needed after anyway. */ - panfrost_pool_init(&batch->invisible_pool, NULL, dev, PAN_BO_INVISIBLE, - 65536, "Varyings", false, true); + if (panfrost_pool_init(&batch->invisible_pool, NULL, dev, + PAN_BO_INVISIBLE, 65536, "Varyings", false, true)) + return -1; for (unsigned i = 0; i < batch->key.nr_cbufs; ++i) panfrost_batch_add_surface(batch, batch->key.cbufs[i]); panfrost_batch_add_surface(batch, batch->key.zsbuf); - screen->vtbl.init_batch(batch); + return screen->vtbl.init_batch(batch); } static void @@ -184,7 +186,13 @@ panfrost_get_batch(struct panfrost_context *ctx, panfrost_batch_submit(ctx, batch); } - panfrost_batch_init(ctx, key, batch); + if (panfrost_batch_init(ctx, key, batch)) { + mesa_loge("panfrost_batch_init failed"); + panfrost_batch_cleanup(ctx, batch); + /* prevent this batch from being reused without initializing */ + batch->seqnum = 0; + return NULL; + } unsigned batch_idx = panfrost_batch_idx(batch); BITSET_SET(ctx->batches.active, batch_idx); diff --git a/src/gallium/drivers/panfrost/pan_mempool.c b/src/gallium/drivers/panfrost/pan_mempool.c index 1a59974df11..4f5613297e6 100644 --- a/src/gallium/drivers/panfrost/pan_mempool.c +++ b/src/gallium/drivers/panfrost/pan_mempool.c @@ -54,7 +54,8 @@ panfrost_pool_alloc_backing(struct panfrost_pool *pool, size_t bo_sz) */ struct panfrost_bo *bo = panfrost_bo_create(pool->dev, bo_sz, pool->create_flags, pool->label); - assert(bo); + if (!bo) + return NULL; if (pool->owned) util_dynarray_append(&pool->bos, struct panfrost_bo *, bo); @@ -67,7 +68,7 @@ panfrost_pool_alloc_backing(struct panfrost_pool *pool, size_t bo_sz) return bo; } -void +int panfrost_pool_init(struct panfrost_pool *pool, void *memctx, struct panfrost_device *dev, unsigned create_flags, size_t slab_size, const char *label, bool prealloc, @@ -83,8 +84,12 @@ panfrost_pool_init(struct panfrost_pool *pool, void *memctx, if (owned) util_dynarray_init(&pool->bos, memctx); - if (prealloc) - panfrost_pool_alloc_backing(pool, pool->base.slab_size); + if (prealloc) { + if (panfrost_pool_alloc_backing(pool, pool->base.slab_size) == NULL) + return -1; + } + + return 0; } void @@ -143,6 +148,9 @@ panfrost_pool_alloc_aligned(struct panfrost_pool *pool, size_t sz, unsigned bo_size = aligned + PAN_GUARD_SIZE; bo = panfrost_pool_alloc_backing(pool, bo_size); + if (!bo) + return (struct panfrost_ptr){0}; + memset(bo->ptr.cpu, 0xbb, bo_size); /* Place the object as close as possible to the protected @@ -160,6 +168,9 @@ panfrost_pool_alloc_aligned(struct panfrost_pool *pool, size_t sz, if (unlikely(bo == NULL || (offset + sz) >= pool->base.slab_size)) { bo = panfrost_pool_alloc_backing( pool, ALIGN_POT(MAX2(pool->base.slab_size, sz), 4096)); + if (!bo) + return (struct panfrost_ptr){0}; + offset = 0; } diff --git a/src/gallium/drivers/panfrost/pan_mempool.h b/src/gallium/drivers/panfrost/pan_mempool.h index ae61aba84ef..954ece1ffd2 100644 --- a/src/gallium/drivers/panfrost/pan_mempool.h +++ b/src/gallium/drivers/panfrost/pan_mempool.h @@ -89,10 +89,10 @@ panfrost_pool_take_ref(struct panfrost_pool *pool, mali_ptr ptr) }; } -void panfrost_pool_init(struct panfrost_pool *pool, void *memctx, - struct panfrost_device *dev, unsigned create_flags, - size_t slab_size, const char *label, bool prealloc, - bool owned); +int panfrost_pool_init(struct panfrost_pool *pool, void *memctx, + struct panfrost_device *dev, unsigned create_flags, + size_t slab_size, const char *label, bool prealloc, + bool owned); void panfrost_pool_cleanup(struct panfrost_pool *pool); diff --git a/src/gallium/drivers/panfrost/pan_screen.c b/src/gallium/drivers/panfrost/pan_screen.c index d8883829fcc..4baeec9bdfa 100644 --- a/src/gallium/drivers/panfrost/pan_screen.c +++ b/src/gallium/drivers/panfrost/pan_screen.c @@ -1021,10 +1021,14 @@ panfrost_create_screen(int fd, const struct pipe_screen_config *config, panfrost_disk_cache_init(screen); - panfrost_pool_init(&screen->mempools.bin, NULL, dev, PAN_BO_EXECUTE, 4096, - "Preload shaders", false, true); - panfrost_pool_init(&screen->mempools.desc, NULL, dev, 0, 65536, - "Preload RSDs", false, true); + if (panfrost_pool_init(&screen->mempools.bin, NULL, dev, PAN_BO_EXECUTE, + 4096, "Preload shaders", false, true) || + panfrost_pool_init(&screen->mempools.desc, NULL, dev, 0, 65536, + "Preload RSDs", false, true)) { + panfrost_destroy_screen(&(screen->base)); + return NULL; + } + if (dev->arch == 4) panfrost_cmdstream_screen_init_v4(screen); else if (dev->arch == 5) diff --git a/src/gallium/drivers/panfrost/pan_screen.h b/src/gallium/drivers/panfrost/pan_screen.h index f703cc08e62..0bc81a215e0 100644 --- a/src/gallium/drivers/panfrost/pan_screen.h +++ b/src/gallium/drivers/panfrost/pan_screen.h @@ -75,7 +75,7 @@ struct panfrost_vtable { void (*context_cleanup)(struct panfrost_context *ctx); /* Device-dependent initialization/cleanup of a panfrost_batch */ - void (*init_batch)(struct panfrost_batch *batch); + int (*init_batch)(struct panfrost_batch *batch); void (*cleanup_batch)(struct panfrost_batch *batch); /* Device-dependent submission of a panfrost_batch */ diff --git a/src/panfrost/lib/pan_pool.h b/src/panfrost/lib/pan_pool.h index 3a9098e65bb..b4a6a38041d 100644 --- a/src/panfrost/lib/pan_pool.h +++ b/src/panfrost/lib/pan_pool.h @@ -70,7 +70,10 @@ pan_pool_upload_aligned(struct pan_pool *pool, const void *data, size_t sz, unsigned alignment) { struct panfrost_ptr transfer = pan_pool_alloc_aligned(pool, sz, alignment); - memcpy(transfer.cpu, data, sz); + + if (transfer.cpu) + memcpy(transfer.cpu, data, sz); + return transfer.gpu; }