From: akpm@osdl.org Subject: [patch 16/22] acpi_os_acquire_object (GFP_KERNEL) called with IRQs disabled through suspend-resume Date: Tue, 07 Mar 2006 23:49:42 -0800 Message-ID: <200603080751.k287pVM0000994@shell0.pdx.osdl.net> Return-path: Received: from smtp.osdl.org ([65.172.181.4]:56481 "EHLO smtp.osdl.org") by vger.kernel.org with ESMTP id S1752089AbWCHHvg (ORCPT ); Wed, 8 Mar 2006 02:51:36 -0500 Sender: linux-acpi-owner@vger.kernel.org List-Id: linux-acpi@vger.kernel.org To: len.brown@intel.com Cc: linux-acpi@vger.kernel.org, akpm@osdl.org, davi.arnaut@gmail.com, pavel@ucw.cz From: Davi Arnaut acpi_os_acquire_object() gets called, with IRQs disabled, from: Debug: sleeping function called from invalid context at mm/slab.c:2499 in_atomic():0, irqs_disabled():1 [] kmem_cache_alloc+0x40/0x4f [] acpi_os_acquire_object+0xb/0x3c [] acpi_ut_allocate_object_desc_dbg+0x13/0x49 [] acpi_ut_create_internal_object_dbg+0xf/0x5e [] acpi_rs_set_srs_method_data+0x3d/0xb9 [] acpi_pci_link_set+0x102/0x17b [] irqrouter_resume+0x1e/0x3c [] __sysdev_resume+0x11/0x6b [] sysdev_resume+0x34/0x52 [] device_power_up+0x5/0xa [] suspend_enter+0x44/0x46 [] suspend_prepare+0x63/0xc1 [] enter_state+0x5e/0x7c [] state_store+0x81/0x8f [] state_store+0x0/0x8f [] subsys_attr_store+0x1e/0x22 [] flush_write_buffer+0x22/0x28 [] sysfs_write_file+0x4c/0x71 [] sysfs_write_file+0x0/0x71 [] vfs_write+0xa2/0x15a [] sys_write+0x41/0x6a [] syscall_call+0x7/0xb The patch also fixes a missing check for NULL return from acpi_os_acquire_object(). Signed-off-by: Davi Arnaut Cc: "Brown, Len" Cc: Pavel Machek Signed-off-by: Andrew Morton --- drivers/acpi/osl.c | 7 ++++++- drivers/acpi/parser/psutils.c | 8 ++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff -puN drivers/acpi/osl.c~acpi_os_acquire_object-gfp_kernel-called-with-irqs drivers/acpi/osl.c --- devel/drivers/acpi/osl.c~acpi_os_acquire_object-gfp_kernel-called-with-irqs 2006-03-07 23:47:11.000000000 -0800 +++ devel-akpm/drivers/acpi/osl.c 2006-03-07 23:47:11.000000000 -0800 @@ -1175,7 +1175,12 @@ acpi_status acpi_os_release_object(acpi_ void *acpi_os_acquire_object(acpi_cache_t * cache) { - void *object = kmem_cache_alloc(cache, GFP_KERNEL); + void *object; + + if (acpi_in_resume) + object = kmem_cache_alloc(cache, GFP_ATOMIC); + else + object = kmem_cache_alloc(cache, GFP_KERNEL); WARN_ON(!object); return object; } diff -puN drivers/acpi/parser/psutils.c~acpi_os_acquire_object-gfp_kernel-called-with-irqs drivers/acpi/parser/psutils.c --- devel/drivers/acpi/parser/psutils.c~acpi_os_acquire_object-gfp_kernel-called-with-irqs 2006-03-07 23:47:11.000000000 -0800 +++ devel-akpm/drivers/acpi/parser/psutils.c 2006-03-07 23:47:11.000000000 -0800 @@ -139,12 +139,16 @@ union acpi_parse_object *acpi_ps_alloc_o /* The generic op (default) is by far the most common (16 to 1) */ op = acpi_os_acquire_object(acpi_gbl_ps_node_cache); - memset(op, 0, sizeof(struct acpi_parse_obj_common)); + + if (op) + memset(op, 0, sizeof(struct acpi_parse_obj_common)); } else { /* Extended parseop */ op = acpi_os_acquire_object(acpi_gbl_ps_node_ext_cache); - memset(op, 0, sizeof(struct acpi_parse_obj_named)); + + if (op) + memset(op, 0, sizeof(struct acpi_parse_obj_named)); } /* Initialize the Op */ _