* [PATCH] drm/nouveau: fix lockdep splat in display
@ 2013-02-05 10:29 Maarten Lankhorst
0 siblings, 0 replies; only message in thread
From: Maarten Lankhorst @ 2013-02-05 10:29 UTC (permalink / raw)
To: Ben Skeggs
Cc: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
Add a flag NVOBJ_FLAG_CREAT_EXCL, which will make sure that only 1 engctx will be created.
This removes the need of having multiple
Fixes the following lockdep splat:
=============================================
[ INFO: possible recursive locking detected ]
3.8.0-rc6-ninja+ #1 Not tainted
---------------------------------------------
modprobe/585 is trying to acquire lock:
(&subdev->mutex){+.+.+.}, at: [<ffffffffa016c323>]
nouveau_instobj_create_+0x43/0x90 [nouveau]
but task is already holding lock:
(&subdev->mutex){+.+.+.}, at: [<ffffffffa017672d>]
nv50_disp_data_ctor+0x5d/0xd0 [nouveau]
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
----
lock(&subdev->mutex);
lock(&subdev->mutex);
*** DEADLOCK ***
May be due to missing lock nesting notation
4 locks held by modprobe/585:
#0: (&__lockdep_no_validate__){......}, at: [<ffffffff813075f3>]
__driver_attach+0x53/0xb0
#1: (&__lockdep_no_validate__){......}, at: [<ffffffff81307601>]
__driver_attach+0x61/0xb0
#2: (drm_global_mutex){+.+.+.}, at: [<ffffffff812ee59c>]
drm_get_pci_dev+0xbc/0x2b0
#3: (&subdev->mutex){+.+.+.}, at: [<ffffffffa017672d>]
nv50_disp_data_ctor+0x5d/0xd0 [nouveau]
stack backtrace:
Pid: 585, comm: modprobe Not tainted 3.8.0-rc6-expert+ #1
Call Trace:
[<ffffffff8108fde2>] validate_chain.isra.33+0xd72/0x10d0
[<ffffffff8105fa08>] ? __kernel_text_address+0x58/0x80
[<ffffffff8100575d>] ? print_context_stack+0x5d/0xd0
[<ffffffff81090bc1>] __lock_acquire+0x3a1/0xb60
[<ffffffff8108d504>] ? __lock_is_held+0x54/0x80
[<ffffffff8109184a>] lock_acquire+0x5a/0x70
[<ffffffffa016c323>] ? nouveau_instobj_create_+0x43/0x90 [nouveau]
[<ffffffff81558739>] mutex_lock_nested+0x69/0x340
[<ffffffffa016c323>] ? nouveau_instobj_create_+0x43/0x90 [nouveau]
[<ffffffffa0152370>] ? nouveau_object_create_+0x60/0xa0 [nouveau]
[<ffffffffa016c323>] nouveau_instobj_create_+0x43/0x90 [nouveau]
[<ffffffffa016cf8c>] nv50_instobj_ctor+0x4c/0xf0 [nouveau]
[<ffffffffa0152163>] nouveau_object_ctor+0x33/0xc0 [nouveau]
[<ffffffffa016cd51>] nv50_instmem_alloc+0x21/0x30 [nouveau]
[<ffffffffa0150917>] nouveau_gpuobj_create_+0x247/0x2f0 [nouveau]
[<ffffffff8155b35a>] ? _raw_spin_unlock_irqrestore+0x3a/0x70
[<ffffffff810921fd>] ? trace_hardirqs_on_caller+0x10d/0x1a0
[<ffffffffa014f4bc>] nouveau_engctx_create_+0x25c/0x2a0 [nouveau]
[<ffffffffa0176791>] nv50_disp_data_ctor+0xc1/0xd0 [nouveau]
[<ffffffffa0153722>] ? nouveau_subdev_reset+0x52/0x60 [nouveau]
[<ffffffffa0152163>] nouveau_object_ctor+0x33/0xc0 [nouveau]
[<ffffffffa0152a42>] nouveau_object_new+0x112/0x240 [nouveau]
[<ffffffffa01f4b1d>] nv50_display_create+0x18d/0x860 [nouveau]
[<ffffffff8105cb5d>] ? __cancel_work_timer+0x6d/0xc0
[<ffffffffa01db8eb>] nouveau_display_create+0x3cb/0x670 [nouveau]
[<ffffffffa01cb1bf>] nouveau_drm_load+0x26f/0x590 [nouveau]
[<ffffffff81304c99>] ? device_register+0x19/0x20
[<ffffffff812efe91>] ? drm_sysfs_device_add+0x81/0xb0
[<ffffffff812ee65e>] drm_get_pci_dev+0x17e/0x2b0
[<ffffffff81245e56>] ? __pci_set_master+0x26/0x80
[<ffffffffa01cab2a>] nouveau_drm_probe+0x25a/0x2a0 [nouveau]
[<ffffffff8124a386>] local_pci_probe+0x46/0x80
[<ffffffff8124ac11>] pci_device_probe+0x101/0x110
[<ffffffff813073d6>] driver_probe_device+0x76/0x240
[<ffffffff81307643>] __driver_attach+0xa3/0xb0
[<ffffffff813075a0>] ? driver_probe_device+0x240/0x240
[<ffffffff8130564d>] bus_for_each_dev+0x4d/0x90
[<ffffffff81306f39>] driver_attach+0x19/0x20
[<ffffffff81306af0>] bus_add_driver+0x1a0/0x270
[<ffffffffa023d000>] ? 0xffffffffa023cfff
[<ffffffff81307cd2>] driver_register+0x72/0x170
[<ffffffffa023d000>] ? 0xffffffffa023cfff
[<ffffffff8124ad0f>] __pci_register_driver+0x5f/0x70
[<ffffffff812ee8a5>] drm_pci_init+0x115/0x130
[<ffffffffa023d000>] ? 0xffffffffa023cfff
[<ffffffffa023d000>] ? 0xffffffffa023cfff
[<ffffffffa023d04d>] nouveau_drm_init+0x4d/0x1000 [nouveau]
[<ffffffff810002da>] do_one_initcall+0x11a/0x170
[<ffffffff8109d044>] load_module+0xe84/0x1470
[<ffffffff81098c30>] ? in_lock_functions+0x20/0x20
[<ffffffff8122c22e>] ? trace_hardirqs_on_thunk+0x3a/0x3f
[<ffffffff8109d6e7>] sys_init_module+0xb7/0xe0
[<ffffffff8155c156>] system_call_fastpath+0x1a/0x1f
Reported-by: Arend van Spriel <arend-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
Reported-by: Peter Hurley <peter-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8@public.gmane.org>
Reported-by: Daniel J Blueman <daniel-JCXMqzvhRcvYtjvyW6yDsg@public.gmane.org>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
---
XXX: Add Cc: stable-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org if it applies to 3.7 ?
diff --git a/drivers/gpu/drm/nouveau/core/core/engctx.c b/drivers/gpu/drm/nouveau/core/core/engctx.c
index 84c71fa..4a0ab2b 100644
--- a/drivers/gpu/drm/nouveau/core/core/engctx.c
+++ b/drivers/gpu/drm/nouveau/core/core/engctx.c
@@ -31,12 +31,15 @@
#include <subdev/vm.h>
static inline int
-nouveau_engctx_exists(struct nouveau_object *parent,
+nouveau_engctx_exists(struct nouveau_object *parent, u32 flags,
struct nouveau_engine *engine, void **pobject)
{
struct nouveau_engctx *engctx;
struct nouveau_object *parctx;
+ if ((flags & NVOBJ_FLAG_CREAT_EXCL) && !list_empty(&engine->contexts))
+ return -EBUSY;
+
list_for_each_entry(engctx, &engine->contexts, head) {
parctx = nv_pclass(nv_object(engctx), NV_PARENT_CLASS);
if (parctx == parent) {
@@ -67,7 +70,7 @@ nouveau_engctx_create_(struct nouveau_object *parent,
* and reference it instead of creating a new one
*/
spin_lock_irqsave(&engine->lock, save);
- ret = nouveau_engctx_exists(parent, engine, pobject);
+ ret = nouveau_engctx_exists(parent, flags, engine, pobject);
spin_unlock_irqrestore(&engine->lock, save);
if (ret)
return ret;
@@ -94,7 +97,7 @@ nouveau_engctx_create_(struct nouveau_object *parent,
* it's not possible to allocate the object with it held.
*/
spin_lock_irqsave(&engine->lock, save);
- ret = nouveau_engctx_exists(parent, engine, pobject);
+ ret = nouveau_engctx_exists(parent, flags, engine, pobject);
if (ret) {
spin_unlock_irqrestore(&engine->lock, save);
nouveau_object_ref(NULL, &engctx);
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
index ca1a7d7..1d3dcd0 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
@@ -695,9 +695,8 @@ nv50_disp_data_ctor(struct nouveau_object *parent,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
- struct nv50_disp_priv *priv = (void *)engine;
struct nouveau_engctx *ectx;
- int ret = -EBUSY;
+ int ret;
/* no context needed for channel objects... */
if (nv_mclass(parent) != NV_DEVICE_CLASS) {
@@ -707,14 +706,10 @@ nv50_disp_data_ctor(struct nouveau_object *parent,
}
/* allocate display hardware to client */
- mutex_lock(&nv_subdev(priv)->mutex);
- if (list_empty(&nv_engine(priv)->contexts)) {
- ret = nouveau_engctx_create(parent, engine, oclass, NULL,
- 0x10000, 0x10000,
- NVOBJ_FLAG_HEAP, &ectx);
- *pobject = nv_object(ectx);
- }
- mutex_unlock(&nv_subdev(priv)->mutex);
+ ret = nouveau_engctx_create(parent, engine, oclass, NULL, 0x10000, 0x10000,
+ NVOBJ_FLAG_HEAP | NVOBJ_FLAG_CREAT_EXCL, &ectx);
+
+ *pobject = nv_object(ectx);
return ret;
}
diff --git a/drivers/gpu/drm/nouveau/core/include/core/gpuobj.h b/drivers/gpu/drm/nouveau/core/include/core/gpuobj.h
index b3b9ce4..9d47d51 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/gpuobj.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/gpuobj.h
@@ -12,6 +12,7 @@ struct nouveau_vm;
#define NVOBJ_FLAG_ZERO_ALLOC 0x00000001
#define NVOBJ_FLAG_ZERO_FREE 0x00000002
#define NVOBJ_FLAG_HEAP 0x00000004
+#define NVOBJ_FLAG_CREAT_EXCL 0x00000008
struct nouveau_gpuobj {
struct nouveau_object base;
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2013-02-05 10:29 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-02-05 10:29 [PATCH] drm/nouveau: fix lockdep splat in display Maarten Lankhorst
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.