drm/radeon/kms: fix r600/r700 cs checker to avoid double kfree
authorJerome Glisse <jglisse@redhat.com>
Thu, 11 Feb 2010 11:44:32 +0000 (12:44 +0100)
committerDave Airlie <airlied@redhat.com>
Thu, 11 Feb 2010 20:48:33 +0000 (06:48 +1000)
radeon_cs kfree the tracker structure but for r6xx/r7xx we want
to kfree it inside the parse function because we share it with
the UMS code path. Set tracker to NULL after freeing it will
avoid double free.

Signed-off-by: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/radeon/r600_cs.c

index ac67d6488a95be42d147842f2f70ae8675940ffc..00e69c585fbf4e2dbcb29daddf08782fd27eb53a 100644 (file)
@@ -846,9 +846,9 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
                                        "0x%04X\n", reg);
                        return -EINVAL;
                }
+               tmp = (reg - CB_COLOR0_BASE) / 4;
                track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx);
                ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
-               tmp = (reg - CB_COLOR0_BASE) / 4;
                track->cb_color_base_last[tmp] = ib[idx];
                track->cb_color_bo[tmp] = reloc->robj;
                break;
@@ -1324,6 +1324,8 @@ int r600_cs_parse(struct radeon_cs_parser *p)
        do {
                r = r600_cs_packet_parse(p, &pkt, p->idx);
                if (r) {
+                       kfree(p->track);
+                       p->track = NULL;
                        return r;
                }
                p->idx += pkt.count + 2;
@@ -1339,10 +1341,12 @@ int r600_cs_parse(struct radeon_cs_parser *p)
                default:
                        DRM_ERROR("Unknown packet type %d !\n", pkt.type);
                        kfree(p->track);
+                       p->track = NULL;
                        return -EINVAL;
                }
                if (r) {
                        kfree(p->track);
+                       p->track = NULL;
                        return r;
                }
        } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
@@ -1353,6 +1357,7 @@ int r600_cs_parse(struct radeon_cs_parser *p)
        }
 #endif
        kfree(p->track);
+       p->track = NULL;
        return 0;
 }