Documentation/translations/zh_CN/core-api/kref.rst

Source file repositories/reference/linux-study-clean/Documentation/translations/zh_CN/core-api/kref.rst

File Facts

System
Linux kernel
Corpus path
Documentation/translations/zh_CN/core-api/kref.rst
Extension
.rst
Size
9280 bytes
Lines
312
Domain
Support Tooling And Documentation
Bucket
Documentation
Inferred role
Support Tooling And Documentation: documentation
Status
atlas-only

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!list_empty(&q)) {
			entry = container_of(q.next, struct my_data, link);
			kref_get(&entry->refcount);
		}
		mutex_unlock(&mutex);
		return entry;
	}

	static void release_entry(struct kref *ref)
	{
		struct my_data *entry = container_of(ref, struct my_data, refcount);

		list_del(&entry->link);
		kfree(entry);
	}

	static void put_entry(struct my_data *entry)
	{
		mutex_lock(&mutex);
		kref_put(&entry->refcount, release_entry);
		mutex_unlock(&mutex);
	}

如果你不想在整个释放操作过程中持有锁,kref_put()的返回值是有用的。假设你不想在
上面的例子中在持有锁的情况下调用kfree()(因为这样做有点无意义)。你可以使用kref_put(),
如下所示::

	static void release_entry(struct kref *ref)
	{
		/* 所有的工作都是在从kref_put()返回后完成的。*/
	}

	static void put_entry(struct my_data *entry)
	{
		mutex_lock(&mutex);
		if (kref_put(&entry->refcount, release_entry)) {
			list_del(&entry->link);
			mutex_unlock(&mutex);
			kfree(entry);
		} else
			mutex_unlock(&mutex);
	}

如果你必须调用其他程序作为释放操作的一部分,而这些程序可能需要很长的时间,或者可
能要求相同的锁,那么这真的更有用。请注意,在释放例程中做所有的事情还是比较好的,
因为它比较整洁。

上面的例子也可以用kref_get_unless_zero()来优化,方法如下::

	static struct my_data *get_entry()
	{
		struct my_data *entry = NULL;
		mutex_lock(&mutex);
		if (!list_empty(&q)) {
			entry = container_of(q.next, struct my_data, link);
			if (!kref_get_unless_zero(&entry->refcount))
				entry = NULL;
		}
		mutex_unlock(&mutex);
		return entry;
	}

	static void release_entry(struct kref *ref)
	{
		struct my_data *entry = container_of(ref, struct my_data, refcount);

		mutex_lock(&mutex);
		list_del(&entry->link);
		mutex_unlock(&mutex);
		kfree(entry);

Annotation

Implementation Notes