定时器问题请教高手

zx77 2002-12-16 04:25:58
各位高手,我现在遇到一个让人迷惑的问题。(Kernel version 2.2.19)
我的程序结构是这样的:
1. 有一个HashTable,其节点上有一个timer_list结构,还有一个id号以及一些我用的属性。
2. 有一个通用的delete函数,它做如下操作:
a. 先cli关中断。
b. 如果timer_list不为空,则调用del_timer将其删除。
c. 用一个全局变量记录下id(这是我后来为了debug而加上的)。
d. 将id清空为0。
e. 将该节点从HashTable中去掉。
f. restore_flags开中断。
g. 调用kfree_s释放该节点。
3. 在新建节点时,用add_timer设置timer_list,定时器函数为delete函数。也就是说,delete将在timer_bh里运行。
4. 在net_bh中,有些特殊的时候,我也会直接调用delete函数来删除节点。由于考虑到net_bh和timer_bh应该是不会重入的,所以我认为这没有问题。
5. 实际运行中,当系统在大负荷运行下,有时会出现死机,通过LKCD的分析,发现,都死在delete函数的kfree_s处,而节点的数据都没错,唯一奇怪的是在进入delete函数时,id已经为0了,说明以前被删除过。但从代码中我实在是分析不出有什么问题了。
希望高手能解答。谢谢!

void node_delete(struct node *pnode)
{
unsigned long flags;

save_flags(flags);
cli();

if (pnode->timer_set) {
del_timer(&pnode->timer);
pnode->timer_set = 0;
}

// this is for LKCD dump debug
global_debug = pnode->id;

pnode->id = 0;

// now I unlink the node from HashTable
...

restore_flags(flags);

// do some other things
...

kfree_s(pnode, sizeof(struct node));
}

struct node * node_insert(...)
{
__u32 key = NODE_KEY(...);
struct node *pnode;
unsigned long flags;

if ((pnode = (struct node *)kmalloc(sizeof(struct node), GFP_ATOMIC)) == NULL) {
return NULL;
}

memset(pnode, 0, sizeof(struct node));

// now i set some basic properties
...

init_timer(&pnode->timer); // timer is a member of struct node, its type is timer_list
set_node_timer(pnode, MY_TIMEOUT);

save_flags(flags);
cli();

// link this into HashTable
...

// gen unique id of node, based on 1, 0 means invalid
...

restore_flags(flags);
return pnode;
}

inline void set_node_timer(struct node *pnode, unsigned long when)
{
unsigned long flags;

if (NULL == pnode) {
return;
}

save_flags(flags);
cli();

if (pnode->timer_set) {
del_timer(&pnode->timer);
}

pnode->timer.expires = jiffies + when;
pnode->timer.data = (unsigned long) pnode;
pnode->timer.function = (node_expire) node_delete;
pnode->timer_set = 1;
add_timer(pnode->timer);

restore_flags(flags);
}

// myfun() is called by net_bh in some cases
void myfun()
{
// some other operations

if (some_case) {
node_delete(pnode);
// I found someone says that del_timer may not success in 2.2.x
// so if it's real, that my process may die, but I didn't so sure
// does anyone know something else?
// ref to http://www.uwsg.iu.edu/hypermail/linux/kernel/0005.3/0269.html
}

// other operations...
}
...全文
27 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧