From 3040724f532cef78f5733243dbc26f2ff4cc4f12 Mon Sep 17 00:00:00 2001 From: "Mark M. Hoffman" Date: Sun, 5 Mar 2006 23:13:47 +0100 Subject: [PATCH] --- yaml --- r: 23263 b: refs/heads/master c: ded2b66615613093eeb83b81499bc270de8fc499 h: refs/heads/master i: 23261: 816c5374ca16ce83a2251c2409c04d739a0c4b81 23259: e6009d0c67a0a4148c0b86c973045c9838b19df1 23255: cea1935e4c95d28670a08ee41a453ced6095fac7 23247: 45487e3fcd07aa3dafa96cf479e48e749f8ed1bd 23231: ecfeadef76c5581b09913d85c896fa321b511a37 v: v3 --- [refs] | 2 +- trunk/drivers/hwmon/hwmon.c | 26 ++++++++++++++++++++------ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index 060105979ebd..d43a72eaba25 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f6c27fc17c5e575c5471fb344bdbd5f5f6072136 +refs/heads/master: ded2b66615613093eeb83b81499bc270de8fc499 diff --git a/trunk/drivers/hwmon/hwmon.c b/trunk/drivers/hwmon/hwmon.c index dddd3eb9b387..106fa01cdb60 100644 --- a/trunk/drivers/hwmon/hwmon.c +++ b/trunk/drivers/hwmon/hwmon.c @@ -17,6 +17,7 @@ #include #include #include +#include #define HWMON_ID_PREFIX "hwmon" #define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d" @@ -24,6 +25,7 @@ static struct class *hwmon_class; static DEFINE_IDR(hwmon_idr); +static DEFINE_SPINLOCK(idr_lock); /** * hwmon_device_register - register w/ hwmon sysfs class @@ -37,20 +39,30 @@ static DEFINE_IDR(hwmon_idr); struct class_device *hwmon_device_register(struct device *dev) { struct class_device *cdev; - int id; + int id, err; - if (idr_pre_get(&hwmon_idr, GFP_KERNEL) == 0) +again: + if (unlikely(idr_pre_get(&hwmon_idr, GFP_KERNEL) == 0)) return ERR_PTR(-ENOMEM); - if (idr_get_new(&hwmon_idr, NULL, &id) < 0) - return ERR_PTR(-ENOMEM); + spin_lock(&idr_lock); + err = idr_get_new(&hwmon_idr, NULL, &id); + spin_unlock(&idr_lock); + + if (unlikely(err == -EAGAIN)) + goto again; + else if (unlikely(err)) + return ERR_PTR(err); id = id & MAX_ID_MASK; cdev = class_device_create(hwmon_class, NULL, MKDEV(0,0), dev, HWMON_ID_FORMAT, id); - if (IS_ERR(cdev)) + if (IS_ERR(cdev)) { + spin_lock(&idr_lock); idr_remove(&hwmon_idr, id); + spin_unlock(&idr_lock); + } return cdev; } @@ -64,9 +76,11 @@ void hwmon_device_unregister(struct class_device *cdev) { int id; - if (sscanf(cdev->class_id, HWMON_ID_FORMAT, &id) == 1) { + if (likely(sscanf(cdev->class_id, HWMON_ID_FORMAT, &id) == 1)) { class_device_unregister(cdev); + spin_lock(&idr_lock); idr_remove(&hwmon_idr, id); + spin_unlock(&idr_lock); } else dev_dbg(cdev->dev, "hwmon_device_unregister() failed: bad class ID!\n");