From mboxrd@z Thu Jan 1 00:00:00 1970 From: Marcin Slusarz Subject: deadlock possiblity introduced by "drm/nouveau: use drm_mm in preference to custom code doing the same thing" Date: Sun, 11 Jul 2010 01:24:32 +0200 Message-ID: <20100710232432.GA4137@joi.lan> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Content-Disposition: inline List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dri-devel-bounces+sf-dri-devel=m.gmane.org@lists.freedesktop.org Errors-To: dri-devel-bounces+sf-dri-devel=m.gmane.org@lists.freedesktop.org To: Ben Skeggs Cc: nouveau@lists.freedesktop.org, dri-devel@lists.freedesktop.org, Dave Airlie List-Id: nouveau.vger.kernel.org Hi Patch "drm/nouveau: use drm_mm in preference to custom code doing the same thing" in nouveau tree introduced new deadlock possibility, for which lockdep complains loudly: [ 1541.070202] [drm] nouveau 0000:02:00.0: Allocating FIFO number 3 [ 1541.084772] [drm] nouveau 0000:02:00.0: nouveau_channel_alloc: initialised FIFO 3 [ 2417.733440] [drm] nouveau 0000:02:00.0: nouveau_channel_free: freeing fifo 3 [ 2417.746638] [ 2417.746639] ====================================================== [ 2417.746642] [ INFO: HARDIRQ-safe -> HARDIRQ-unsafe lock order detected ] [ 2417.746644] 2.6.35-rc4-nv+ #379 [ 2417.746645] ------------------------------------------------------ [ 2417.746648] warsow/2850 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire: [ 2417.746650] (&(&mm->unused_lock)->rlock){+.+...}, at: [] drm_mm_put_block+0x17a/0x1c0 [ 2417.746657] [ 2417.746658] and this task is already holding: [ 2417.746659] (&(&dev_priv->context_switch_lock)->rlock){-.....}, at: [] nouveau_channel_free+0x10f/0x233 [nouveau] [ 2417.746669] which would create a new lock dependency: [ 2417.746671] (&(&dev_priv->context_switch_lock)->rlock){-.....} -> (&(&mm->unused_lock)->rlock){+.+...} [ 2417.746676] [ 2417.746676] but this new dependency connects a HARDIRQ-irq-safe lock: [ 2417.746678] (&(&dev_priv->context_switch_lock)->rlock){-.....} [ 2417.746680] ... which became HARDIRQ-irq-safe at: [ 2417.746682] [] __lock_acquire+0x671/0x8f4 [ 2417.746685] [] lock_acquire+0x148/0x18d [ 2417.746688] [] _raw_spin_lock_irqsave+0x41/0x53 [ 2417.746692] [] nouveau_irq_handler+0x56/0xa48 [nouveau] [ 2417.746698] [] handle_IRQ_event+0xec/0x25d [ 2417.746702] [] handle_fasteoi_irq+0x92/0xd2 [ 2417.746705] [] handle_irq+0x83/0x8c [ 2417.746707] [] do_IRQ+0x57/0xbe [ 2417.746711] [] ret_from_intr+0x0/0xf [ 2417.746714] [] cpu_idle+0x5c/0xb3 [ 2417.746717] [] start_secondary+0x1c7/0x1cb [ 2417.746720] [ 2417.746720] to a HARDIRQ-irq-unsafe lock: [ 2417.746722] (&(&mm->unused_lock)->rlock){+.+...} [ 2417.746724] ... which became HARDIRQ-irq-unsafe at: [ 2417.746725] ... [] __lock_acquire+0x6eb/0x8f4 [ 2417.746729] [] lock_acquire+0x148/0x18d [ 2417.746732] [] _raw_spin_lock+0x36/0x45 [ 2417.746735] [] drm_mm_pre_get+0x20/0x1a7 [ 2417.746738] [] ttm_bo_init+0x234/0x385 [ttm] [ 2417.746743] [] nouveau_bo_new+0x366/0x3eb [nouveau] [ 2417.746750] [] nouveau_mem_init+0x262/0x44a [nouveau] [ 2417.746756] [] nouveau_card_init+0xa73/0xd7e [nouveau] [ 2417.746761] [] nouveau_load+0x6ba/0x70a [nouveau] [ 2417.746766] [] drm_get_dev+0x470/0x5a1 [ 2417.746769] [] nouveau_pci_probe+0x10/0x12 [nouveau] [ 2417.746778] [] local_pci_probe+0x12/0x16 [ 2417.746781] [] pci_device_probe+0x60/0x8f [ 2417.746784] [] driver_probe_device+0xa7/0x136 [ 2417.746788] [] __driver_attach+0x5c/0x80 [ 2417.746790] [] bus_for_each_dev+0x54/0x89 [ 2417.746793] [] driver_attach+0x19/0x1b [ 2417.746796] [] bus_add_driver+0x183/0x2ef [ 2417.746799] [] driver_register+0x98/0x109 [ 2417.746801] [] __pci_register_driver+0x63/0xd3 [ 2417.746805] [] drm_init+0x6b/0xd1 [ 2417.746807] [] 0xffffffffa0128048 [ 2417.746810] [] do_one_initcall+0x59/0x14e [ 2417.746814] [] sys_init_module+0x9c/0x1dd [ 2417.746817] [] system_call_fastpath+0x16/0x1b [ 2417.746820] [ 2417.746820] other info that might help us debug this: [ 2417.746821] [ 2417.746823] 1 lock held by warsow/2850: [ 2417.746824] #0: (&(&dev_priv->context_switch_lock)->rlock){-.....}, at: [] nouveau_channel_free+0x10f/0x233 [nouveau] [ 2417.746833] [ 2417.746833] the dependencies between HARDIRQ-irq-safe lock and the holding lock: [ 2417.746841] -> (&(&dev_priv->context_switch_lock)->rlock){-.....} ops: 18 { [ 2417.746845] IN-HARDIRQ-W at: [ 2417.746847] [] __lock_acquire+0x671/0x8f4 [ 2417.746851] [] lock_acquire+0x148/0x18d [ 2417.746854] [] _raw_spin_lock_irqsave+0x41/0x53 [ 2417.746858] [] nouveau_irq_handler+0x56/0xa48 [nouveau] [ 2417.746865] [] handle_IRQ_event+0xec/0x25d [ 2417.746868] [] handle_fasteoi_irq+0x92/0xd2 [ 2417.746871] [] handle_irq+0x83/0x8c [ 2417.746874] [] do_IRQ+0x57/0xbe [ 2417.746878] [] ret_from_intr+0x0/0xf [ 2417.746881] [] cpu_idle+0x5c/0xb3 [ 2417.746885] [] start_secondary+0x1c7/0x1cb [ 2417.746888] INITIAL USE at: [ 2417.746890] [] __lock_acquire+0x767/0x8f4 [ 2417.746893] [] lock_acquire+0x148/0x18d [ 2417.746897] [] _raw_spin_lock_irqsave+0x41/0x53 [ 2417.746900] [] nv50_fifo_create_context+0x17d/0x485 [nouveau] [ 2417.746910] [] nouveau_channel_alloc+0x5c7/0x693 [nouveau] [ 2417.746915] [] nouveau_card_init+0xb72/0xd7e [nouveau] [ 2417.746921] [] nouveau_load+0x6ba/0x70a [nouveau] [ 2417.746927] [] drm_get_dev+0x470/0x5a1 [ 2417.746930] [] nouveau_pci_probe+0x10/0x12 [nouveau] [ 2417.746939] [] local_pci_probe+0x12/0x16 [ 2417.746942] [] pci_device_probe+0x60/0x8f [ 2417.746946] [] driver_probe_device+0xa7/0x136 [ 2417.746949] [] __driver_attach+0x5c/0x80 [ 2417.746952] [] bus_for_each_dev+0x54/0x89 [ 2417.746955] [] driver_attach+0x19/0x1b [ 2417.746958] [] bus_add_driver+0x183/0x2ef [ 2417.746962] [] driver_register+0x98/0x109 [ 2417.746965] [] __pci_register_driver+0x63/0xd3 [ 2417.746969] [] drm_init+0x6b/0xd1 [ 2417.746972] [] 0xffffffffa0128048 [ 2417.746975] [] do_one_initcall+0x59/0x14e [ 2417.746978] [] sys_init_module+0x9c/0x1dd [ 2417.746981] [] system_call_fastpath+0x16/0x1b [ 2417.746985] } [ 2417.746986] ... key at: [] __key.39000+0x0/0xfffffffffffee196 [nouveau] [ 2417.746992] ... acquired at: [ 2417.746994] [] check_irq_usage+0x5d/0xbe [ 2417.746997] [] validate_chain+0x74a/0xd23 [ 2417.746999] [] __lock_acquire+0x883/0x8f4 [ 2417.747002] [] lock_acquire+0x148/0x18d [ 2417.747005] [] _raw_spin_lock+0x36/0x45 [ 2417.747008] [] drm_mm_put_block+0x17a/0x1c0 [ 2417.747011] [] nouveau_gpuobj_del+0x167/0x1b5 [nouveau] [ 2417.747017] [] nouveau_gpuobj_ref_del+0x2f3/0x31a [nouveau] [ 2417.747023] [] nv50_graph_destroy_context+0xf1/0xfd [nouveau] [ 2417.747032] [] nouveau_channel_free+0x141/0x233 [nouveau] [ 2417.747037] [] nouveau_ioctl_fifo_free+0x6f/0x73 [nouveau] [ 2417.747043] [] drm_ioctl+0x27b/0x347 [ 2417.747045] [] vfs_ioctl+0x2d/0xa1 [ 2417.747049] [] do_vfs_ioctl+0x454/0x48d [ 2417.747052] [] sys_ioctl+0x42/0x65 [ 2417.747055] [] system_call_fastpath+0x16/0x1b [ 2417.747058] [ 2417.747059] [ 2417.747060] the dependencies between the lock to be acquired and HARDIRQ-irq-unsafe lock: [ 2417.747067] -> (&(&mm->unused_lock)->rlock){+.+...} ops: 328035 { [ 2417.747072] HARDIRQ-ON-W at: [ 2417.747074] [] __lock_acquire+0x6eb/0x8f4 [ 2417.747077] [] lock_acquire+0x148/0x18d [ 2417.747081] [] _raw_spin_lock+0x36/0x45 [ 2417.747084] [] drm_mm_pre_get+0x20/0x1a7 [ 2417.747088] [] ttm_bo_init+0x234/0x385 [ttm] [ 2417.747093] [] nouveau_bo_new+0x366/0x3eb [nouveau] [ 2417.747100] [] nouveau_mem_init+0x262/0x44a [nouveau] [ 2417.747106] [] nouveau_card_init+0xa73/0xd7e [nouveau] [ 2417.747112] [] nouveau_load+0x6ba/0x70a [nouveau] [ 2417.747117] [] drm_get_dev+0x470/0x5a1 [ 2417.747121] [] nouveau_pci_probe+0x10/0x12 [nouveau] [ 2417.747129] [] local_pci_probe+0x12/0x16 [ 2417.747133] [] pci_device_probe+0x60/0x8f [ 2417.747136] [] driver_probe_device+0xa7/0x136 [ 2417.747140] [] __driver_attach+0x5c/0x80 [ 2417.747143] [] bus_for_each_dev+0x54/0x89 [ 2417.747146] [] driver_attach+0x19/0x1b [ 2417.747149] [] bus_add_driver+0x183/0x2ef [ 2417.747152] [] driver_register+0x98/0x109 [ 2417.747156] [] __pci_register_driver+0x63/0xd3 [ 2417.747159] [] drm_init+0x6b/0xd1 [ 2417.747162] [] 0xffffffffa0128048 [ 2417.747165] [] do_one_initcall+0x59/0x14e [ 2417.747169] [] sys_init_module+0x9c/0x1dd [ 2417.747172] [] system_call_fastpath+0x16/0x1b [ 2417.747176] SOFTIRQ-ON-W at: [ 2417.747178] [] __lock_acquire+0x70e/0x8f4 [ 2417.747181] [] lock_acquire+0x148/0x18d [ 2417.747184] [] _raw_spin_lock+0x36/0x45 [ 2417.747188] [] drm_mm_pre_get+0x20/0x1a7 [ 2417.747191] [] ttm_bo_init+0x234/0x385 [ttm] [ 2417.747196] [] nouveau_bo_new+0x366/0x3eb [nouveau] [ 2417.747203] [] nouveau_mem_init+0x262/0x44a [nouveau] [ 2417.747209] [] nouveau_card_init+0xa73/0xd7e [nouveau] [ 2417.747215] [] nouveau_load+0x6ba/0x70a [nouveau] [ 2417.747221] [] drm_get_dev+0x470/0x5a1 [ 2417.747224] [] nouveau_pci_probe+0x10/0x12 [nouveau] [ 2417.747233] [] local_pci_probe+0x12/0x16 [ 2417.747236] [] pci_device_probe+0x60/0x8f [ 2417.747239] [] driver_probe_device+0xa7/0x136 [ 2417.747243] [] __driver_attach+0x5c/0x80 [ 2417.747246] [] bus_for_each_dev+0x54/0x89 [ 2417.747249] [] driver_attach+0x19/0x1b [ 2417.747252] [] bus_add_driver+0x183/0x2ef [ 2417.747255] [] driver_register+0x98/0x109 [ 2417.747259] [] __pci_register_driver+0x63/0xd3 [ 2417.747262] [] drm_init+0x6b/0xd1 [ 2417.747265] [] 0xffffffffa0128048 [ 2417.747268] [] do_one_initcall+0x59/0x14e [ 2417.747272] [] sys_init_module+0x9c/0x1dd [ 2417.747275] [] system_call_fastpath+0x16/0x1b [ 2417.747278] INITIAL USE at: [ 2417.747280] [] __lock_acquire+0x767/0x8f4 [ 2417.747284] [] lock_acquire+0x148/0x18d [ 2417.747287] [] _raw_spin_lock+0x36/0x45 [ 2417.747291] [] drm_mm_pre_get+0x20/0x1a7 [ 2417.747294] [] ttm_bo_init+0x234/0x385 [ttm] [ 2417.747299] [] nouveau_bo_new+0x366/0x3eb [nouveau] [ 2417.747306] [] nouveau_mem_init+0x262/0x44a [nouveau] [ 2417.747312] [] nouveau_card_init+0xa73/0xd7e [nouveau] [ 2417.747318] [] nouveau_load+0x6ba/0x70a [nouveau] [ 2417.747323] [] drm_get_dev+0x470/0x5a1 [ 2417.747327] [] nouveau_pci_probe+0x10/0x12 [nouveau] [ 2417.747335] [] local_pci_probe+0x12/0x16 [ 2417.747339] [] pci_device_probe+0x60/0x8f [ 2417.747342] [] driver_probe_device+0xa7/0x136 [ 2417.747345] [] __driver_attach+0x5c/0x80 [ 2417.747349] [] bus_for_each_dev+0x54/0x89 [ 2417.747352] [] driver_attach+0x19/0x1b [ 2417.747355] [] bus_add_driver+0x183/0x2ef [ 2417.747358] [] driver_register+0x98/0x109 [ 2417.747361] [] __pci_register_driver+0x63/0xd3 [ 2417.747365] [] drm_init+0x6b/0xd1 [ 2417.747368] [] 0xffffffffa0128048 [ 2417.747371] [] do_one_initcall+0x59/0x14e [ 2417.747374] [] sys_init_module+0x9c/0x1dd [ 2417.747377] [] system_call_fastpath+0x16/0x1b [ 2417.747381] } [ 2417.747382] ... key at: [] __key.36424+0x0/0x8 [ 2417.747386] ... acquired at: [ 2417.747387] [] check_irq_usage+0x5d/0xbe [ 2417.747390] [] validate_chain+0x74a/0xd23 [ 2417.747393] [] __lock_acquire+0x883/0x8f4 [ 2417.747396] [] lock_acquire+0x148/0x18d [ 2417.747399] [] _raw_spin_lock+0x36/0x45 [ 2417.747401] [] drm_mm_put_block+0x17a/0x1c0 [ 2417.747405] [] nouveau_gpuobj_del+0x167/0x1b5 [nouveau] [ 2417.747410] [] nouveau_gpuobj_ref_del+0x2f3/0x31a [nouveau] [ 2417.747416] [] nv50_graph_destroy_context+0xf1/0xfd [nouveau] [ 2417.747425] [] nouveau_channel_free+0x141/0x233 [nouveau] [ 2417.747430] [] nouveau_ioctl_fifo_free+0x6f/0x73 [nouveau] [ 2417.747436] [] drm_ioctl+0x27b/0x347 [ 2417.747438] [] vfs_ioctl+0x2d/0xa1 [ 2417.747441] [] do_vfs_ioctl+0x454/0x48d [ 2417.747444] [] sys_ioctl+0x42/0x65 [ 2417.747447] [] system_call_fastpath+0x16/0x1b [ 2417.747450] [ 2417.747451] [ 2417.747451] stack backtrace: [ 2417.747454] Pid: 2850, comm: warsow Not tainted 2.6.35-rc4-nv+ #379 [ 2417.747455] Call Trace: [ 2417.747458] [] check_usage+0x45c/0x470 [ 2417.747462] [] check_irq_usage+0x5d/0xbe [ 2417.747465] [] validate_chain+0x74a/0xd23 [ 2417.747468] [] __lock_acquire+0x883/0x8f4 [ 2417.747472] [] ? drm_mm_put_block+0x17a/0x1c0 [ 2417.747475] [] lock_acquire+0x148/0x18d [ 2417.747477] [] ? drm_mm_put_block+0x17a/0x1c0 [ 2417.747480] [] ? mark_held_locks+0x52/0x70 [ 2417.747483] [] _raw_spin_lock+0x36/0x45 [ 2417.747486] [] ? drm_mm_put_block+0x17a/0x1c0 [ 2417.747490] [] drm_mm_put_block+0x17a/0x1c0 [ 2417.747496] [] nouveau_gpuobj_del+0x167/0x1b5 [nouveau] [ 2417.747501] [] nouveau_gpuobj_ref_del+0x2f3/0x31a [nouveau] [ 2417.747510] [] nv50_graph_destroy_context+0xf1/0xfd [nouveau] [ 2417.747516] [] nouveau_channel_free+0x141/0x233 [nouveau] [ 2417.747519] [] ? add_preempt_count+0x34/0x36 [ 2417.747525] [] nouveau_ioctl_fifo_free+0x6f/0x73 [nouveau] [ 2417.747527] [] drm_ioctl+0x27b/0x347 [ 2417.747533] [] ? nouveau_ioctl_fifo_free+0x0/0x73 [nouveau] [ 2417.747536] [] ? debug_check_no_locks_freed+0x113/0x129 [ 2417.747539] [] ? mark_held_locks+0x52/0x70 [ 2417.747542] [] ? kmem_cache_free+0xb6/0x195 [ 2417.747545] [] vfs_ioctl+0x2d/0xa1 [ 2417.747548] [] do_vfs_ioctl+0x454/0x48d [ 2417.747551] [] ? fget_light+0xd6/0x289 [ 2417.747554] [] sys_ioctl+0x42/0x65 [ 2417.747557] [] system_call_fastpath+0x16/0x1b Deadlock scenario looks like this: CPU1 CPU2 nouveau code calls some drm_mm.c function which takes mm->unused_lock nouveau_channel_free disables irqs and takes dev_priv->context_switch_lock calls nv50_graph_destroy_context which (... backtrace above) calls drm_mm_put_block which tries to take mm->unused_lock (spins) nouveau interrupt raises nouveau_irq_handler tries to take dev_priv->context_switch_lock (spins) deadlock Possible solutions: - reverting "drm/nouveau: use drm_mm in preference to custom code doing the same thing" - disabling interrupts before calling drm_mm functions - unmaintainable and still deadlockable in multicard setups (nouveau and eg radeon) - making mm->unused_lock HARDIRQ-safe (patch below) - simple but with slight overhead --- From: Marcin Slusarz Subject: [PATCH] drm: make drm_mm->unused_lock HARDIRQ-safe nouveau started to use drm_mm functions (in "drm/nouveau: use drm_mm in preference to custom code doing the same thing") but it has to call them under HARDIRQ-safe lock. To prevent deadlocks we have to make drm_mm->unused_lock HARDIRQ-safe too. Deadlock scenario: CPU1 CPU2 nouveau code calls some drm_mm.c function which takes mm->unused_lock nouveau_channel_free disables irqs and takes dev_priv->context_switch_lock calls nv50_graph_destroy_context which (... backtrace above) calls drm_mm_put_block which tries to take mm->unused_lock (spins) nouveau interrupt raises nouveau_irq_handler tries to take dev_priv->context_switch_lock (spins) Signed-off-by: Marcin Slusarz --- drivers/gpu/drm/drm_mm.c | 30 +++++++++++++++++------------- 1 files changed, 17 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 2ac074c..bb95831 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -81,6 +81,7 @@ int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size) static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) { struct drm_mm_node *child; + unsigned long flags; if (atomic) child = kmalloc(sizeof(*child), GFP_ATOMIC); @@ -88,7 +89,7 @@ static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) child = kmalloc(sizeof(*child), GFP_KERNEL); if (unlikely(child == NULL)) { - spin_lock(&mm->unused_lock); + spin_lock_irqsave(&mm->unused_lock, flags); if (list_empty(&mm->unused_nodes)) child = NULL; else { @@ -98,7 +99,7 @@ static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) list_del(&child->fl_entry); --mm->num_unused; } - spin_unlock(&mm->unused_lock); + spin_unlock_irqrestore(&mm->unused_lock, flags); } return child; } @@ -111,22 +112,23 @@ static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) int drm_mm_pre_get(struct drm_mm *mm) { struct drm_mm_node *node; + unsigned long flags; - spin_lock(&mm->unused_lock); + spin_lock_irqsave(&mm->unused_lock, flags); while (mm->num_unused < MM_UNUSED_TARGET) { - spin_unlock(&mm->unused_lock); + spin_unlock_irqrestore(&mm->unused_lock, flags); node = kmalloc(sizeof(*node), GFP_KERNEL); - spin_lock(&mm->unused_lock); + spin_lock_irqsave(&mm->unused_lock, flags); if (unlikely(node == NULL)) { int ret = (mm->num_unused < 2) ? -ENOMEM : 0; - spin_unlock(&mm->unused_lock); + spin_unlock_irqrestore(&mm->unused_lock, flags); return ret; } ++mm->num_unused; list_add_tail(&node->fl_entry, &mm->unused_nodes); } - spin_unlock(&mm->unused_lock); + spin_unlock_irqrestore(&mm->unused_lock, flags); return 0; } EXPORT_SYMBOL(drm_mm_pre_get); @@ -277,6 +279,7 @@ void drm_mm_put_block(struct drm_mm_node *cur) struct list_head *root_head = &mm->ml_entry; struct drm_mm_node *prev_node = NULL; struct drm_mm_node *next_node; + unsigned long flags; int merged = 0; @@ -296,14 +299,14 @@ void drm_mm_put_block(struct drm_mm_node *cur) prev_node->size += next_node->size; list_del(&next_node->ml_entry); list_del(&next_node->fl_entry); - spin_lock(&mm->unused_lock); + spin_lock_irqsave(&mm->unused_lock, flags); if (mm->num_unused < MM_UNUSED_TARGET) { list_add(&next_node->fl_entry, &mm->unused_nodes); ++mm->num_unused; } else kfree(next_node); - spin_unlock(&mm->unused_lock); + spin_unlock_irqrestore(&mm->unused_lock, flags); } else { next_node->size += cur->size; next_node->start = cur->start; @@ -316,13 +319,13 @@ void drm_mm_put_block(struct drm_mm_node *cur) list_add(&cur->fl_entry, &mm->fl_entry); } else { list_del(&cur->ml_entry); - spin_lock(&mm->unused_lock); + spin_lock_irqsave(&mm->unused_lock, flags); if (mm->num_unused < MM_UNUSED_TARGET) { list_add(&cur->fl_entry, &mm->unused_nodes); ++mm->num_unused; } else kfree(cur); - spin_unlock(&mm->unused_lock); + spin_unlock_irqrestore(&mm->unused_lock, flags); } } @@ -445,6 +448,7 @@ void drm_mm_takedown(struct drm_mm * mm) struct list_head *bnode = mm->fl_entry.next; struct drm_mm_node *entry; struct drm_mm_node *next; + unsigned long flags; entry = list_entry(bnode, struct drm_mm_node, fl_entry); @@ -458,13 +462,13 @@ void drm_mm_takedown(struct drm_mm * mm) list_del(&entry->ml_entry); kfree(entry); - spin_lock(&mm->unused_lock); + spin_lock_irqsave(&mm->unused_lock, flags); list_for_each_entry_safe(entry, next, &mm->unused_nodes, fl_entry) { list_del(&entry->fl_entry); kfree(entry); --mm->num_unused; } - spin_unlock(&mm->unused_lock); + spin_unlock_irqrestore(&mm->unused_lock, flags); BUG_ON(mm->num_unused != 0); } -- 1.7.1