我已经写了一个小驱动程序来读取一些数据,并将其提供给用户。 我的驱动程序可以被多个应用程序使用,即它是一个可重入驱动程序,因此使用自旋锁。 但是我发现copy_to_user
不应该被保持为自旋锁。 在下面的代码中char_device_buf
是共享数据; 我必须保护它。 是否有任何机制,除了互斥使用旋转锁和使用copy_to_user
?
static ssize_t char_dev_read(struct file *file, char *buf, size_t lbuf, loff_t *ppos) { int maxbytes; /* number of bytes from ppos to MAX_LENGTH */ int bytes_to_do; /* number of bytes to read */ int nbytes; /* number of bytes actually read */ maxbytes = MAX_LENGTH - *ppos; if( maxbytes > lbuf ) bytes_to_do = lbuf; else bytes_to_do = maxbytes; if( bytes_to_do == 0 ) { printk("Reached end of device\n"); return -ENOSPC; /* Causes read() to return EOF */ } /* Tesing for accidental release */ // accidental_release(); printk(KERN_DEBUG "READER: trying for critical region lock \n"); spin_lock(&myspin);/*begin of critical region */ printk(KERN_DEBUG "READER : acquired lock: executing critical code\n"); nbytes = bytes_to_do - copy_to_user( buf, /* to */ char_device_buf + *ppos, /* from */ bytes_to_do ); /* how many bytes */ spin_unlock(&myspin); /* end of critical region */ *ppos += nbytes; return nbytes; }
copy_{to,from}_user
不应该在旋转锁内部使用的原因是这些函数可以睡眠。 想象一下这种情况(在单处理器的机器上):
mmap()
编辑一个文件 mmap()
编辑区域 copy_to_user
在该地址上导致页面错误 – 内存不存在,所以进程进入休眠状态,直到数据来自磁盘。 除非100%保证copy_{to,from}_user
不会导致段错误,否则不能使用自旋锁,而必须使用睡眠锁,而不是像“mutex_lock”那样。 睡眠锁对调度器产生控制,而自旋锁则不能。