Linux中与中断相关的内核数据结构

news2024/10/6 14:31:42

【摘要】本文树妖详细讲解了Linux中与中断相关的内核数据结构及其内部联系。

八、中断相关的数据结构

8.1 irq_desc

  • 用于表示IRQ描述符的结构定义如下:\linux-2.6.32.63\include\linux\irq.h
struct irq_desc 
{
    unsigned int        irq;	//中断号
    unsigned int        *kstat_irqs;	//2. irq stats per cpu
#ifdef CONFIG_INTR_REMAP
    struct irq_2_iommu  *irq_2_iommu;    //3. iommu with this irq
#endif
    //4. highlevel irq-events handler [if NULL, __do_IRQ()]
    irq_flow_handler_t    handle_irq;

    //5. low level interrupt hardware access
    struct irq_chip        *chip;

    //6. MSI descriptor
    struct msi_desc        *msi_desc;

    //7. per-IRQ data for the irq_chip methods
    void            *handler_data;

    //8. platform-specific per-chip private data for the chip methods, to allow shared chip implementations
    void            *chip_data;

    /* IRQ action list */
    //9. the irq action chain
    struct irqaction    *action;    

    /* IRQ status */
    //10. status information
    unsigned int        status;        

    /* nested irq disables */
    //11. disable-depth, for nested irq_disable() calls
    unsigned int        depth;        

    /* nested wake enables */
    //12. enable depth, for multiple set_irq_wake() callers
    unsigned int        wake_depth;    

    /* For detecting broken IRQs */
    //13. stats field to detect stalled irqs
    unsigned int        irq_count;    

    /* Aging timer for unhandled count */
    //14. aging timer for unhandled count
    unsigned long        last_unhandled;    

    //15. stats field for spurious unhandled interrupts
    unsigned int        irqs_unhandled;

    //16. locking for SMP
    spinlock_t        lock;
#ifdef CONFIG_SMP
    //17. IRQ affinity on SMP
    cpumask_var_t        affinity;

    //18. node index useful for balancing
    unsigned int        node;
#ifdef CONFIG_GENERIC_PENDING_IRQ
    //19. pending rebalanced interrupts
    cpumask_var_t        pending_mask;
#endif
#endif
    //20. number of irqaction threads currently running
    atomic_t        threads_active;

    //21. wait queue for sync_irq to wait for threaded handlers
    wait_queue_head_t       wait_for_threads;
#ifdef CONFIG_PROC_FS
    //22. /proc/irq/ procfs entry
    struct proc_dir_entry    *dir;
#endif
    //23. flow handler name for /proc/interrupts output
    const char        *name;
} ____cacheline_internodealigned_in_smp;
  • status描述了IRQ的当前状态,irq.h中定义了各种表示当前状态的常数,可用于描述IRQ电路当前的状态。每个常数表示位串中的一个置位的标志位(可以同时设置)
/*
 * IRQ line status.
 *
 * Bits 0-7 are reserved for the IRQF_* bits in linux/interrupt.h
 *
 * IRQ types
 */
#define IRQ_TYPE_NONE        0x00000000    /* Default, unspecified type */
#define IRQ_TYPE_EDGE_RISING    0x00000001    /* Edge rising type */
#define IRQ_TYPE_EDGE_FALLING    0x00000002    /* Edge falling type */
#define IRQ_TYPE_EDGE_BOTH (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
#define IRQ_TYPE_LEVEL_HIGH    0x00000004    /* Level high type */
#define IRQ_TYPE_LEVEL_LOW    0x00000008    /* Level low type */
#define IRQ_TYPE_SENSE_MASK    0x0000000f    /* Mask of the above */
#define IRQ_TYPE_PROBE        0x00000010    /* Probing in progress */

/* 
IRQ handler active - do not enter! 
与IRQ_DISABLED类似,IRQ_INPROGRESS会阻止其余的内核代码执行该处理程序
*/
#define IRQ_INPROGRESS        0x00000100    

/* 
IRQ disabled - do not enter!  
用户表示被设备驱动程序禁用的IRQ电路,标志通知内核不要进入处理程序
*/
#define IRQ_DISABLED        0x00000200    

/* 
IRQ pending - replay on enable 
当CPU产生一个中断但尚未执行对应的处理程序时,IRQ_PENDING标志位置位
*/
#define IRQ_PENDING        0x00000400    

/* 
IRQ has been replayed but not acked yet 
IRQ_REPLAY意味着该IRQ已经禁用,但此前尚有一个未确认的中断
*/
#define IRQ_REPLAY        0x00000800    
#define IRQ_AUTODETECT    0x00001000    /* IRQ is being autodetected */
#define IRQ_WAITING       0x00002000    /* IRQ not yet seen - for autodetection */

/* 
IRQ level triggered 
用于Alpha和PowerPC系统,用于区分电平触发和边沿触发的IRQ
*/
#define IRQ_LEVEL        0x00004000    

/* 
IRQ masked - shouldn't be seen again 
为正确处理发生在中断处理期间的中断,需要IRQ_MASKED标志位
*/
#define IRQ_MASKED        0x00008000    

/* 
IRQ is per CPU 
某个IRQ只能发生在一个CPU上时,将设置IRQ_PER_CPU标志位,在SMP系统中,该标志使几个用于防止并发访问的保护机制变得多余
*/
#define IRQ_PER_CPU        0x00010000    
#define IRQ_NOPROBE        0x00020000    /* IRQ is not valid for probing */
#define IRQ_NOREQUEST      0x00040000    /* IRQ cannot be requested */
#define IRQ_NOAUTOEN       0x00080000    /* IRQ will not be enabled on request irq */
#define IRQ_WAKEUP         0x00100000    /* IRQ triggers system wakeup */
#define IRQ_MOVE_PENDING   0x00200000    /* need to re-target IRQ destination */
#define IRQ_NO_BALANCING   0x00400000    /* IRQ is excluded from balancing */
#define IRQ_SPURIOUS_DISABLED    0x00800000    /* IRQ was disabled by the spurious trap */
#define IRQ_MOVE_PCNTXT    0x01000000    /* IRQ migration from process context */
#define IRQ_AFFINITY_SET   0x02000000    /* IRQ affinity was set from userspace*/
#define IRQ_SUSPENDED      0x04000000    /* IRQ has gone through suspend sequence */
#define IRQ_ONESHOT        0x08000000    /* IRQ is not unmasked after hardirq */
#define IRQ_NESTED_THREAD  0x10000000    /* IRQ is nested into another, no own handler thread */

#ifdef CONFIG_IRQ_PER_CPU
	#define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU)
	#define IRQ_NO_BALANCING_MASK    (IRQ_PER_CPU | IRQ_NO_BALANCING)
#else
	#define CHECK_IRQ_PER_CPU(var) 0
	#define IRQ_NO_BALANCING_MASK    IRQ_NO_BALANCING
#endif

8.2 irq_chip

  • \linux-2.6.32.63\include\linux\irq.h
struct irq_chip 
{
    /*
    1. name for /proc/interrupts
    包含一个短的字符串,用于标识硬件控制器
        1) IA-32: XTPIC
        2) AMD64: IO-APIC
    */
    const char    *name;

    //2. start up the interrupt (defaults to ->enable if NULL),用于第一次初始化一个IRQ,startup实际上就是将工作转给enable
    unsigned int    (*startup)(unsigned int irq);

    //3. shut down the interrupt (defaults to ->disable if NULL)
    void        (*shutdown)(unsigned int irq);

    //4. enable the interrupt (defaults to chip->unmask if NULL)
    void        (*enable)(unsigned int irq);

    //5. disable the interrupt (defaults to chip->mask if NULL)
    void        (*disable)(unsigned int irq);

    //6. start of a new interrupt
    void        (*ack)(unsigned int irq);

    //7. mask an interrupt source
    void        (*mask)(unsigned int irq);

    //8. ack and mask an interrupt source
    void        (*mask_ack)(unsigned int irq);

    //9. unmask an interrupt source
    void        (*unmask)(unsigned int irq);

    //10. end of interrupt - chip level
    void        (*eoi)(unsigned int irq);

    //11. end of interrupt - flow level
    void        (*end)(unsigned int irq);

    //12. set the CPU affinity on SMP machines
    int        (*set_affinity)(unsigned int irq, const struct cpumask *dest);

    //13. resend an IRQ to the CPU
    int        (*retrigger)(unsigned int irq);

    //14. set the flow type (IRQ_TYPE_LEVEL/etc.) of an IRQ
    int        (*set_type)(unsigned int irq, unsigned int flow_type);

    //15. enable/disable power-management wake-on of an IRQ
    int        (*set_wake)(unsigned int irq, unsigned int on);

    //16. function to lock access to slow bus (i2c) chips
    void        (*bus_lock)(unsigned int irq);

    //17. function to sync and unlock slow bus (i2c) chips
    void        (*bus_sync_unlock)(unsigned int irq);

    /* Currently used only by UML, might disappear one day.*/
#ifdef CONFIG_IRQ_RELEASE_METHOD
    //18. release function solely used by UML
    void        (*release)(unsigned int irq, void *dev_id);
#endif
    /*
     * For compatibility, ->typename is copied into ->name.
     * Will disappear.
     */
    //19. obsoleted by name, kept as migration helper
    const char    *typename;
};
  • 该结构需要考虑内核中出现的各个IRQ实现的所有特性。因此,一个该结构的特定实例,通常只定义所有可能方法的一个子集,下面以IO-APIC、i8259A标准中断控制器作为例子:

    • \linux-2.6.32.63\arch\x86\kernel\io_apic.c

      static struct irq_chip ioapic_chip __read_mostly = {
          .name        = "IO-APIC",
          .startup    = startup_ioapic_irq,
          .mask        = mask_IO_APIC_irq,
          .unmask        = unmask_IO_APIC_irq,
          .ack        = ack_apic_edge,
          .eoi        = ack_apic_level,
      #ifdef CONFIG_SMP
          .set_affinity    = set_ioapic_affinity_irq,
      #endif
          .retrigger    = ioapic_retrigger_irq,
      };
      
    • \linux-2.6.32.63\arch\alpha\kernel\irq_i8259.c

      struct irq_chip i8259a_irq_type = {
          .name        = "XT-PIC",
          .startup    = i8259a_startup_irq,
          .shutdown    = i8259a_disable_irq,
          .enable        = i8259a_enable_irq,
          .disable    = i8259a_disable_irq,
          .ack        = i8259a_mask_and_ack_irq,
          .end        = i8259a_end_irq,
      };
      
  • 可以看到,运行该设备,只需要定义所有可能处理程序函数的一个子集

8.3 irqaction

  • struct irqaction结构是struct irq_desc中和IRQ处理函数相关的成员结构
struct irqaction 
{
    //1. name、dev_id唯一地标识一个中断处理程序
    irq_handler_t           handler;
    void                    *dev_id;

    void __percpu           *percpu_dev_id;

    //2. next用于实现共享的IRQ处理程序
    struct irqaction        *next;
    irq_handler_t           thread_fn;
    struct task_struct      *thread;
    unsigned int            irq;

    //3. flags是一个标志变量,通过位图描述了IRQ(和相关的中断)的一些特性,位图中的各个标志位可以通过预定义的常数访问
    unsigned int            flags;
    unsigned long           thread_flags;
    unsigned long           thread_mask;

    //4. name是一个短字符串,用于标识设备
    const char              *name;
    struct proc_dir_entry   *dir;
} ____cacheline_internodealigned_in_smp;
  • 几个irqaction实例聚集到一个链表中,链表的所有元素都必须处理同一个IRQ编号,在发生一个共享中断时,内核扫描该链表找出中断实际上的来源设备

image-20230505233103971

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/589165.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ipad可以使用其他品牌的手写笔吗?2023年电容笔推荐

现在,人们的生活越来越智能化,有些人已经用平板电脑取代了传统的笔记本。我发现用ipad不管是用来画画还是做笔记非常方便,但是苹果Pencil对于大多数人来说都是昂贵的。据我所知,如果仅仅是为了记录,而不是为了画画的话…

他是98年的卷王,我真的玩不过他····

现在的小年轻真的卷得过分了。前段时间我们公司来了个98年的,工作没两年,跳槽到我们公司起薪18K,都快接近我了。后来才知道人家是个卷王,从早干到晚就差搬张床到工位睡觉了。 最近和他聊了一次天,原来这位小老弟家里…

PKI 基础知识

摘要 本白皮书介绍了加密和公钥基本结构(PKI)的概念和使用 Microsoft Windows 2000 Server 操作系统中的证书服务的基础知识。如果您还不熟悉加密和公钥技术,先阅读本白皮书将有助于理解 Windows 2000 Web 站点上有关这些主题的其它技术白皮书。 引言 Microsoft …

玩转VLAN间路由,教你3个好方法

我的网工朋友大家好啊 在现实网络中,经常会遇到需要跨VLAN相互访问的情况。 很多网工通常会选择一些方法,来实现不同VLAN间主机的相互访问,例如单臂路由。 但是,单臂路由技术中由于存在一些局限性,比如带宽、转发效…

NodeJS基础到入门EXPS⑥

文章目录 ✨文章有误请指正,如果觉得对你有用,请点三连一波,蟹蟹支持😘前言Express框架 Router路由NEST 方法路由端点使用回调函数数组处理路由使用混合使用函数和函数数组处理路由中间件的分类及用法 1、应用级中间件 2、路…

使用 python 制作自动填写问卷星问卷调查程序

目录 前言环境:代码展示尾语 💝 前言 嗨喽~大家好呀,这里是魔王呐 ❤ ~! 你的问卷星任务还没做完吗?今天教你如何快速把问卷星调查任务给完成。 环境: anaconda5.2.0(python3.6.8) 编辑器: p…

ASEMI代理KY可控硅BT169的工作原理及应用领域

编辑-Z 本文主要介绍了可控硅BT169的工作原理及其在各个领域的用。首先,我们将详细阐述可控硅BT169的工作原理,包括结构特点、工作过程等;其次,我们将探讨可控硅BT169在家用电器、工业控制、电力电子等领域的应用。 1、可控硅BT1…

RSA加密 多线程读写不安全

转自:(一场开源 RSA 库引发的“血案”) 导读 RSA 加密算法是一种非对称加密算法,该算法极为可靠,在现有技术条件下,很难破解,因此在软件开发中被广泛使用。你不必担心,本文不会介绍…

如何Debug调试Android程序

当开发过程中遇到一些奇怪的bug,但又迟迟定位不出来原因是什么的时候,最好的解决办法就是调试了。调试允许我们逐行地执行代码,并可以实时观察内存中的数据,从而能够比较轻易地查出问题的原因。总结一下使用Android Studio来调试A…

又双叒添新证书:上海斯歌通过ISO9001和ISO27001认证

近期,上海斯歌顺利通过权威机构审查,正式成为ISO9001质量管理体系和ISO27001信息管理安全体系双重认证企业。 可以说ISO9001及ISO27001的认证,既是斯歌坚持管理标准化、程序化、规范化的成果;也是国际标准化组织(ISO&a…

Vue3通透教程【十六】TS自动编译

文章目录 🌟 写在前面🌟 自动编译🌟 编译器的配置文件🌟 写在最后 🌟 写在前面 专栏介绍: 凉哥作为 Vue 的忠实 粉丝输出过大量的 Vue 文章,应粉丝要求开始更新 Vue3 的相关技术文章&#xff0…

Apache的配置与应用(构建web、日志分割及AWStats分析系统)

Apache的配置与应用 一、构建虚拟Web主机二、httpd服务支持的三种虚拟机类型1、基于域名的虚拟主机2、基于IP地址的虚拟主机3、基于端口的虚拟主机 三、构建web虚拟目录与用户授权限制1、创建用户认证数据文件2、添加用户授权配置3、验证用户访问权限4、在客户机中浏览器访问 四…

F牌独立站都有哪些收款方式?各有什么优缺点?

最近几个月以来,FP独立站的收款支付问题变得非常焦灼,不少跨境卖家忧心忡忡,害怕自己收不了款血本无归。今天,我跟大家介绍几种FP独立站的收款方式,以及解析他们各有哪些优缺点,方便卖家选择。 一、TT电汇 …

Go GPM 调度器介绍

Go GPM 调度器介绍 1 简介 ​ 这几天在学习Go的GPM机制,于是就整理了一下收集的资料分享给大家,文章末尾有原文链接。主要介绍了Go在运行时调度器的基本实现逻辑和演变过程。 ​ 2 什么是Go调度器 ​ Go调度器很轻量也很简单,足以撑起gorout…

数据结构基础-数组

2.1 数组 概述 定义 在计算机科学中,数组是由一组元素(值或变量)组成的数据结构,每个元素有至少一个索引或键来标识 In computer science, an array is a data structure consisting of a collection of elements (values or v…

在 Linux 中启动时自动启动 Docker 容器的 2 种方法

Docker 是一种流行的容器化平台,允许开发人员将应用程序及其依赖项打包成一个独立的容器,以便在不同环境中运行。在 Linux 系统中,我们可以通过配置来实现在系统启动时自动启动 Docker 容器。本文将详细介绍两种方法,以便您了解如…

软件测试面试了一个00后,让我见识到了什么是内卷届的天花板

公司前段缺人,也面了不少测试,结果竟然没有一个合适的。一开始瞄准的就是中级的水准,也没指望来大牛,提供的薪资也不低,面试的人很多,但平均水平很让人失望。令我印象最深的是一个00后测试员,他…

Android bitmap保姆级教学

1. 认识Bitmap Bitmap是一个final类,因此不能被继承。Bitmap只有一个构造方法,且该构造方法是没有任何访问权限修饰符修饰,也就是说该构造方法是friendly,但是谷歌称Bitmap的构造方法是private(私有的)&am…

【C++】this 指针的概念

欢迎来到博主 Apeiron 的博客,祝您旅程愉快 ! 时止则止,时行则行。动静不失其时,其道光明。 目录 1、缘起 2、this 指针的用途 2.1、用途 1 2.1.1 解法 1 2.1.2 解法 2 2.2、用途 2 2.3、用途 3 3、总结 1、缘起 我…

网络编程_TCP/IP四层协议分层

网络编程_TCP/IP四层协议分层 1. OSI七层协议模型 (open system interconnection)与TCP/IP四层协议分层2. 协议封装3. TCP 协议头部4.三次握手5.滑动窗口正常情况丢包情况 6.四次挥手 1. OSI七层协议模型 (open system interconnection)与TCP/IP四层协议分层 OSI七层协议模型 (…