作者:Greg Kroah-Hartman
原文地址:http://www.kroah.com/linux/talks/ols_2004_kref_talk/
3 rules of use中关于第3点使用规则的说明:
If the code wanting to access the variable,
does not have a valid reference, then it
needs to serialize
with a place
within the
code where the last call to kref_put
put
could happen.(红色表示断句)
对上面这段英文简要解释就是:一个内核
线程调用
kref_get之前一定要有kref_put的
调用(本线程或其他共享kref的线程),使得
kref_get和kref_put调用呈交替串行的状态。
This third rule can not be emphasized enough.
The only reason that the
struct kref
can
work without any internal locks is because a
call to
kref_get
can not happen at the same
time that
kref_put
is happening. In order to
ensure this, a simple lock for the driver or sub
system that owns the specifific
struct kref
reference can be used.See the Exapmle blow.
/* prevent races between open() and disconnect() */
static DECLARE_MUTEX (disconnect_sem);
static int skel_open(struct inode *inode, struct file *file)
{
struct usb_skel *dev;
struct usb_interface *interface;
/* prevent disconnects */
down (&disconnect_sem);
interface = usb_find_interface(&skel_driver, iminor(inode));
dev = usb_get_intfdata(interface);
/* increment our usage count for the device */
kref_get(&dev->kref);
up(&disconnect_sem);
...
}
static void skel_disconnect(struct usb_interface *interface)
{
struct usb_skel *dev;
int minor = interface->minor;
/* prevent skel_open() from racing skel_disconnect() */
down (&disconnect_sem);
dev = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL);
/* give back our minor */
usb_deregister_dev(interface, &skel_class);
/* decrement our usage count */
kref_put(&dev->kref);
up(&disconnect_sem);
}
Example: Using a lock to ensure safe access to kref_put