X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=Documentation%2Fkref.txt;h=ae203f91ee9b8a80e54f98d76f09457a665cad0f;hb=b9498bfe86530fd54fb855906383c0c905a52c80;hp=96d8f5666afe6006e47dc0155962885f491ea188;hpb=5c11c52046eb0f7252574bad161db53d0345ea50;p=safe%2Fjmp%2Flinux-2.6 diff --git a/Documentation/kref.txt b/Documentation/kref.txt index 96d8f56..ae203f9 100644 --- a/Documentation/kref.txt +++ b/Documentation/kref.txt @@ -67,7 +67,7 @@ void more_data_handling(void *cb_data) . . do stuff with data here . - kref_put(data, data_release); + kref_put(&data->refcount, data_release); } int my_data_handler(void) @@ -84,7 +84,6 @@ int my_data_handler(void) task = kthread_run(more_data_handling, data, "more_data_handling"); if (task == ERR_PTR(-ENOMEM)) { rv = -ENOMEM; - kref_put(&data->refcount, data_release); goto out; } @@ -141,10 +140,10 @@ The last rule (rule 3) is the nastiest one to handle. Say, for instance, you have a list of items that are each kref-ed, and you wish to get the first one. You can't just pull the first item off the list and kref_get() it. That violates rule 3 because you are not already -holding a valid pointer. You must add locks or semaphores. For -instance: +holding a valid pointer. You must add a mutex (or some other lock). +For instance: -static DECLARE_MUTEX(sem); +static DEFINE_MUTEX(mutex); static LIST_HEAD(q); struct my_data { @@ -155,12 +154,12 @@ struct my_data static struct my_data *get_entry() { struct my_data *entry = NULL; - down(&sem); + mutex_lock(&mutex); if (!list_empty(&q)) { entry = container_of(q.next, struct my_q_entry, link); kref_get(&entry->refcount); } - up(&sem); + mutex_unlock(&mutex); return entry; } @@ -174,9 +173,9 @@ static void release_entry(struct kref *ref) static void put_entry(struct my_data *entry) { - down(&sem); + mutex_lock(&mutex); kref_put(&entry->refcount, release_entry); - up(&sem); + mutex_unlock(&mutex); } The kref_put() return value is useful if you do not want to hold the @@ -191,13 +190,13 @@ static void release_entry(struct kref *ref) static void put_entry(struct my_data *entry) { - down(&sem); + mutex_lock(&mutex); if (kref_put(&entry->refcount, release_entry)) { list_del(&entry->link); - up(&sem); + mutex_unlock(&mutex); kfree(entry); } else - up(&sem); + mutex_unlock(&mutex); } This is really more useful if you have to call other routines as part @@ -208,4 +207,9 @@ preferred as it is a little neater. Corey Minyard -A lot of this was lifted from Greg KH's OLS presentation on krefs. +A lot of this was lifted from Greg Kroah-Hartman's 2004 OLS paper and +presentation on krefs, which can be found at: + http://www.kroah.com/linux/talks/ols_2004_kref_paper/Reprint-Kroah-Hartman-OLS2004.pdf +and: + http://www.kroah.com/linux/talks/ols_2004_kref_talk/ +