发博文
todaygood

todaygood.blog.chinaunix.net

存储,Linux   
个人资料
  • 博客访问:3072649
  • 博文数量:392
  • 博客积分:20848
  • 博客等级:上将
  • 关注人气: 9
  • 注册时间:2006-09-30 13:40:58
订阅我的博客
  • 订阅
  • 订阅到鲜果
  • 订阅到抓虾
  • 订阅到Google
字体大小: 博文
tasklet笔记(1) (2007-01-05 21:43)
分类: linux_Kernel

驱动程序使用tasklet机制
转自:http://blog.chinaunix.net/u/15169/showart.php?id=82989
驱 动程序在初始化时,通过函数task_init建立一个tasklet,然后调用函数tasklet_schedule将这个tasklet放在 tasklet_vec链表的头部,并唤醒后台线程ksoftirqd。当后台线程ksoftirqd运行调用__do_softirq时,会执行在中断 向量表softirq_vec里中断号TASKLET_SOFTIRQ对应的tasklet_action函数,然后tasklet_action遍历 tasklet_vec链表,调用每个tasklet的函数完成软中断操作。
 
下面对函数tasklet_init和tasklet_schedule分析:
   函数tasklet_init初始化一个tasklet,其参数t是tasklet_struct结构描述的tasklet,参数(*func)是软中断响应函数。
void tasklet_init(struct tasklet_struct *t,
    void (*func)(unsigned long), unsigned long data)
{
 t->next = NULL;
 t->state = 0;
 atomic_set(&t->count, 0);
 t->func = func;
 t->data = data;
}
驱动程序调用函数tasklet_schedule来运行tasklet。
static inline void tasklet_schedule(struct tasklet_struct *t)
{
 if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state))
  __tasklet_schedule(t);
}
函数__tasklet_schedule得到当前CPU的tasklet_vec链表,并执行TASKLET_SOFTIRQ软中断。
void fastcall __tasklet_schedule(struct tasklet_struct *t)
{
 unsigned long flags;
 local_irq_save(flags);
 t->next = __get_cpu_var(tasklet_vec).list;
 __get_cpu_var(tasklet_vec).list = t;
 raise_softirq_irqoff(TASKLET_SOFTIRQ);
 local_irq_restore(flags);
}
函数raise_softirq_irqoff设置软中断nr为挂起状态,并在没有中断时唤醒线程ksoftirqd。函数raise_softirq_irqoff必须在关中断情况下运行。
inline fastcall void raise_softirq_irqoff(unsigned int nr)
{
 __raise_softirq_irqoff(nr);
 /*
  * If we're in an interrupt or softirq, we're done
  * (this also catches softirq-disabled code). We will
  * actually run the softirq once we return from
  * the irq or softirq.
  *
  * Otherwise we wake up ksoftirqd to make sure we
  * schedule the softirq soon.
  */
 if (!in_interrupt())
  wakeup_softirqd();
}
 
下面是tasklet_struct和softirq_action的定义。
struct tasklet_struct
{
 struct tasklet_struct *next;
 unsigned long state;
 atomic_t count;
 void (*func)(unsigned long);
 unsigned long data;
};
 
struct softirq_action
{
 void (*action)(struct softirq_action *);
 void *data;
};
 
摘录于《Linux内核分析及编程>


http://hi.baidu.com/ryderlee/blog/item/ceeec316e8d1f318962b431a.html
 1.Tasklet 可被hi-schedule和一般schedule,hi-schedule一定比一般shedule早运行;
   2.同一个Tasklet可同时被hi-schedule和一般schedule;
   3.同一个Tasklet若被同时hi-schedule多次,等同于只hi-shedule一次,因为,在tasklet未 运行时,hi-shedule同一tasklet无意义,会冲掉前一个tasklet;
   4.对于一般shedule, 同上。
   5.不同的tasklet不按先后shedule顺序运行,而是并行运行。
 6.Tasklet的运行时间:
         a.若在中断中schedule tasklet, 中断结束后立即运行;
         b.若CPU忙,在不在此次中断后立即运行;
         c.不在中断中shedule tasklet;
         d.有软或硬中断在运行;
         e.从系统调用中返回;(仅当process闲时)
         f.从异常中返回;
         g.调试程序调度。(ksoftirqd运行时,此时CPU闲)
 7.Taskelet的hi-schedule 使用softirq 0, 一般schedule用softirq 30;
 8.Tasklet的运行时间最完在下一次time tick 时。(因为最外层中断一定会运行使能的softirq, 面不在中断中便能或shedule的softirq在下一定中断后一定会被调用。)

  综上: Tasklet 能保证的运行时间是(1000/HZ)ms,一般是10ms。Tasklet在CPU闲或中断后被调用。

[发评论] 评论 重要提示:警惕虚假中奖信息!
  • chinaunix网友 2009-06-24 09:56
    写的不错,抢沙发
  • chinaunix网友 2009-06-24 09:56
    写的不错,抢沙发
亲,您还没有登录,请[登录][注册]后再进行评论