diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-11-11 14:56:22 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-11-11 15:05:56 +0000 |
commit | c489934ed732ed3d5a906939381c62a6bc1c38d5 (patch) | |
tree | 7d96475036f22ccad0bc43ad98ad7f71449f4ecb | |
parent | 3e93449b5492a4fc09401c23f8754655b63959b5 (diff) |
xvmc: Handle allocation failure around batch submission
If we fail to allocate a new batch, just stall and reuse the old one
rather than crashing.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | xvmc/i915_xvmc.c | 2 | ||||
-rw-r--r-- | xvmc/i965_xvmc.c | 2 | ||||
-rw-r--r-- | xvmc/intel_batchbuffer.c | 60 | ||||
-rw-r--r-- | xvmc/intel_batchbuffer.h | 4 | ||||
-rw-r--r-- | xvmc/intel_xvmc.c | 16 | ||||
-rw-r--r-- | xvmc/xvmc_vld.c | 4 |
6 files changed, 50 insertions, 38 deletions
diff --git a/xvmc/i915_xvmc.c b/xvmc/i915_xvmc.c index fbd4555e..204d9507 100644 --- a/xvmc/i915_xvmc.c +++ b/xvmc/i915_xvmc.c @@ -1207,7 +1207,7 @@ static int i915_xvmc_mc_render_surface(Display * display, XvMCContext * context, } } - intelFlushBatch(TRUE); + intelFlushBatch(); i915_xvmc_free_render_state_buffers(pI915XvMC); diff --git a/xvmc/i965_xvmc.c b/xvmc/i965_xvmc.c index 1850480c..198027f4 100644 --- a/xvmc/i965_xvmc.c +++ b/xvmc/i965_xvmc.c @@ -841,7 +841,7 @@ static Status render_surface(Display * display, } } } - intelFlushBatch(TRUE); + intelFlushBatch(); UNLOCK_HARDWARE(intel_ctx->hw_context); } return Success; diff --git a/xvmc/intel_batchbuffer.c b/xvmc/intel_batchbuffer.c index 3fa16bb4..b427d852 100644 --- a/xvmc/intel_batchbuffer.c +++ b/xvmc/intel_batchbuffer.c @@ -62,6 +62,15 @@ static void i965_end_batch(void) xvmc_driver->batch.ptr += 4; } +static void reset_batch(void) +{ + dri_bo *bo = xvmc_driver->batch.buf; + + xvmc_driver->batch.ptr = xvmc_driver->batch.init_ptr = bo->virtual; + xvmc_driver->batch.size = bo->size; + xvmc_driver->batch.space = bo->size - 8; +} + Bool intelInitBatchBuffer(void) { if ((xvmc_driver->batch.buf = @@ -71,59 +80,50 @@ Bool intelInitBatchBuffer(void) return False; } - drm_intel_gem_bo_map_gtt(xvmc_driver->batch.buf); + if (drm_intel_gem_bo_map_gtt(xvmc_driver->batch.buf)) { + drm_intel_bo_unreference(xvmc_driver->batch.buf); + return False; + } - xvmc_driver->batch.init_ptr = xvmc_driver->batch.buf->virtual; - xvmc_driver->batch.size = BATCH_SIZE; - xvmc_driver->batch.space = BATCH_SIZE; - xvmc_driver->batch.ptr = xvmc_driver->batch.init_ptr; + reset_batch(); return True; } void intelFiniBatchBuffer(void) { - drm_intel_gem_bo_unmap_gtt(xvmc_driver->batch.buf); + if (xvmc_driver->batch.buf == NULL) + return; drm_intel_bo_unreference(xvmc_driver->batch.buf); } -void intelFlushBatch(Bool refill) +void intelFlushBatch(void) { - i965_end_batch(); + dri_bo *bo; - drm_intel_gem_bo_unmap_gtt(xvmc_driver->batch.buf); + i965_end_batch(); drm_intel_bo_exec(xvmc_driver->batch.buf, xvmc_driver->batch.ptr - xvmc_driver->batch.init_ptr, 0, 0, 0); - drm_intel_bo_unreference(xvmc_driver->batch.buf); - if ((xvmc_driver->batch.buf = - drm_intel_bo_alloc(xvmc_driver->bufmgr, - "batch buffer", BATCH_SIZE, 0x1000)) == NULL) { - fprintf(stderr, "unable to alloc batch buffer\n"); + bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, + "batch buffer", BATCH_SIZE, 0x1000); + if (bo != NULL && drm_intel_gem_bo_map_gtt(bo) == 0) { + drm_intel_bo_unreference(xvmc_driver->batch.buf); + xvmc_driver->batch.buf = bo; + } else { + if (bo != NULL) + drm_intel_bo_unreference(bo); + drm_intel_gem_bo_map_gtt(xvmc_driver->batch.buf); } - drm_intel_gem_bo_map_gtt(xvmc_driver->batch.buf); - - xvmc_driver->batch.init_ptr = xvmc_driver->batch.buf->virtual; - xvmc_driver->batch.size = BATCH_SIZE; - xvmc_driver->batch.space = BATCH_SIZE; - xvmc_driver->batch.ptr = xvmc_driver->batch.init_ptr; -} - -void intelBatchbufferRequireSpace(int size) -{ - assert(xvmc_driver->batch.ptr - xvmc_driver->batch.init_ptr + size < - xvmc_driver->batch.size - 8); - if (xvmc_driver->batch.ptr - xvmc_driver->batch.init_ptr + size - >= xvmc_driver->batch.size - 8) - intelFlushBatch(1); + reset_batch(); } void intelBatchbufferData(const void *data, unsigned bytes, unsigned flags) { - intelBatchbufferRequireSpace(bytes); + assert(bytes <= xvmc_driver->batch.space); memcpy(xvmc_driver->batch.ptr, data, bytes); xvmc_driver->batch.ptr += bytes; xvmc_driver->batch.space -= bytes; diff --git a/xvmc/intel_batchbuffer.h b/xvmc/intel_batchbuffer.h index 7fae6f7d..c63ee5ef 100644 --- a/xvmc/intel_batchbuffer.h +++ b/xvmc/intel_batchbuffer.h @@ -11,8 +11,6 @@ extern int VERBOSE; #define BEGIN_BATCH(n) \ do { \ assert(xvmc_driver->batch.space >= (n) *4); \ - if (xvmc_driver->batch.space < (n)*4) \ - intelFlushBatch(TRUE); \ batch_ptr = xvmc_driver->batch.ptr; \ } while (0) @@ -46,7 +44,7 @@ extern int VERBOSE; xvmc_driver->batch.ptr = batch_ptr; \ } while(0) -extern void intelFlushBatch(Bool); +extern void intelFlushBatch(void); extern void intelBatchbufferData(const void *, unsigned, unsigned); extern Bool intelInitBatchBuffer(void); extern void intelFiniBatchBuffer(void); diff --git a/xvmc/intel_xvmc.c b/xvmc/intel_xvmc.c index ff13d03c..2a2c8b9a 100644 --- a/xvmc/intel_xvmc.c +++ b/xvmc/intel_xvmc.c @@ -313,6 +313,16 @@ _X_EXPORT Status XvMCCreateContext(Display * display, XvPortID port, } drm_intel_bufmgr_gem_enable_reuse(xvmc_driver->bufmgr); + if (!intelInitBatchBuffer()) { + XFree(priv_data); + context->privData = NULL; + + dri_bufmgr_destroy(xvmc_driver->bufmgr); + xvmc_driver = NULL; + + return BadAlloc; + } + /* call driver hook. * driver hook should free priv_data after return if success.*/ ret = @@ -320,14 +330,18 @@ _X_EXPORT Status XvMCCreateContext(Display * display, XvPortID port, priv_data); if (ret) { XVMC_ERR("driver create context failed\n"); + intelFiniBatchBuffer(); + XFree(priv_data); context->privData = NULL; + + dri_bufmgr_destroy(xvmc_driver->bufmgr); xvmc_driver = NULL; return ret; } + pthread_mutex_init(&xvmc_driver->ctxmutex, NULL); - intelInitBatchBuffer(); intel_xvmc_dump_open(); return Success; diff --git a/xvmc/xvmc_vld.c b/xvmc/xvmc_vld.c index e5762941..4c684ff1 100644 --- a/xvmc/xvmc_vld.c +++ b/xvmc/xvmc_vld.c @@ -1010,7 +1010,7 @@ static Status put_slice2(Display * display, XvMCContext * context, cs_buffer(); vld_send_media_object(media_state.slice_data.bo, nbytes, 0, mb_row, 6, 127, q_scale_code); - intelFlushBatch(TRUE); + intelFlushBatch(); UNLOCK_HARDWARE(intel_ctx->hw_context); return Success; @@ -1207,7 +1207,7 @@ static Status render_surface(Display * display, } } } - intelFlushBatch(TRUE); + intelFlushBatch(); UNLOCK_HARDWARE(intel_ctx->hw_context); return Success; } |