summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-10-09 23:54:57 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2013-10-10 00:00:46 +0100
commitb16999da214803a026d7246ec4aa62031e82dfc8 (patch)
treea97e6e0e0b8eddbc3ad2a936dbe88d7078987798
parentb9ad5b625e8935a3c115760bdd4738d4432542e3 (diff)
sna: Upon unwinding operations, also check for exec objects to clear
If we cancel an operation after partially committing it, we may leave the batch bookkeeping in an inconsistent state with an exec object with a zero-length batch. Ordinarily, this would not be an issue as we could pass the extra object to the next batch. However, if we switch rings, we need to clear the extra objects as they are currently flagged as being on the wrong ring, leading to hilarity. Reported-by: Jiri Slaby <jirislaby@gmail.com> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/gen6_render.c11
-rw-r--r--src/sna/gen7_render.c12
2 files changed, 20 insertions, 3 deletions
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index ee1686fc..401041c2 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -3622,10 +3622,19 @@ gen6_render_context_switch(struct kgem *kgem,
int new_mode)
{
if (kgem->nbatch) {
- DBG(("%s: from %d to %d\n", __FUNCTION__, kgem->mode, new_mode));
+ DBG(("%s: from %d to %d, submit batch\n", __FUNCTION__, kgem->mode, new_mode));
_kgem_submit(kgem);
}
+ if (kgem->nexec) {
+ DBG(("%s: from %d to %d, reset incomplete batch\n", __FUNCTION__, kgem->mode, new_mode));
+ kgem_reset(kgem);
+ }
+
+ assert(kgem->nbatch == 0);
+ assert(kgem->nreloc == 0);
+ assert(kgem->nexec == 0);
+
kgem->ring = new_mode;
}
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 30e1cc1b..e17fc949 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -3844,11 +3844,19 @@ gen7_render_context_switch(struct kgem *kgem,
int new_mode)
{
if (kgem->nbatch) {
- DBG(("%s: switch rings %d -> %d\n",
- __FUNCTION__, kgem->mode, new_mode));
+ DBG(("%s: from %d to %d, submit batch\n", __FUNCTION__, kgem->mode, new_mode));
_kgem_submit(kgem);
}
+ if (kgem->nexec) {
+ DBG(("%s: from %d to %d, reset incomplete batch\n", __FUNCTION__, kgem->mode, new_mode));
+ kgem_reset(kgem);
+ }
+
+ assert(kgem->nbatch == 0);
+ assert(kgem->nreloc == 0);
+ assert(kgem->nexec == 0);
+
kgem->ring = new_mode;
}