我正在尝试使用Linux softirq.有一个简单的程序使用linux / interrupt.h中定义的linux系统调用:

//

// Created by kivi on 24.09.16.

//

#include

#include

#include

#include

#define SHARED_IRQ 17

static int irq = SHARED_IRQ, my_dev_id, irq_counter = 0;

module_param( irq, int, S_IRUGO );

/* The interrupt handler */

static irqreturn_t xxx_interrupt( int irq, void *dev_id ) {

printk( KERN_INFO "In the top-half: counter = %d\n", irq_counter );

raise_softirq( XXX_SOFT_IRQ );

return IRQ_HANDLED;

}

/* The bottom half */

void xxx_analyze(struct softirq_action *str) {

irq_counter++;

printk( KERN_INFO "In the bottom-half: counter = %d\n", irq_counter );

}

static int __init my_init( void ) {

request_irq( irq, xxx_interrupt, 0, "xxx", NULL );

open_softirq( XXX_SOFT_IRQ, xxx_analyze);

printk( KERN_INFO "Successfully set softirq handler on IRQ %d\n", irq );

return 0;

}

static void __exit my_exit( void ) {

synchronize_irq( irq );

free_irq( irq, &my_dev_id );

printk( KERN_INFO "Successfully unloading, irq_counter = %d\n", irq_counter );

}

module_init( my_init );

module_exit( my_exit );

MODULE_LICENSE( "GPL v2" );

当我尝试编译此模块时,出现链接器错误,未定义函数open_softirq()和raise_softirq():

kivi@kivi-pc:~/sp_labs/irq_exc/softirq$make

make -C /lib/modules/4.7.5-custom/build M=/home/kivi/sp_labs/irq_exc/softirq modules

make[1]: Entering directory '/home/kivi/Downloads/linux-4.7.5'

Building modules, stage 2.

MODPOST 1 modules

WARNING: "open_softirq" [/home/kivi/sp_labs/irq_exc/softirq/softirq.ko] undefined!

WARNING: "raise_softirq" [/home/kivi/sp_labs/irq_exc/softirq/softirq.ko] undefined!

make[1]: Leaving directory '/home/kivi/Downloads/linux-4.7.5'

有趣的是,函数request_irq()e.t.c.也在interrupt.h文件中定义,但它们不会引起任何问题.

这是我的Makefile:

obj-m += softirq.o

all:

make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:

make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

所以任何人都可以帮助我解决我的问题.

附言我用我的问题搜索了一下,发现了一些建议,建议我在编译时添加KBUILD_EXTRA_SYMBOLS = *模块路径* / Module.symvers,但这没有帮助.

解决方法:

问题在于,open_softirq和raise_softirq函数未导出,因此您无法链接到它们.导出的函数用EXPORT_SYMBOL或EXPORT_SYMBOL_GPL宏标记.

另一方面,您将看到如何导出request_irq(实际上,request_threaded_irq是inlined,其中is导出了).

您可以找到有关EXPORT_SYMBOL宏的大量信息.例如,here’s来自Robert Love的解释.

现在,您可能想知道为什么不导出这些功能.好吧,softirqs是一种低级机制,旨在供其他更高级别的设施使用,因此其目的是防止其在非核心内核代码中使用.

模块应改为使用更高级别的设施(例如计时器).

检查内核有多少softirqs用户很有趣.

$git grep open_softirq

block/blk-softirq.c: open_softirq(BLOCK_SOFTIRQ, blk_done_softirq);

include/linux/interrupt.h:extern void open_softirq(int nr, void (*action)(struct softirq_action *));

kernel/rcu/tiny.c: open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);

kernel/rcu/tree.c: open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);

kernel/sched/fair.c: open_softirq(SCHED_SOFTIRQ, run_rebalance_domains);

kernel/softirq.c:void open_softirq(int nr, void (*action)(struct softirq_action *))

kernel/softirq.c: open_softirq(TASKLET_SOFTIRQ, tasklet_action);

kernel/softirq.c: open_softirq(HI_SOFTIRQ, tasklet_hi_action);

kernel/time/timer.c: open_softirq(TIMER_SOFTIRQ, run_timer_softirq);

lib/irq_poll.c: open_softirq(IRQ_POLL_SOFTIRQ, irq_poll_softirq);

net/core/dev.c: open_softirq(NET_TX_SOFTIRQ, net_tx_action);

net/core/dev.c: open_softirq(NET_RX_SOFTIRQ, net_rx_action);

才十二岁!

这种模式在内核中重复:维护者认为较低级别的内容不会导出,仅用于核心内核代码.

标签:linux-kernel,c-3,linux

来源: https://codeday.me/bug/20191118/2025855.html

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐