首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >工作队列和计时器模块在读取时崩溃。

工作队列和计时器模块在读取时崩溃。
EN

Stack Overflow用户
提问于 2014-01-26 11:15:26
回答 1查看 555关注 0票数 0

我正在做一个模块,它由三个部分组成。我在Debian 6工作。

第一个是计时器,每125次触发一次。它的功能是选择系统jiffies,屏蔽它们,并将它们包含在一个带有10个空格的循环缓冲区中。当该空间的80%处于繁忙状态时,一个工作项将被添加到一个工作队列中,该工作队列将把数字输入到列表中。当任何用户读取/proc/modtimer条目时,该列表将被移除其元素。

我的问题是:我可以毫无问题地安装模块,/proc条目(我需要2,但现在只有一个实现)是在没有问题的情况下创建的,但是当我试图读取内核崩溃时。当我阅读控制信息时,我认为问题在于发布过程。我不知道是什么问题。这是我的密码

编辑:经过几次测试后,我的程序崩溃,行为:“del_timer_sync(&my_timer);

EDIT2:除了安装/卸载/打开/关闭/读取函数之外,我已经删除了所有内容,因为任何其他功能都是无关的。

EDIT3:也可以是“add_timer(&my_timer)”;

代码语言:javascript
复制
#define PROC_ENTRY "modtimer"
#define PROC_ENTRY_OPS "modconfig"
#define CBUFFER_SIZE 10
#define TRESHOLD_SIZE 80 // percentage of the treshold for the workqueue calling
#define DELAY 125 //125 tics for timer (1 each half a sec)
#define MAX_BUFFER 512

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/proc_fs.h>
#include <linux/semaphore.h>
#include <linux/vmalloc.h>
#include <linux/timer.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <asm-generic/uaccess.h>
#include "cbuffer.h"

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Pseudo-Random number generator for DSO");
MODULE_AUTHOR("Kaostias");

/**********************************************************/
/********************** Declarations **********************/
/**********************************************************/

/*Timer*/
struct timer_list my_timer;

/*Workqueue*/
struct work_struct my_workqueue;

/* The workqueue has been planified but not resolved */
int workqueue_pendiente;

/* /proc entries */
static struct proc_dir_entry *proc_entry, *proc_entry_opts;

/*Semaphore used as spin_lock */
struct semaphore mtx;
int openDevices;

/*Spinlock*/
DEFINE_SPINLOCK(spinlock);

/*List*/
struct list_head mylist = LIST_HEAD_INIT(mylist);
typedef struct {
    int data;
    struct list_head links;
}list_item_t;

/*Buffer of integer numbers*/
cbuffer_t *cbuf;

/*Functions*/
void vacia_list_item(void);
void add_list(int num);
void fire_timer(unsigned long data);
void copy_items_into_list(struct work_struct *work);
static int modtimer_open (struct inode *, struct file *);
static int modtimer_release (struct inode*, struct file *);
static ssize_t modtimer_read (struct file *file, char __user*, size_t nbits, loff_t * offset);
/*Se escribe la entrada PROC_ENTRY_OPS*/
int procOpsWrite( struct file *punterofichero, const char __user *bufferusuario,
                        unsigned long longitud, void *data);
int procOpsRead( char *buffer, char **bufferlocation, off_t offset,
                   int buffer_lenghth, int *eof, void *data );
/*Operaciones de proc PROC_ENTRY*/
static const struct file_operations my_fops = {
    .open = modtimer_open,
    .read = modtimer_read,
    .release = modtimer_release,
};




/**********************************************************/
/****** Install/Uninstall/Open/close/read functions *******/
/**********************************************************/

/*module install*/
int install_module(void){
    int ret = 0;
    printk(KERN_INFO "installing module");
    /*Timer inicialization*/
    my_timer.expires = jiffies + DELAY;
    my_timer.data = 0;
    my_timer.function = fire_timer;
    printk(KERN_INFO "Timer created but not used");

    /*workqueue inicialization*/
    workqueue_pendiente = 0;    
    INIT_WORK(&my_workqueue, copy_items_into_list);
    printk(KERN_INFO "creada workqueue");   

    /* Semaphore inicialization */  
    sema_init(&mtx,1);
    openDevices = 0;
    printk(KERN_INFO "Semapore created");
    
    /*Spin_lock inicialization*/
    spin_lock_init(&spinlock);
    printk(KERN_INFO "spinlock created");

    /*buffer inicialization*/
    cbuf = create_cbuffer_t (CBUFFER_SIZE);
    printk(KERN_INFO "buffer created");
    
    /*list Inicialization*/
    printk(KERN_INFO "list created");

    /*  /proc  entries */
    proc_entry = create_proc_entry(PROC_ENTRY,0777, NULL);
    if (proc_entry == NULL) {
            ret = -ENOMEM;
            printk(KERN_INFO "Error: No puedo crear la entrada en proc /proc/%s\n",PROC_ENTRY);
    } else {
        proc_entry->proc_fops=&my_fops;
            printk(KERN_INFO "Entrada /proc/%s creada.\n", PROC_ENTRY);
    }

    proc_entry_opts = create_proc_entry(PROC_ENTRY_OPS,0777, NULL);
    if (proc_entry_opts == NULL) {
            ret = -ENOMEM;
            printk(KERN_INFO "Error: No puedo crear la entrada en proc /proc/%s\n",PROC_ENTRY_OPS);
        remove_proc_entry(PROC_ENTRY, NULL);
            printk(KERN_INFO "Entrada /proc/%s eliminada.\n", PROC_ENTRY);      
    } else {
            proc_entry_opts->read_proc = procOpsRead;
            proc_entry_opts->write_proc =procOpsWrite;
            printk(KERN_INFO "Entrada /proc/%s creada.\n", PROC_ENTRY_OPS);
    }
    printk(KERN_INFO "módulo instalado correctamente");
    return ret;
}

/*Uninstalling module*/
void uninstall_module(void){
    printk(KERN_INFO "Uninstalling module");

    /*  /proc  removal*/
    remove_proc_entry(PROC_ENTRY, NULL);
    printk(KERN_INFO " /proc/%s entry removed.\n", PROC_ENTRY);

    remove_proc_entry(PROC_ENTRY_OPS, NULL);
    printk(KERN_INFO " /proc/%s entry removed.\n", PROC_ENTRY_OPS);

    /*buffer destruction*/
    remove_cbuffer_t (cbuf);

    /*list gets empty*/
    vacia_list_item();

    printk(KERN_INFO "The uninstalling procese has been complete");

}


/* PROC_ENTRY /proc entry is open (Like a file) */
static int modtimer_open (struct inode *inod, struct file *f){
    int ret = 0;
    printk(KERN_INFO "entering modtimer_open");
    
    // timer is added (Not synchrone yet)
    if(openDevices==0){
        printk(KERN_INFO "Entra");
        my_timer.expires = jiffies + DELAY;
        add_timer(&my_timer);
    }
    
    openDevices++;

    printk(KERN_INFO "saliendo de modtimer_open");
    return ret;
}
/* PROC_ENTRY /proc entry is closed*/
static int modtimer_release (struct inode *inod, struct file *f){
    int ret = 0;    
    printk(KERN_INFO "entering modtimer_release");



    openDevices--; // In this moment there just will be 1 device open, i will fix this

    printk(KERN_INFO "1");
    del_timer_sync(&my_timer);
    printk(KERN_INFO "2");
    flush_scheduled_work();

    printk(KERN_INFO "modtimer_release cerrado");
    return ret;
}

module_init(install_module);
module_exit(uninstall_module);
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-26 22:02:31

问题真的很简单。我已经初始化了计时器值,但没有初始化计时器本身。计时器的初始化是使用以下函数完成的:

代码语言:javascript
复制
init_timer(struct timer_list *timer);

在这场追逐中

代码语言:javascript
复制
init_timer(&my_timer); 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21362671

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档