From patchwork Fri Aug 5 16:39:44 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Senozhatsky X-Patchwork-Id: 1038952 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p75GWtfr029295 for ; Fri, 5 Aug 2011 16:40:58 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752935Ab1HEQkt (ORCPT ); Fri, 5 Aug 2011 12:40:49 -0400 Received: from mail-ey0-f174.google.com ([209.85.215.174]:48513 "EHLO mail-ey0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750908Ab1HEQkt (ORCPT ); Fri, 5 Aug 2011 12:40:49 -0400 Received: by eyx24 with SMTP id 24so1406642eyx.19 for ; Fri, 05 Aug 2011 09:40:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=date:from:to:cc:subject:message-id:references:mime-version :content-type:content-disposition:in-reply-to:user-agent; bh=fRjgT3sywWvkVkuMYW1OZN7J0pu+rQJ2qn7ODTAdVuc=; b=ssFUpDBsQ6kY6CrN/fypm9w73TZwAlLP5+FvISCttngbC3htlVjy1+rK0vIqv5bH1s wZRteUvligUhGRSoviVHZwlhUvQ1OSBrR94tpqxg8TIVOH4C+OMATBHH85ZDmsY4FN3i WBuLrdtjfo9fop622hfcIvQp/8apJrKlO8btI= Received: by 10.204.156.216 with SMTP id y24mr779282bkw.75.1312562447642; Fri, 05 Aug 2011 09:40:47 -0700 (PDT) Received: from localhost ([86.57.255.94]) by mx.google.com with ESMTPS id k5sm898469bka.38.2011.08.05.09.40.46 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 05 Aug 2011 09:40:46 -0700 (PDT) Date: Fri, 5 Aug 2011 19:39:44 +0300 From: Sergey Senozhatsky To: "lan,Tianyu" Cc: Len Brown , "linux-acpi@vger.kernel.org" , "linux-kernel@vger.kernel.org" Subject: Re: [PATCH] Battery: sysfs_remove_battery(): possible circular locking Message-ID: <20110805163944.GA3132@swordfish.minsk.epam.com> References: <20110805003322.GA8311@swordfish> <1312521008.2096.173.camel@lantianyu-ws> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1312521008.2096.173.camel@lantianyu-ws> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 05 Aug 2011 16:40:59 +0000 (UTC) On (08/05/11 13:10), lan,Tianyu wrote: > I think changing 'the marker' to 'battery->bat.name' will introduce > problem. > In the sysfs_add_battery(), when the 'battery->bat.name' is assigned, > the power_supply_register() and device_create_file() have not been > invoked. In this time, maybe sysfs_remove_battery() will be invoked and > cause device_remove_file() and power_supply_unregister() invoked without > device file created and power supply registered. > > sysfs_remove_battery() will be invoked in the battery_notify(), > acpi_battery_refresh() and sysfs_remove_battery() which causes the > situation. This is also the cause of bug 35642. > Well, how about using separate (independent lock) for sysfs_remove_battery() case? Since we can't safely drop battery->lock in sysfs_remove_battery() before power_supply_unregister() call. Not sure if it should be within struct acpi_battery, perhaps we could have it as a 'global' battery lock. Anyway, here it is: --- drivers/acpi/battery.c | 10 +++++++--- 1 files changed, 7 insertions(+), 3 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 87c0a8d..7711d94 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -99,6 +99,7 @@ enum { struct acpi_battery { struct mutex lock; + struct mutex sysfs_lock; struct power_supply bat; struct acpi_device *device; struct notifier_block pm_nb; @@ -573,16 +574,16 @@ static int sysfs_add_battery(struct acpi_battery *battery) static void sysfs_remove_battery(struct acpi_battery *battery) { - mutex_lock(&battery->lock); + mutex_lock(&battery->sysfs_lock); if (!battery->bat.dev) { - mutex_unlock(&battery->lock); + mutex_unlock(&battery->sysfs_lock); return; } device_remove_file(battery->bat.dev, &alarm_attr); power_supply_unregister(&battery->bat); battery->bat.dev = NULL; - mutex_unlock(&battery->lock); + mutex_unlock(&battery->sysfs_lock); } /* @@ -982,6 +983,7 @@ static int acpi_battery_add(struct acpi_device *device) strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); device->driver_data = battery; mutex_init(&battery->lock); + mutex_init(&battery->sysfs_lock); if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle, "_BIX", &handle))) set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); @@ -1010,6 +1012,7 @@ static int acpi_battery_add(struct acpi_device *device) fail: sysfs_remove_battery(battery); mutex_destroy(&battery->lock); + mutex_destroy(&battery->sysfs_lock); kfree(battery); return result; } @@ -1027,6 +1030,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type) #endif sysfs_remove_battery(battery); mutex_destroy(&battery->lock); + mutex_destroy(&battery->sysfs_lock); kfree(battery); return 0; }