Merge with kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6.git/

for 13 driver core, sysfs, and debugfs fixes.

+286 -8
+216
Documentation/kref.txt
··· 1 + 2 + krefs allow you to add reference counters to your objects. If you 3 + have objects that are used in multiple places and passed around, and 4 + you don't have refcounts, your code is almost certainly broken. If 5 + you want refcounts, krefs are the way to go. 6 + 7 + To use a kref, add one to your data structures like: 8 + 9 + struct my_data 10 + { 11 + . 12 + . 13 + struct kref refcount; 14 + . 15 + . 16 + }; 17 + 18 + The kref can occur anywhere within the data structure. 19 + 20 + You must initialize the kref after you allocate it. To do this, call 21 + kref_init as so: 22 + 23 + struct my_data *data; 24 + 25 + data = kmalloc(sizeof(*data), GFP_KERNEL); 26 + if (!data) 27 + return -ENOMEM; 28 + kref_init(&data->refcount); 29 + 30 + This sets the refcount in the kref to 1. 31 + 32 + Once you have an initialized kref, you must follow the following 33 + rules: 34 + 35 + 1) If you make a non-temporary copy of a pointer, especially if 36 + it can be passed to another thread of execution, you must 37 + increment the refcount with kref_get() before passing it off: 38 + kref_get(&data->refcount); 39 + If you already have a valid pointer to a kref-ed structure (the 40 + refcount cannot go to zero) you may do this without a lock. 41 + 42 + 2) When you are done with a pointer, you must call kref_put(): 43 + kref_put(&data->refcount, data_release); 44 + If this is the last reference to the pointer, the release 45 + routine will be called. If the code never tries to get 46 + a valid pointer to a kref-ed structure without already 47 + holding a valid pointer, it is safe to do this without 48 + a lock. 49 + 50 + 3) If the code attempts to gain a reference to a kref-ed structure 51 + without already holding a valid pointer, it must serialize access 52 + where a kref_put() cannot occur during the kref_get(), and the 53 + structure must remain valid during the kref_get(). 54 + 55 + For example, if you allocate some data and then pass it to another 56 + thread to process: 57 + 58 + void data_release(struct kref *ref) 59 + { 60 + struct my_data *data = container_of(ref, struct my_data, refcount); 61 + kfree(data); 62 + } 63 + 64 + void more_data_handling(void *cb_data) 65 + { 66 + struct my_data *data = cb_data; 67 + . 68 + . do stuff with data here 69 + . 70 + kref_put(data, data_release); 71 + } 72 + 73 + int my_data_handler(void) 74 + { 75 + int rv = 0; 76 + struct my_data *data; 77 + struct task_struct *task; 78 + data = kmalloc(sizeof(*data), GFP_KERNEL); 79 + if (!data) 80 + return -ENOMEM; 81 + kref_init(&data->refcount); 82 + 83 + kref_get(&data->refcount); 84 + task = kthread_run(more_data_handling, data, "more_data_handling"); 85 + if (task == ERR_PTR(-ENOMEM)) { 86 + rv = -ENOMEM; 87 + kref_put(&data->refcount, data_release); 88 + goto out; 89 + } 90 + 91 + . 92 + . do stuff with data here 93 + . 94 + out: 95 + kref_put(&data->refcount, data_release); 96 + return rv; 97 + } 98 + 99 + This way, it doesn't matter what order the two threads handle the 100 + data, the kref_put() handles knowing when the data is not referenced 101 + any more and releasing it. The kref_get() does not require a lock, 102 + since we already have a valid pointer that we own a refcount for. The 103 + put needs no lock because nothing tries to get the data without 104 + already holding a pointer. 105 + 106 + Note that the "before" in rule 1 is very important. You should never 107 + do something like: 108 + 109 + task = kthread_run(more_data_handling, data, "more_data_handling"); 110 + if (task == ERR_PTR(-ENOMEM)) { 111 + rv = -ENOMEM; 112 + goto out; 113 + } else 114 + /* BAD BAD BAD - get is after the handoff */ 115 + kref_get(&data->refcount); 116 + 117 + Don't assume you know what you are doing and use the above construct. 118 + First of all, you may not know what you are doing. Second, you may 119 + know what you are doing (there are some situations where locking is 120 + involved where the above may be legal) but someone else who doesn't 121 + know what they are doing may change the code or copy the code. It's 122 + bad style. Don't do it. 123 + 124 + There are some situations where you can optimize the gets and puts. 125 + For instance, if you are done with an object and enqueuing it for 126 + something else or passing it off to something else, there is no reason 127 + to do a get then a put: 128 + 129 + /* Silly extra get and put */ 130 + kref_get(&obj->ref); 131 + enqueue(obj); 132 + kref_put(&obj->ref, obj_cleanup); 133 + 134 + Just do the enqueue. A comment about this is always welcome: 135 + 136 + enqueue(obj); 137 + /* We are done with obj, so we pass our refcount off 138 + to the queue. DON'T TOUCH obj AFTER HERE! */ 139 + 140 + The last rule (rule 3) is the nastiest one to handle. Say, for 141 + instance, you have a list of items that are each kref-ed, and you wish 142 + to get the first one. You can't just pull the first item off the list 143 + and kref_get() it. That violates rule 3 because you are not already 144 + holding a valid pointer. You must add locks or semaphores. For 145 + instance: 146 + 147 + static DECLARE_MUTEX(sem); 148 + static LIST_HEAD(q); 149 + struct my_data 150 + { 151 + struct kref refcount; 152 + struct list_head link; 153 + }; 154 + 155 + static struct my_data *get_entry() 156 + { 157 + struct my_data *entry = NULL; 158 + down(&sem); 159 + if (!list_empty(&q)) { 160 + entry = container_of(q.next, struct my_q_entry, link); 161 + kref_get(&entry->refcount); 162 + } 163 + up(&sem); 164 + return entry; 165 + } 166 + 167 + static void release_entry(struct kref *ref) 168 + { 169 + struct my_data *entry = container_of(ref, struct my_data, refcount); 170 + 171 + list_del(&entry->link); 172 + kfree(entry); 173 + } 174 + 175 + static void put_entry(struct my_data *entry) 176 + { 177 + down(&sem); 178 + kref_put(&entry->refcount, release_entry); 179 + up(&sem); 180 + } 181 + 182 + The kref_put() return value is useful if you do not want to hold the 183 + lock during the whole release operation. Say you didn't want to call 184 + kfree() with the lock held in the example above (since it is kind of 185 + pointless to do so). You could use kref_put() as follows: 186 + 187 + static void release_entry(struct kref *ref) 188 + { 189 + /* All work is done after the return from kref_put(). */ 190 + } 191 + 192 + static void put_entry(struct my_data *entry) 193 + { 194 + down(&sem); 195 + if (kref_put(&entry->refcount, release_entry)) { 196 + list_del(&entry->link); 197 + up(&sem); 198 + kfree(entry); 199 + } else 200 + up(&sem); 201 + } 202 + 203 + This is really more useful if you have to call other routines as part 204 + of the free operations that could take a long time or might claim the 205 + same lock. Note that doing everything in the release routine is still 206 + preferred as it is a little neater. 207 + 208 + 209 + Corey Minyard <minyard@acm.org> 210 + 211 + A lot of this was lifted from Greg Kroah-Hartman's 2004 OLS paper and 212 + presentation on krefs, which can be found at: 213 + http://www.kroah.com/linux/talks/ols_2004_kref_paper/Reprint-Kroah-Hartman-OLS2004.pdf 214 + and: 215 + http://www.kroah.com/linux/talks/ols_2004_kref_talk/ 216 +
+2
drivers/base/class.c
··· 430 430 sysfs_create_link(&class_dev->kobj, 431 431 &class_dev->dev->kobj, "device"); 432 432 433 + kobject_hotplug(&class_dev->kobj, KOBJ_ADD); 433 434 register_done: 434 435 if (error && parent) 435 436 class_put(parent); ··· 462 461 sysfs_remove_link(&class_dev->kobj, "device"); 463 462 class_device_remove_attrs(class_dev); 464 463 464 + kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE); 465 465 kobject_del(&class_dev->kobj); 466 466 467 467 if (parent)
+3
drivers/base/core.c
··· 260 260 /* notify platform of device entry */ 261 261 if (platform_notify) 262 262 platform_notify(dev); 263 + 264 + kobject_hotplug(&dev->kobj, KOBJ_ADD); 263 265 Done: 264 266 put_device(dev); 265 267 return error; ··· 351 349 platform_notify_remove(dev); 352 350 bus_remove_device(dev); 353 351 device_pm_remove(dev); 352 + kobject_hotplug(&dev->kobj, KOBJ_REMOVE); 354 353 kobject_del(&dev->kobj); 355 354 if (parent) 356 355 put_device(parent);
+3
drivers/base/firmware_class.c
··· 102 102 if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len, 103 103 "FIRMWARE=%s", fw_priv->fw_id)) 104 104 return -ENOMEM; 105 + if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len, 106 + "TIMEOUT=%i", loading_timeout)) 107 + return -ENOMEM; 105 108 106 109 envp[i] = NULL; 107 110
+1
drivers/base/platform.c
··· 341 341 342 342 EXPORT_SYMBOL_GPL(platform_bus); 343 343 EXPORT_SYMBOL_GPL(platform_bus_type); 344 + EXPORT_SYMBOL_GPL(platform_add_devices); 344 345 EXPORT_SYMBOL_GPL(platform_device_register); 345 346 EXPORT_SYMBOL_GPL(platform_device_register_simple); 346 347 EXPORT_SYMBOL_GPL(platform_device_unregister);
+1
drivers/usb/host/hc_crisv10.c
··· 4396 4396 device_initialize(&fake_device); 4397 4397 kobject_set_name(&fake_device.kobj, "etrax_usb"); 4398 4398 kobject_add(&fake_device.kobj); 4399 + kobject_hotplug(&fake_device.kobj, KOBJ_ADD); 4399 4400 hc->bus->controller = &fake_device; 4400 4401 usb_register_bus(hc->bus); 4401 4402
+2
fs/partitions/check.c
··· 337 337 if ((err = kobject_add(&disk->kobj))) 338 338 return; 339 339 disk_sysfs_symlinks(disk); 340 + kobject_hotplug(&disk->kobj, KOBJ_ADD); 340 341 341 342 /* No minors to use for partitions */ 342 343 if (disk->minors == 1) { ··· 442 441 sysfs_remove_link(&disk->driverfs_dev->kobj, "block"); 443 442 put_device(disk->driverfs_dev); 444 443 } 444 + kobject_hotplug(&disk->kobj, KOBJ_REMOVE); 445 445 kobject_del(&disk->kobj); 446 446 }
+35
fs/sysfs/file.c
··· 428 428 429 429 430 430 /** 431 + * sysfs_chmod_file - update the modified mode value on an object attribute. 432 + * @kobj: object we're acting for. 433 + * @attr: attribute descriptor. 434 + * @mode: file permissions. 435 + * 436 + */ 437 + int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode) 438 + { 439 + struct dentry *dir = kobj->dentry; 440 + struct dentry *victim; 441 + struct sysfs_dirent *sd; 442 + umode_t umode = (mode & S_IALLUGO) | S_IFREG; 443 + int res = -ENOENT; 444 + 445 + down(&dir->d_inode->i_sem); 446 + victim = sysfs_get_dentry(dir, attr->name); 447 + if (!IS_ERR(victim)) { 448 + if (victim->d_inode && 449 + (victim->d_parent->d_inode == dir->d_inode)) { 450 + sd = victim->d_fsdata; 451 + attr->mode = mode; 452 + sd->s_mode = umode; 453 + victim->d_inode->i_mode = umode; 454 + dput(victim); 455 + res = 0; 456 + } 457 + } 458 + up(&dir->d_inode->i_sem); 459 + 460 + return res; 461 + } 462 + EXPORT_SYMBOL_GPL(sysfs_chmod_file); 463 + 464 + 465 + /** 431 466 * sysfs_remove_file - remove an object attribute. 432 467 * @kobj: object we're acting for. 433 468 * @attr: attribute descriptor.
+10 -3
include/linux/debugfs.h
··· 17 17 18 18 #include <linux/fs.h> 19 19 20 + #include <linux/types.h> 21 + 22 + struct file_operations; 23 + 20 24 #if defined(CONFIG_DEBUG_FS) 21 25 struct dentry *debugfs_create_file(const char *name, mode_t mode, 22 26 struct dentry *parent, void *data, ··· 40 36 struct dentry *parent, u32 *value); 41 37 42 38 #else 39 + 40 + #include <linux/err.h> 41 + 43 42 /* 44 43 * We do not return NULL from these functions if CONFIG_DEBUG_FS is not enabled 45 44 * so users have a chance to detect if there was a real error or not. We don't ··· 75 68 76 69 static inline struct dentry *debugfs_create_u16(const char *name, mode_t mode, 77 70 struct dentry *parent, 78 - u8 *value) 71 + u16 *value) 79 72 { 80 73 return ERR_PTR(-ENODEV); 81 74 } 82 75 83 76 static inline struct dentry *debugfs_create_u32(const char *name, mode_t mode, 84 77 struct dentry *parent, 85 - u8 *value) 78 + u32 *value) 86 79 { 87 80 return ERR_PTR(-ENODEV); 88 81 } 89 82 90 83 static inline struct dentry *debugfs_create_bool(const char *name, mode_t mode, 91 84 struct dentry *parent, 92 - u8 *value) 85 + u32 *value) 93 86 { 94 87 return ERR_PTR(-ENODEV); 95 88 }
+7
include/linux/sysfs.h
··· 99 99 extern int 100 100 sysfs_update_file(struct kobject *, const struct attribute *); 101 101 102 + extern int 103 + sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode); 104 + 102 105 extern void 103 106 sysfs_remove_file(struct kobject *, const struct attribute *); 104 107 ··· 140 137 } 141 138 142 139 static inline int sysfs_update_file(struct kobject * k, const struct attribute * a) 140 + { 141 + return 0; 142 + } 143 + static inline int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode) 143 144 { 144 145 return 0; 145 146 }
+3 -4
lib/kobject.c
··· 184 184 unlink(kobj); 185 185 if (parent) 186 186 kobject_put(parent); 187 - } else { 188 - kobject_hotplug(kobj, KOBJ_ADD); 189 187 } 190 188 191 189 return error; ··· 205 207 printk("kobject_register failed for %s (%d)\n", 206 208 kobject_name(kobj),error); 207 209 dump_stack(); 208 - } 210 + } else 211 + kobject_hotplug(kobj, KOBJ_ADD); 209 212 } else 210 213 error = -EINVAL; 211 214 return error; ··· 300 301 301 302 void kobject_del(struct kobject * kobj) 302 303 { 303 - kobject_hotplug(kobj, KOBJ_REMOVE); 304 304 sysfs_remove_dir(kobj); 305 305 unlink(kobj); 306 306 } ··· 312 314 void kobject_unregister(struct kobject * kobj) 313 315 { 314 316 pr_debug("kobject %s: unregistering\n",kobject_name(kobj)); 317 + kobject_hotplug(kobj, KOBJ_REMOVE); 315 318 kobject_del(kobj); 316 319 kobject_put(kobj); 317 320 }
+2
net/bridge/br_sysfs_if.c
··· 248 248 if (err) 249 249 goto out2; 250 250 251 + kobject_hotplug(&p->kobj, KOBJ_ADD); 251 252 return 0; 252 253 out2: 253 254 kobject_del(&p->kobj); ··· 260 259 { 261 260 pr_debug("br_sysfs_removeif\n"); 262 261 sysfs_remove_link(&p->br->ifobj, p->dev->name); 262 + kobject_hotplug(&p->kobj, KOBJ_REMOVE); 263 263 kobject_del(&p->kobj); 264 264 } 265 265
+1 -1
scripts/ver_linux
··· 87 87 88 88 expr --v 2>&1 | awk 'NR==1{print "Sh-utils ", $NF}' 89 89 90 - udevinfo -V | awk '{print "udev ", $3}' 90 + udevinfo -V 2>&1 | grep version | awk '{print "udev ", $3}' 91 91 92 92 if [ -e /proc/modules ]; then 93 93 X=`cat /proc/modules | sed -e "s/ .*$//"`