- 论坛徽章:
- 0
|
最近需要将显卡中断信息从内核层提到用户层,显卡每次中断用户层都需要要获得其一些寄存器值,直接在内核中写模块,导出一个函数给中断handler调用,在函数里使用netlink_broadcast广播。现在问题是把netlink_broadcast注释掉一点问题没有,只要执行 netlink_broadcast,刚开机就黑屏;我设一计数器,在中断1000次时调用netlink_broadcast(开机过程大约800次左右),屏幕直接变黑。
代码如下: 函数kernel_girq_to_user给中断handler调用
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/kthread.h>
#include <linux/slab.h>
#include <net/sock.h>
#include <net/net_namespace.h>
MODULE_LICENSE("GPL");
#define MAX_MSGSIZE 1024
struct sock *nl_sk= NULL;
int kernel_girq_to_user(struct gpu_irqinfo *g_irqmsg)
{
struct sk_buff *nl_skb;
struct nlmsghdr *nlh;
static int cc = 0;
int ret = 0;
if(!nl_sk)
return -1;
nl_skb = alloc_skb(NLMSG_SPACE(MAX_MSGSIZE), GFP_KERNEL);
if(!nl_skb){
printk("netlink: alloc_skb Error.\n");
}
nlh = nlmsg_put(nl_skb, 0, 0, 0, MAX_MSGSIZE, 0);
NETLINK_CB(nl_skb).portid = 0;
NETLINK_CB(nl_skb).dst_group = GPUIRQ_GROUP;
memcpy(NLMSG_DATA(nlh), g_irqmsg, sizeof(struct gpu_irqinfo));
// if(0 == (cc % 1000))
// ret = netlink_broadcast(nl_sk, nl_skb, 0, GPUIRQ_GROUP, GFP_KERNEL);
printk("[%s]----------------->>> cc = %d, ret = %d\n", __func__, cc++, ret);
kfree_skb(nl_skb);
nl_skb = NULL;
return 0;
}
EXPORT_SYMBOL(kernel_girq_to_user);
static int __init gpuirq_init(void)
{
struct netlink_kernel_cfg cfg = {
.groups = 1,
.flags = NL_CFG_F_NONROOT_RECV,
};
nl_sk = netlink_kernel_create(&init_net, NETLINK_GIRQ_MSG, &cfg);
if(!nl_sk)
printk("create kernel gpu irq scoket failed!!!\n");
return 0;
}
static void __exit gpuirq_exit(void)
{
netlink_kernel_release(nl_sk);
return;
}
module_init(gpuirq_init);
module_exit(gpuirq_exit);
急用!!!多谢 |
|