Forest_Leo
驱动牛犊
驱动牛犊
  • 注册日期2004-02-26
  • 最后登录2004-11-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1368回复:9

请教内核中的信号灯的问题(高手请进)????!!

楼主#
更多 发布于:2004-04-20 15:37
如题,俺要做一个驱动,采用DMA方式(plx9054)与PCI卡通讯,现在遇到这样一个问题,即在用户层同时并发1024个进程,而每个进程请求的都是大数据量的运算,我如何实现在驱动中的互斥呢?

我的想法是这样的,即每个进程的每一次数据运算请求都通过ioctl的调用,率先探测当前板卡的DMA通道是否空闲,如果不空闲,则该请求被投入内核的一个FIFO对列中睡眠,直到空闲被唤醒。

问题是:

1.我如果要判断是否空闲,必须判断我自己的设备结构中的一个变量的值,如  mydev->dma0_idle,可是我如何保证我在判断这个值的时候,这个值不会被修改,比如,我正在判断的时候,某个进程的运算结束,最后一次DMA的中断被触发,这时候我肯定要在中断处理程序中(tasklet)将这个 mydev->dma0_idle 重新置位空闲,而此时另外一个进程的请求很有可能正在判断这个值是什么,我如何控制这种情况?


2.上面我说的情况,我听说可以通过内核提供的 semaphore或spinlock来做,可是前者据说不能用于中断环境,我不知道是什么
意识,如果我上面那种情况下用semaphore,不知道算不算中断环境?而后者,据说影响效率,且容易死锁,而且据说用在SMP系统的比较多,所以归根到底还是问题一,我该怎么办???!!!


3.如果我说的要求能使用semaphore,那么听说他可以自己排队等候
那是不是说我不需要自己在内核重新定义一个链表了,只需要用semaphore提供的排队就可以了


呵呵呵呵,问得比较乱,可能理解就有问题,恳请高手体谅初学者,耐心看完,盼复!!!!多谢!!!

另注:千万别光说一句“自己看书!”就拉倒这样的话,俺不是懒人,俺看了很多帖子和资料也没想通,才问得,DX们多少给点提示也好,可能俺悟性太差了吧!!

再次感谢,能回答这个问题的DX
start
驱动小牛
驱动小牛
  • 注册日期2001-11-05
  • 最后登录2010-09-03
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望27点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-04-20 16:18
非常关注你的话题,我使用semaphore 信号量,运行没有问题,但是好像在处理一些异常时候,有问题。

比如,我应用层一个死循环来测试板卡,如果中断这个程序,可能导致控制台死机,我不得不切换控制台来重新进行测试。

你呢,目前有什么好办法??
second
Forest_Leo
驱动牛犊
驱动牛犊
  • 注册日期2004-02-26
  • 最后登录2004-11-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-04-20 18:03
非常关注你的话题,我使用semaphore 信号量,运行没有问题,但是好像在处理一些异常时候,有问题。

比如,我应用层一个死循环来测试板卡,如果中断这个程序,可能导致控制台死机,我不得不切换控制台来重新进行测试。

你呢,目前有什么好办法??


你说的这个问题我怀疑是不是由于你使用了down 而不是down_interruptible()造成的,改成后者试试
Forest_Leo
驱动牛犊
驱动牛犊
  • 注册日期2004-02-26
  • 最后登录2004-11-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-04-20 19:19
哎,还是没人理我,我提议下我自己的想法,高手给点建议总可以了吧?

由于我的驱动有可能向SMP系统拓展,并且要与BH或TASKLET打交道,因此我肯定不会用semaphore了

我的想法如下(程序框架来源于我的概要设计):

ioctl()
{

   /* I think bh or tasklet can interrupt the ioctl ,so I use spin_lock_bh . But I think spin_lock_bh can not close hard irq .Hard irq do not modify dma0_idle,it just let tasklet or bh do it ,so I think spin_lock_bh is enough  */
   spin_lock_bh();  

   if (mydev->dma0_idle) return; /* 1 means dma 0 channel can be used */
  
   spin_unlock_bh();  /* must be unlock before wait*/


   wait_event_interruptible(mydev->res_wait,mydev->dma0_idle);

   return;
    
}

bh()
{
   /* I think hard irq will interrupt bh or tasklet ,so  I use spin_lock_irqsave */
   spin_lock_irqsave();

   mydev->dma0_idle = 1;

   wake_up_interruptible(mydev->res_wait); /* I think it can be used before unlock */
  
   spin_unlock_irqrestore();
}

请DX们注意我上面“I think....”的部分,我认为比较easy,没有翻译过来,直接从我的概要设计里copy过来了,DX们看看我这些地方有什么死锁或无效锁(即无法达到我想要的目的)的潜在问题吗???

拜托!!急!!
Forest_Leo
驱动牛犊
驱动牛犊
  • 注册日期2004-02-26
  • 最后登录2004-11-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-04-20 19:26
更正一个地方,我自己发现设计的有问题了,不过不是根本问题,所以还请DX们继续指点

ioctl中作判断的地方,应该如下:

if (mydev->dma0_idle) { /* 1 means dma 0 channel can be used */

mydev->dma0_idle = 0;
spin_unlock_bh();
return;
}
rainyss
驱动牛犊
驱动牛犊
  • 注册日期2004-04-05
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-04-20 23:03
用spin_lock()自已看......源代码.
Forest_Leo
驱动牛犊
驱动牛犊
  • 注册日期2004-02-26
  • 最后登录2004-11-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-04-21 10:10
用spin_lock()自已看......源代码.


我的理解用spin_lock是不行的吧?

应该是spin_unlock_bh 和 spin_lock_irqsave 吧
rainyss
驱动牛犊
驱动牛犊
  • 注册日期2004-04-05
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-04-21 20:15
一年多没用我也记不清了,但是是用spin_lock_irqsave()没错,反正你照着现成的驱动里用就行了.只不过要注意的是,如果因为设计失误引起spin_lock被死锁,那么你的整个系统前台会被完全锁住,从效果上来说与死机没有区别.切记切记.
再一个就是编译的问题,单CPU的spin_lock与SMP的目标代码是完全不同的,所以决不能共用同一个驱动.
rainyss
驱动牛犊
驱动牛犊
  • 注册日期2004-04-05
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-04-21 20:24
所谓\"中断环境\",也就是回调过程(call back),linux设计了两种过程,一种是由上到下调用,一种是由下到上,这两种过程通常又叫做\"上半部\"与\"下半部\".上半部用于排队,发送队列,然后休眠等待,而唤醒由下半部即回调过程完成.这就意味着,下半部是从中断程序调用过来的,不能使用任何排斥中断的操作.回调过程可以看作是资源独占过程.
知道了这一点,相信哪里要用什么类型的互斥量就很清楚了吧?
Forest_Leo
驱动牛犊
驱动牛犊
  • 注册日期2004-02-26
  • 最后登录2004-11-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-04-22 09:43
多谢多谢!!!

我会尽快作试验来测试各种情况,最后选定一种至少用起来是稳定的方法
游客

返回顶部