用 unlocked_ioctl() 取代 ioctl()
呼叫 ioctl() 會先用 lock_kernel() 來 lock,而呼叫 unlocked_ioctl() 沒有 lock ,unlocked_ioctl() 需自行確保有無問題,例如用 per-driver 或 per-device 的 mutexes 取代。unlocked_ioctl() 不再提供inode參數,但可以透過 filp->f_dentry->d_inode 取得。
lock_kernel()/unlock_kernel() 是 Big Kernel Lock (BKL),在 Linux v2.6.39 deprecated。
參考
#if HAVE_UNLOCKED_IOCTL
#include <linux/mutex.h>
#else
#include <linux/smp_lock.h>
#endif
.
.
.
#if HAVE_UNLOCKED_IOCTL
mutex_lock(&fs_mutex);
#else
lock_kernel();
#endif
http://stackoverflow.com/questions/5956145/can-someone-help-me-replace-lock-kernel-on-a-block-device-driver
- compat_ioctl() 是 32-bit process 在 64-bit 系統呼叫 ioctl() 用,和 unlocked_ioctl() 一樣沒有 BKL。
- https://kernelnewbies.org/BigKernelLock:BKL 最終在 Linux v2.6.39 移除。Big Kernel Lock (BKL) 是想要 get rid of 的 old serialization method,用更 fine-grained locking 取代,如 mutex、spinlock 和 RCU。BKL 是 recursive lock,意思是可以從已經持有的 thread 取得。聽起來方便,但容易 introduces all sorts of bugs。另一個問題是,當 thread sleep,BKL 自動釋出。這避免 mutex 在有些情況 lock order 問題,但也 creates more problems because it makes it really hard to track what code is executed under the lock。
沒有留言:
張貼留言