Linux内核中断模块之中断描述符分配

对于一个系统来说,管理中断描述符也是一个值得考量的问题,如果中断个数有限,并且分布连续,则使用一个数组
较为简单,而如果中断分散,则采用动态分配较为可观,内核在配置CONFIG_SPARSE_IRQ时,采用动态分配中断
描述符。在非配置情形下则使用一个固定数组跟踪所有的中断描述符,即中断描述符表,数组形式如下:
struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
 [0 ... NR_IRQS-1] = {
  .handle_irq = handle_bad_irq,
  .depth  = 1,
  .lock  = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock),
 }
};
显然这里通过NR_IRQS定义了数组长度。
这种情形下,所有的中断描述符管理非常简单。
 
1. IRQ号到中断描述符
struct irq_desc *irq_to_desc(unsigned int irq)
{
 return (irq < NR_IRQS) ? irq_desc + irq : NULL;
}
EXPORT_SYMBOL(irq_to_desc);
 
2. 分配连续多个中断描述符

static inline int alloc_descs(unsigned int start, unsigned int cnt, int node,          const struct cpumask *affinity,          struct module *owner) {  u32 i;

 for (i = 0; i < cnt; i++) {   struct irq_desc *desc = irq_to_desc(start + i);

  desc->owner = owner;  }  return start; }

3. 初始化函数

int __init early_irq_init(void) {  int count, i, node = first_online_node;  struct irq_desc *desc;

 init_irq_default_affinity();

 printk(KERN_INFO "NR_IRQS:%d\n", NR_IRQS);

 desc = irq_desc;  count = ARRAY_SIZE(irq_desc);

 for (i = 0; i < count; i++) {   desc[i].kstat_irqs = alloc_percpu(unsigned int);   alloc_masks(&desc[i], GFP_KERNEL, node);   raw_spin_lock_init(&desc[i].lock);   lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);   desc_set_defaults(i, &desc[i], node, NULL, NULL);  }  return arch_early_irq_init(); }

4. 释放IRQ描述符

static void free_desc(unsigned int irq) {  struct irq_desc *desc = irq_to_desc(irq);  unsigned long flags;

 raw_spin_lock_irqsave(&desc->lock, flags);  desc_set_defaults(irq, desc, irq_desc_get_node(desc), NULL, NULL);  raw_spin_unlock_irqrestore(&desc->lock, flags); }

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值