博客
关于我
中断管理基础学习笔记 - 5.2 ARM64高层中断处理
阅读量:174 次
发布时间:2019-02-28

本文共 2758 字,大约阅读时间需要 9 分钟。

gic_handle_irq 与 中断 处理流程

前言

本专题主要介绍ARM64架构下的中断管理机制,重点分析Linux内核中gic_handle_irq函数的处理流程。以下将从gic_handle_irq的实现细节、中断处理机制以及相关优化措施等方面展开讨论。

gic_handle_irq 函数

gic_handle_irq是ARM64体系结构下处理中断的核心函数。该函数主要负责从底层硬件中断处理进入内核中断处理逻辑,并通过调用handle_domain_irq完成中断的上下文切换。

gic_handle_irq 内部逻辑

gic_handle_irq的实现代码如下:

static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs){    struct gic_chip_data *gic = &gic_data[0];    void __iomem *cpu_base = gic_data_cpu_base(gic);    do {        irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK);        irqnr = irqstat & GICC_IAR_INT_ID_MASK;        if (unlikely(irqnr >= 1020))            break;        if (static_branch_likely(&supports_deactivate_key))            writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);        isb();        if (irqnr <= 15)            smp_rmb();        this_cpu_write(sgi_intid, irqstat);        handle_domain_irq(gic->domain, irqnr, regs);    } while (1);}

while 循环退出条件

while (1) 循环的退出条件基于以下逻辑:当GIC的GICC_IAR寄存器中的所有位都为1时,中断处理完成,进入下一个中断处理阶段。

handle_domain_irq 调用

handle_domain_irq 是一个通用的中断处理函数,主要负责将硬中断转换为软中断,并根据中断类型(如SGI中断或普通中断)分别调用相应的处理函数。

handle_domain_irq 实现

int handle_domain_irq(struct irq_domain *domain, unsigned int hwirq, struct pt_regs *regs){    __handle_domain_irq(domain, hwirq, true, regs);    unsigned int irq = hwirq;    irq_enter();    irq = irq_find_mapping(domain, hwirq);    generic_handle_irq(irq);    irq_exit();}

中断处理流程

  • 读取GICC_IAR寄存器:通过readl_relaxed读取中断状态,完成中断的ACK操作。
  • 处理SGI中断:对于SGI中断(ID <= 15),执行taskletworkqueue等处理。
  • 调用domain的处理函数:将硬中断转换为软中断,并调用对应的中断处理函数。
  • irq_enter 与 irq_exit

    irq_enterirq_exit 分别用于进入和退出中断上下文。

    irq_enter

    void irq_enter(void){    rcu_irq_enter();    irq_enter_rcu();    if (is_idle_task(current) && !in_interrupt())    {        local_bh_disable();        tick_irq_enter();        _local_bh_enable();    }    __irq_enter();    account_irq_enter_time(current);    preempt_count_add(HARDIRQ_OFFSET);    __preempt_count_add(val);    u32 pc = READ_ONCE(current_thread_info()->preempt.count);    pc += val;    WRITE_ONCE(current_thread_info()->preempt.count, pc);    lockdep_hardirq_enter();}

    irq_exit

    void irq_exit(void){    __irq_exit_rcu();    local_irq_disable();    account_irq_exit_time(current);    preempt_count_sub(HARDIRQ_OFFSET);    if (!in_interrupt() && local_softirq_pending())    {        invoke_softirq();    }    tick_irq_exit();    rcu_irq_exit();    lockdep_hardirq_exit();}

    中断管理优化

    软中断管理

    local_softirq_pending 用于检查是否有软中断(如taskletworkqueue)等待处理。通过检查local_softirq_pending_ref,可以快速判断中断状态。

    中断上下文管理

    irq_enterirq_exit 函数通过修改preempt.count来管理中断上下文。preempt_count_addpreempt_count_sub 用于递增和递减硬中断计数,同时local_bh_disablelocal_bh_enable 用于管理软中断。

    总结

    通过分析gic_handle_irq函数及其相关处理流程,可以清晰地了解ARM64体系结构下的中断管理机制。从硬中断到软中断的转换,再到中断上下文的管理,都体现了Linux内核对中断处理的高效设计。

    转载地址:http://csqd.baihongyu.com/

    你可能感兴趣的文章
    nginx+mysql+redis+mongdb+rabbitmq 自动化部署脚本
    查看>>
    nginx+php的搭建
    查看>>
    nginx+tomcat+memcached
    查看>>
    Nginx+Tomcat实现动静分离
    查看>>
    nginx+Tomcat性能监控
    查看>>
    nginx+uwsgi+django
    查看>>
    nginx+vsftp搭建图片服务器
    查看>>
    Nginx-http-flv-module流媒体服务器搭建+模拟推流+flv.js在前端html和Vue中播放HTTP-FLV视频流
    查看>>
    nginx-vts + prometheus 监控nginx
    查看>>
    nginx: [emerg] getpwnam(“www”) failed 错误处理方法
    查看>>
    nginx: [emerg] the “ssl“ parameter requires ngx_http_ssl_module in /usr/local/nginx/conf/nginx.conf:
    查看>>
    nginx:Error ./configure: error: the HTTP rewrite module requires the PCRE library
    查看>>
    Nginx、HAProxy、LVS
    查看>>
    Nginx下配置codeigniter框架方法
    查看>>
    Nginx中使用expires指令实现配置浏览器缓存
    查看>>
    nginx中配置root和alias的区别
    查看>>
    nginx主要流程(未完成)
    查看>>
    Nginx之二:nginx.conf简单配置(参数详解)
    查看>>
    Nginx从入门到精通
    查看>>
    Nginx代理websocket配置(解决websocket异常断开连接tcp连接不断问题)
    查看>>