Linux kernel 有人能帮我更换吗;锁定“U内核”;在块设备驱动程序上?

Linux kernel 有人能帮我更换吗;锁定“U内核”;在块设备驱动程序上?,linux-kernel,linux-device-driver,ioctl,Linux Kernel,Linux Device Driver,Ioctl,谢谢你看这篇文章。我正在尝试修补网络块设备驱动程序。如果您需要查看源代码,请访问http://code.ximeta.com 我注意到,从Linux2.6.37开始,lock_kernel()似乎已被弃用。我阅读了“ioctl()的新方法”,发现设备驱动程序现在应该在操作之前执行特定的锁定 因此,如果可能的话,我想要一些建议来取代这个 我在当前代码的block folder部分找到了两个我认为相关的部分 Source block->io.c ->c

谢谢你看这篇文章。我正在尝试修补网络块设备驱动程序。如果您需要查看源代码,请访问http://code.ximeta.com

我注意到,从Linux2.6.37开始,lock_kernel()似乎已被弃用。我阅读了“ioctl()的新方法”,发现设备驱动程序现在应该在操作之前执行特定的锁定

因此,如果可能的话,我想要一些建议来取代这个

我在当前代码的block folder部分找到了两个我认为相关的部分

Source 
      block->io.c
           ->ctrldev.c
我把每一个片段都放在这里供你们考虑

io.c包含一个对锁定内核的调用:

NDAS_SAL_API xbool     sal_file_get_size(sal_file file, xuint64* size)
{
    definitions and declarations etc..

lock_kernel();

#ifdef HAVE_UNLOCKED_IOCTL
    if (filp->f_op->unlocked_ioctl) {   
       some small statements

       error = filp->f_op->unlocked_ioctl(filp, BLKGETSIZE64, (unsigned long)size);

       actions if error or not etc.
   }
#endif

   unlock_kernel(); 
   return ret;
}
ctrldev.c包含主要io功能:

#include <linux/spinlock.h> // spinklock_t
#include <linux/semaphore.h> // struct semaphore
#include <asm/atomic.h> // atomic
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/ide.h>
#include <linux/smp_lock.h>
#include <linux/time.h>

......

int ndas_ctrldev_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
  lots of operations and functions. 

  return result;
}
现在我想转换它以避免使用lock_kernel()

根据我的理解,我将对前几节进行如下修改:

NDAS_SAL_API xbool     sal_file_get_size(sal_file file, xuint64* size)
{
    definitions and declarations etc..

#ifndef HAVE_UNLOCKED_IOCTL
    lock_kernel();
#endif

#ifdef HAVE_UNLOCKED_IOCTL
    if (filp->f_op->unlocked_ioctl) {   
       some small statements

       error = filp->f_op->unlocked_ioctl(filp, BLKGETSIZE64, (unsigned long)size);

       actions if error or not etc.
   }
#endif

#ifndef HAVE_UNLOCKED_IOCTL
   unlock_kernel(); 
#endif
   return ret;

}

#ifdef HAVE_UNLOCKED_IOCTL
long ndas_ctrldev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
#else
int ndas_ctrldev_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
#endif
{

#ifdef HAVE_UNLOCKED_IOCTL
  ! add some sort of lock here !
#endif

  lots of operations and functions. 

#ifdef HAVE_UNLOCKED_IOCTL
  ! add unlock statement here  !
#endif
  return result;
}

static struct file_operations ndasctrl_fops = {
    .write = ndas_ctrldev_write,
    .read = ndas_ctrldev_read,
    .open = ndas_ctrldev_open,
    .release = ndas_ctrldev_release,
#ifdef HAVE_UNLOCKED_IOCTL
    .unlocked_ioctl = ndas_ctrldev_ioctl, 
#else
    .ioctl = ndas_ctrldev_ioctl, 
#endif
};
因此,我想提出以下建议

  • 这看起来像是对的吗 过程

  • 我是否理解正确的移动方法 锁定io功能

  • 基于crtrldev.c中的包含,您可以 建议在顶部安装锁 你的头?(我试着研究一些 处理filp和filp的其他司机 锁定内核,但我是一个太多的 没有人能马上找到答案。)

  • 大内核锁(Big Kernel Lock,BKL)已经不推荐使用了——从2.6.39开始,它已经不存在了

    执行
    lock\u kernel()
    转换的方法是将其替换为每个驱动程序互斥锁。如果驱动程序足够简单,您可以简单地为驱动程序创建一个互斥锁,并通过互斥锁/解锁调用替换
    lock\u kernel()
    unlock\u kernel()
    的所有用法。但是,请注意,一些函数过去是在BKL(lock
    lock\u kernel()
    用于锁定)保持的情况下调用的;您还必须向这些函数添加锁定/解锁调用

    如果驱动程序可以递归地获取BKL,那么这将不起作用;如果是这种情况,您必须自己跟踪它以避免死锁(这是在
    reiserfs
    的转换过程中完成的,这在很大程度上取决于递归BKL行为以及它在睡眠时被丢弃的事实)

    转换为每个驱动程序互斥后的下一步是将其更改为使用每个设备互斥,而不是每个驱动程序互斥。

    以下是解决方案

    #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
    
    #如果解锁了IOCTL
    #包括
    #否则
    #包括
    #恩迪夫
    .
    . 
    . 
    #如果您解锁了IOCTL
    互斥锁(&fs\u互斥锁);
    #否则
    锁定内核();
    #恩迪夫
    

    这仅显示如何更换锁定调用。其他部分的结果正如我在上面关于unlocked_ioctl的问题部分中所猜测的那样。谢谢你的检查和帮助

    这个驱动程序中只有一个lock_内核实例。我想这意味着没有递归,在io.c中替换它就足够了。至于用互斥替换lock_内核,这是否意味着我会编写一个小函数,然后调用它,而不是lock_内核?或者我是否尝试链接到设备中现有的互斥锁?在ctrldev.c中有几个对互斥锁的引用。设备上也有一个旋转锁,但不称为旋转锁。如果我在ndas_ctrldev_ioctl函数中的每个可能操作都使用up()和down(),是否会考虑每个设备类型?
    #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