Skip to contentSkip to conversation

drm/nouveau: fix nouveau_mm/nouveau_mm_node leak

PATCH Superseded Marcin Slusarz 2 participants 7 messages Oct 11, 2012 – Oct 21, 2012 3 messages not in the archive

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 drm/nouveau: fix nouveau_mm/nouveau_mm_node leak

---
 drivers/gpu/drm/nouveau/core/core/gpuobj.c         | 6 +++++-
 drivers/gpu/drm/nouveau/core/include/core/gpuobj.h | 3 +++
 2 files changed, 8 insertions(+), 1 deletion(-)
drivers/gpu/drm/nouveau/core/core/gpuobj.c +5 -1
index c2a7608..48121d2 100644
@@ -39,8 +39,11 @@ nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj)
 			nv_wo32(gpuobj, i, 0x00000000);
 	}
 
+	if (gpuobj->node)
+		nouveau_mm_free(gpuobj->node_heap, &gpuobj->node);
+
 	if (gpuobj->heap.block_size)
-		nouveau_mm_fini(&gpuobj->heap);
+		WARN_ON(nouveau_mm_fini(&gpuobj->heap));
 
 	nouveau_object_destroy(&gpuobj->base);
 }
@@ -114,6 +117,7 @@ nouveau_gpuobj_create_(struct nouveau_object *parent,
 				      max(align, (u32)1), &gpuobj->node);
 		if (ret)
 			return ret;
+		gpuobj->node_heap = heap;
 
 		gpuobj->addr += gpuobj->node->offset;
 	}
drivers/gpu/drm/nouveau/core/include/core/gpuobj.h +3 -0
index d09adf1..f65bf5b 100644
@@ -16,7 +16,10 @@ struct nouveau_vm;
 struct nouveau_gpuobj {
 	struct nouveau_object base;
 	struct nouveau_object *parent;
+
+	struct nouveau_mm *node_heap;
 	struct nouveau_mm_node *node;
+
 	struct nouveau_mm heap;
 
 	u32 flags;
Signature · 1 line
1.7.12

A message that is not in the archive (sent off-list or not yet received): [email protected]

#2 lore raw
Quoted 37 lines · Marcin Slusarz
---
 drivers/gpu/drm/nouveau/core/core/gpuobj.c         | 6 +++++-
 drivers/gpu/drm/nouveau/core/include/core/gpuobj.h | 3 +++
 2 files changed, 8 insertions(+), 1 deletion(-)
drivers/gpu/drm/nouveau/core/core/gpuobj.c +5 -1
index c2a7608..48121d2 100644
@@ -39,8 +39,11 @@ nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj)
 			nv_wo32(gpuobj, i, 0x00000000);
 	}
 
+	if (gpuobj->node)
+		nouveau_mm_free(gpuobj->node_heap, &gpuobj->node);
+
 	if (gpuobj->heap.block_size)
-		nouveau_mm_fini(&gpuobj->heap);
+		WARN_ON(nouveau_mm_fini(&gpuobj->heap));
 
 	nouveau_object_destroy(&gpuobj->base);
 }
@@ -114,6 +117,7 @@ nouveau_gpuobj_create_(struct nouveau_object *parent,
 				      max(align, (u32)1), &gpuobj->node);
 		if (ret)
 			return ret;
+		gpuobj->node_heap = heap;
 
 		gpuobj->addr += gpuobj->node->offset;
 	}
drivers/gpu/drm/nouveau/core/include/core/gpuobj.h +0 -0
index d09adf1..f65bf5b 100644

drivers/gpu/drm/nouveau/core/include/core/gpuobj.h struct nouveau_vm; · line 25

Quoted 10 lines
drivers/gpu/drm/nouveau/core/include/core/gpuobj.h +3 -0
@@ -16,7 +16,10 @@ struct nouveau_vm;
 struct nouveau_gpuobj {
 	struct nouveau_object base;
 	struct nouveau_object *parent;
+
+	struct nouveau_mm *node_heap;
 	struct nouveau_mm_node *node;
+
 	struct nouveau_mm heap;
 
 	u32 flags;

What's wrong with this patch?

#3 lore raw
In reply to a message not in the archive
Quoted 11 lines · Marcin Slusarz
---
 drivers/gpu/drm/nouveau/core/core/gpuobj.c         | 6 +++++-
 drivers/gpu/drm/nouveau/core/include/core/gpuobj.h | 3 +++
 2 files changed, 8 insertions(+), 1 deletion(-)
drivers/gpu/drm/nouveau/core/core/gpuobj.c +0 -0
index c2a7608..48121d2 100644

drivers/gpu/drm/nouveau/core/core/gpuobj.c nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj) · line 44

Quoted 6 lines
drivers/gpu/drm/nouveau/core/core/gpuobj.c +3 -0
@@ -39,8 +39,11 @@ nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj)
 			nv_wo32(gpuobj, i, 0x00000000);
 	}
 
+	if (gpuobj->node)
+		nouveau_mm_free(gpuobj->node_heap, &gpuobj->node);
+
if (gpuobj->node) {
	nouveau_mm_free(&nv_gpuobj(gpuobj->parent)->heap,
			&gpuobj->node);
}

Or something to that effect, instead of having to store the heap pointer again.

drivers/gpu/drm/nouveau/core/core/gpuobj.c nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj) · line 46

Quoted 3 lines
drivers/gpu/drm/nouveau/core/core/gpuobj.c +1 -1
 	if (gpuobj->heap.block_size)
-		nouveau_mm_fini(&gpuobj->heap);
+		WARN_ON(nouveau_mm_fini(&gpuobj->heap));

Alright, I get this. However, perhaps we should go the full hog here and make nouveau_mm_fini() directly do the WARN_ON() in this situation?

There was, once upon a time, reasons for it not doing this, I don't believe they're valid anymore though.

If you want to do this, that'd be great. Bonus points for being in a separate patch :)

Quoted 33 lines
drivers/gpu/drm/nouveau/core/core/gpuobj.c +1 -0
 	nouveau_object_destroy(&gpuobj->base);
 }
@@ -114,6 +117,7 @@ nouveau_gpuobj_create_(struct nouveau_object *parent,
 				      max(align, (u32)1), &gpuobj->node);
 		if (ret)
 			return ret;
+		gpuobj->node_heap = heap;
 
 		gpuobj->addr += gpuobj->node->offset;
 	}
drivers/gpu/drm/nouveau/core/include/core/gpuobj.h +3 -0
index d09adf1..f65bf5b 100644
@@ -16,7 +16,10 @@ struct nouveau_vm;
 struct nouveau_gpuobj {
 	struct nouveau_object base;
 	struct nouveau_object *parent;
+
+	struct nouveau_mm *node_heap;
 	struct nouveau_mm_node *node;
+
 	struct nouveau_mm heap;
 
 	u32 flags;
Signature · 6 lines
1.7.12

_______________________________________________
Nouveau mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/nouveau

A message that is not in the archive (sent off-list or not yet received): 20121019060514.GA11173-6RkuLLNOGXsZ315U/[email protected]

#5 lore raw
Quoted 23 lines · Ben Skeggs
Quoted 11 lines · Marcin Slusarz
---
 drivers/gpu/drm/nouveau/core/core/gpuobj.c         | 6 +++++-
 drivers/gpu/drm/nouveau/core/include/core/gpuobj.h | 3 +++
 2 files changed, 8 insertions(+), 1 deletion(-)
drivers/gpu/drm/nouveau/core/core/gpuobj.c +0 -0
index c2a7608..48121d2 100644

drivers/gpu/drm/nouveau/core/core/gpuobj.c nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj) · line 44

Quoted 6 lines
drivers/gpu/drm/nouveau/core/core/gpuobj.c +3 -0
@@ -39,8 +39,11 @@ nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj)
 			nv_wo32(gpuobj, i, 0x00000000);
 	}
 
+	if (gpuobj->node)
+		nouveau_mm_free(gpuobj->node_heap, &gpuobj->node);
+
if (gpuobj->node) {
	nouveau_mm_free(&nv_gpuobj(gpuobj->parent)->heap,
			&gpuobj->node);
}
Quoted 2 lines

Or something to that effect, instead of having to store the heap pointer again.

Oh, right.
(Somehow I assumed pargpu to be different object than parent when I first read it.)

Quoted 8 lines

drivers/gpu/drm/nouveau/core/core/gpuobj.c nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj) · line 46

Quoted 3 lines
drivers/gpu/drm/nouveau/core/core/gpuobj.c +1 -1
 	if (gpuobj->heap.block_size)
-		nouveau_mm_fini(&gpuobj->heap);
+		WARN_ON(nouveau_mm_fini(&gpuobj->heap));

Alright, I get this. However, perhaps we should go the full hog here and make nouveau_mm_fini() directly do the WARN_ON() in this situation?

There was, once upon a time, reasons for it not doing this, I don't believe they're valid anymore though.

OK.

Marcin

A message that is not in the archive (sent off-list or not yet received): [email protected]

#7 lore raw
Quoted 24 lines · Marcin Slusarz
Quoted 23 lines · Ben Skeggs
Quoted 11 lines · Marcin Slusarz
---
 drivers/gpu/drm/nouveau/core/core/gpuobj.c         | 6 +++++-
 drivers/gpu/drm/nouveau/core/include/core/gpuobj.h | 3 +++
 2 files changed, 8 insertions(+), 1 deletion(-)
drivers/gpu/drm/nouveau/core/core/gpuobj.c +0 -0
index c2a7608..48121d2 100644

drivers/gpu/drm/nouveau/core/core/gpuobj.c nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj) · line 44

Quoted 6 lines
drivers/gpu/drm/nouveau/core/core/gpuobj.c +3 -0
@@ -39,8 +39,11 @@ nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj)
 			nv_wo32(gpuobj, i, 0x00000000);
 	}
 
+	if (gpuobj->node)
+		nouveau_mm_free(gpuobj->node_heap, &gpuobj->node);
+
if (gpuobj->node) {
	nouveau_mm_free(&nv_gpuobj(gpuobj->parent)->heap,
			&gpuobj->node);
}
Quoted 2 lines
Quoted 2 lines

Or something to that effect, instead of having to store the heap pointer again.

Thanks, merged both patches :)

Quoted 17 lines

Oh, right.
(Somehow I assumed pargpu to be different object than parent when I first read it.)

Quoted 8 lines

drivers/gpu/drm/nouveau/core/core/gpuobj.c nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj) · line 46

Quoted 3 lines
drivers/gpu/drm/nouveau/core/core/gpuobj.c +1 -1
 	if (gpuobj->heap.block_size)
-		nouveau_mm_fini(&gpuobj->heap);
+		WARN_ON(nouveau_mm_fini(&gpuobj->heap));

Alright, I get this. However, perhaps we should go the full hog here and make nouveau_mm_fini() directly do the WARN_ON() in this situation?

There was, once upon a time, reasons for it not doing this, I don't believe they're valid anymore though.

OK.

Marcin

#8 lore raw

PATCH v2 1/1 drm/nouveau: fix nouveau_mm/nouveau_mm_node leak

In reply to a message not in the archive

v2: use already existing parent

---
 drivers/gpu/drm/nouveau/core/core/gpuobj.c | 5 +++++
 1 file changed, 5 insertions(+)
drivers/gpu/drm/nouveau/core/core/gpuobj.c +5 -0
index c2a7608..18b3f5c 100644
@@ -39,6 +39,11 @@ nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj)
 			nv_wo32(gpuobj, i, 0x00000000);
 	}
 
+	if (gpuobj->node) {
+		nouveau_mm_free(&nv_gpuobj(gpuobj->parent)->heap,
+				&gpuobj->node);
+	}
+
 	if (gpuobj->heap.block_size)
 		nouveau_mm_fini(&gpuobj->heap);
 
Signature · 1 line
1.7.12
#9 lore raw

PATCH 1/1 drm/nouveau: warn when trying to free mm which is still in use

In reply to a message not in the archive
---
 drivers/gpu/drm/nouveau/core/core/mm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/nouveau/core/core/mm.c +1 -1
index bfddf87..4d62064 100644
@@ -236,7 +236,7 @@ nouveau_mm_fini(struct nouveau_mm *mm)
 	int nodes = 0;
 
 	list_for_each_entry(node, &mm->nodes, nl_entry) {
-		if (nodes++ == mm->heap_nodes)
+		if (WARN_ON(nodes++ == mm->heap_nodes))
 			return -EBUSY;
 	}
 
Signature · 1 line
1.7.12